Browse Source

最新版红外 支持多线程

master
王寅 2 months ago
parent
commit
d30b3ff395
10 changed files with 254 additions and 188 deletions
  1. +4
    -4
      sdkLog/SdkLog_1_W.log
  2. +2
    -2
      src/main/java/com/inspect/nvr/controller/CameraController.java
  3. +37
    -10
      src/main/java/com/inspect/nvr/controller/IvsCameraController.java
  4. +3
    -2
      src/main/java/com/inspect/nvr/service/DahuaService.java
  5. +125
    -105
      src/main/java/com/inspect/nvr/service/impl/DahuaServiceImpl.java
  6. +11
    -8
      src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java
  7. +65
    -55
      src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java
  8. +2
    -1
      src/main/java/com/inspect/nvr/utils/StringHexConverter.java
  9. +1
    -1
      src/main/java/com/inspect/nvr/utils/sftp/SftpFactory.java
  10. +4
    -0
      src/main/resources/application.yml

+ 4
- 4
sdkLog/SdkLog_1_W.log View File

@ -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.

+ 2
- 2
src/main/java/com/inspect/nvr/controller/CameraController.java View File

@ -57,12 +57,12 @@ public class CameraController {
log.info("红外开始===================================》》》》》"); log.info("红外开始===================================》》》》》");
TemperatureData temperatureData = null; TemperatureData temperatureData = null;
if(0 == camera.getCameraType()){ if(0 == camera.getCameraType()){
temperatureData = executeWithTimeout(() -> cameraService.StartRemote(camera), 5, TimeUnit.SECONDS);
temperatureData = executeWithTimeout(() -> cameraService.StartRemote(camera), 7, TimeUnit.SECONDS);
// temperatureData = cameraService.StartRemote(camera); // temperatureData = cameraService.StartRemote(camera);
} else { } else {
temperatureData = dahuaService.StartRemote(camera); 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; return temperatureData;
} }


+ 37
- 10
src/main/java/com/inspect/nvr/controller/IvsCameraController.java View File

@ -1,13 +1,16 @@
package com.inspect.nvr.controller; package com.inspect.nvr.controller;
import com.inspect.nvr.domain.Infrared.TemperatureData;
import com.inspect.nvr.domain.device.*; import com.inspect.nvr.domain.device.*;
import com.inspect.nvr.service.IvsCameraService; import com.inspect.nvr.service.IvsCameraService;
import com.inspect.nvr.utils.StringUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -17,7 +20,8 @@ public class IvsCameraController {
@Resource @Resource
private IvsCameraService ivsCameraService; private IvsCameraService ivsCameraService;
private static final Object captureLock = new Object();
private static final Object captureLock_pic = new Object();
@GetMapping("/device/ptzpresetlist/{cameraCode}/{domainCode}") @GetMapping("/device/ptzpresetlist/{cameraCode}/{domainCode}")
public ResponseEntity<IvsPresetListView> ptzPresetList(@PathVariable("cameraCode") String cameraCode, @PathVariable("domainCode") String domainCode) { public ResponseEntity<IvsPresetListView> ptzPresetList(@PathVariable("cameraCode") String cameraCode, @PathVariable("domainCode") String domainCode) {
log.info("PTZ_PRESET_LIST cameraCode : {}, domainCode: {}", cameraCode, domainCode); log.info("PTZ_PRESET_LIST cameraCode : {}, domainCode: {}", cameraCode, domainCode);
@ -29,10 +33,12 @@ public class IvsCameraController {
@PostMapping({"/device/ptzcontrol"}) @PostMapping({"/device/ptzcontrol"})
public ResponseEntity<PtzControlResult> ptzControl(@RequestBody PtzControlParam param) { public ResponseEntity<PtzControlResult> 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}"}) @GetMapping({"/platform/platformSnapshot/{cameraCode}/{domainCode}"})
@ -56,10 +62,31 @@ public class IvsCameraController {
@GetMapping("/downloadfile") @GetMapping("/downloadfile")
public ResponseEntity<InputStreamResource> downloadFile(@RequestParam("filesessionid") String fileSessionId) { public ResponseEntity<InputStreamResource> 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));
// }
} }
} }

+ 3
- 2
src/main/java/com/inspect/nvr/service/DahuaService.java View File

@ -1,16 +1,17 @@
package com.inspect.nvr.service; 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.Camera;
import com.inspect.nvr.domain.Infrared.NvrInfo; import com.inspect.nvr.domain.Infrared.NvrInfo;
import com.inspect.nvr.domain.Infrared.TemperatureData; import com.inspect.nvr.domain.Infrared.TemperatureData;
import com.inspect.nvr.hikVision.utils.AjaxResult; import com.inspect.nvr.hikVision.utils.AjaxResult;
import com.inspect.nvr.daHuaCarme.jna.NetSDKLib.LLong;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
public interface DahuaService { public interface DahuaService {
AjaxResult login(NvrInfo nvrInfo);
LLong login(NvrInfo nvrInfo);
//大华测温 //大华测温
TemperatureData StartRemote(Camera camera); TemperatureData StartRemote(Camera camera);


+ 125
- 105
src/main/java/com/inspect/nvr/service/impl/DahuaServiceImpl.java View File

@ -18,6 +18,7 @@ import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -39,21 +40,24 @@ public class DahuaServiceImpl implements DahuaService {
@Resource @Resource
private RedisService redisService; private RedisService redisService;
private LLong m_hLoginHandle;
// private LLong m_hLoginHandle;
@Autowired @Autowired
private fSnapReceiveCB snapReceiveCB; private fSnapReceiveCB snapReceiveCB;
private static final Object captureLock = new Object(); private static final Object captureLock = new Object();
@Value("${mode.delayTime:3000}")
private int delayTime;
/** /**
* 登录大华设备 * 登录大华设备
*
* @param nvrInfo * @param nvrInfo
* @return * @return
*/ */
@Override @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(); NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();
// pstInParam.szIP=camera.getIp().getBytes(); // pstInParam.szIP=camera.getIp().getBytes();
@ -71,58 +75,62 @@ public class DahuaServiceImpl implements DahuaService {
//调用登录接口 //调用登录接口
// NetSDKLib.LLong m_hLoginHandle=NetSDKLib.cki // 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); System.out.println("m_hLoginHandle : " + m_hLoginHandle);
if (m_hLoginHandle.longValue() == 0) { if (m_hLoginHandle.longValue() == 0) {
System.out.println("登录失败"); System.out.println("登录失败");
System.out.println("大华-获取设备参数失败,错误码:" + ToolKits.getErrorCodePrint(dhNetSDK.CLIENT_GetLastError())); System.out.println("大华-获取设备参数失败,错误码:" + ToolKits.getErrorCodePrint(dhNetSDK.CLIENT_GetLastError()));
return null; 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 * @param camera
* @return * @return
*/ */
@Override @Override
public TemperatureData StartRemote(Camera camera) { public TemperatureData StartRemote(Camera camera) {
log.info("大华实时测温入口================================================="); log.info("大华实时测温入口=================================================");
Object storedObj = redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle");
// Object storedObj = redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle");
// 2. 进行空值和类型判断 // 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. 初始化输入结构体 // 1. 初始化输入结构体
log.info("开始实时测温================================================="); 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(); NetSDKLib.NET_IN_RADIOMETRY_GETTEMPER netIn = new NetSDKLib.NET_IN_RADIOMETRY_GETTEMPER();
// 设置条件参数 // 设置条件参数
netIn.stCondition.nPresetId = camera.getPresetId(); netIn.stCondition.nPresetId = camera.getPresetId();
netIn.stCondition.nRuleId = 1; netIn.stCondition.nRuleId = 1;
netIn.stCondition.nMeterType = NetSDKLib.NET_RADIOMETRY_METERTYPE.NET_RADIOMETRY_METERTYPE_AREA; 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] 结构体参数设置完成 - " + log.info("[DEBUG] 结构体参数设置完成 - " +
@ -168,24 +176,25 @@ public class DahuaServiceImpl implements DahuaService {
netIn.stCondition.nRuleId netIn.stCondition.nRuleId
); );
boolean b = dhNetSDK.CLIENT_Logout(m_hLoginHandle); 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; return data;
} }
System.out.println("大华-获取设备参数失败,错误码:" + ToolKits.getErrorCodePrint(dhNetSDK.CLIENT_GetLastError())); System.out.println("大华-获取设备参数失败,错误码:" + ToolKits.getErrorCodePrint(dhNetSDK.CLIENT_GetLastError()));
boolean b = dhNetSDK.CLIENT_Logout(m_hLoginHandle); 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; return null;
} }
/** /**
* 大华预置位跳转 * 大华预置位跳转
*
* @param camera * @param camera
* @param param1 * @param param1
* @param param2 * @param param2
@ -194,64 +203,74 @@ public class DahuaServiceImpl implements DahuaService {
*/ */
@Override @Override
public String cameraControl(Camera camera, int param1, int param2, int param3) { 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"; String ctr = "GOTO_PRESET";
boolean dResult = dhNetSDK.CLIENT_DHPTZControlEx2(m_hLoginHandle, camera.getChannel() - 1, DahuaUtils.PTZCommand(ctr), 0, camera.getPointNum(), 0, 0, null); boolean dResult = dhNetSDK.CLIENT_DHPTZControlEx2(m_hLoginHandle, camera.getChannel() - 1, DahuaUtils.PTZCommand(ctr), 0, camera.getPointNum(), 0, 0, null);
if (!dResult) { 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 { } else {
log.info("CLIENT_DHPTZControlEx success"); 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 * @param camera
* @return * @return
*/ */
@Override @Override
public ByteArrayInputStream Picture(Camera camera) { public ByteArrayInputStream Picture(Camera camera) {
synchronized (captureLock) { 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. 准备抓图参数 // 2. 准备抓图参数
NetSDKLib.SNAP_PARAMS snapParams = new NetSDKLib.SNAP_PARAMS(); NetSDKLib.SNAP_PARAMS snapParams = new NetSDKLib.SNAP_PARAMS();
snapParams.Channel = camera.getChannel() - 1; // channel snapParams.Channel = camera.getChannel() - 1; // channel
@ -295,39 +314,40 @@ public class DahuaServiceImpl implements DahuaService {
log.error("等待图片回调超时"); log.error("等待图片回调超时");
return null; 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("登出成功"); log.info("登出成功");
// }
} }
return imageBytes[0] != null ? new ByteArrayInputStream(imageBytes[0]) : null;
return imageBytes[0] != null ? new ByteArrayInputStream(imageBytes[0]) : null;
} }
// 7. 返回结果 // 7. 返回结果
} }


+ 11
- 8
src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java View File

@ -57,10 +57,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List; 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); Arrays.fill(cond.byRes2, (byte) 0);
cond.write(); // 手动同步结构体到内存 cond.write(); // 手动同步结构体到内存
CompletableFuture<TemperatureData> temperatureFuture = new CompletableFuture<>(); CompletableFuture<TemperatureData> 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. 启动远程测温 // 3. 启动远程测温
Pointer lpInBuffer = cond.getPointer(); Pointer lpInBuffer = cond.getPointer();
int dwInBufferSize = cond.size(); int dwInBufferSize = cond.size();
@ -258,10 +263,8 @@ public class HikVisionServiceImpl implements HikVisionService {
log.error("启动远程测温失败,错误码为:{},错误信息为:{}", errorCode, errorMsg); log.error("启动远程测温失败,错误码为:{},错误信息为:{}", errorCode, errorMsg);
} }
temperatureData = temperatureFuture.get(); temperatureData = temperatureFuture.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (Exception e) {
log.error("测温异常报错");
} finally { } finally {
log.info("关闭实时测温result值 {}", result); log.info("关闭实时测温result值 {}", result);
//关闭实时测温 //关闭实时测温


+ 65
- 55
src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java View File

@ -43,6 +43,15 @@ public class IvsCameraServiceImpl implements IvsCameraService {
@Value("${test-mode:false}") @Value("${test-mode:false}")
private boolean testMode; 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 @Resource
private RedisService redisService; private RedisService redisService;
@ -78,11 +87,7 @@ public class IvsCameraServiceImpl implements IvsCameraService {
//跳转预置位 //跳转预置位
@Override @Override
public PtzControlResult ptzControl(PtzControlParam param) { public PtzControlResult ptzControl(PtzControlParam param) {
if (testMode) {
return PtzControlResult.builder()
.resultCode("0")
.build();
}
PtzControlResult ptzControlResult = null;
Camera camera = new Camera(); Camera camera = new Camera();
String[] splitArray = param.getAddress().split(":"); String[] splitArray = param.getAddress().split(":");
//给camera赋值 //给camera赋值
@ -102,7 +107,7 @@ public class IvsCameraServiceImpl implements IvsCameraService {
camera.setPassword(password); camera.setPassword(password);
log.info("预置位NVR:" + ip + " channel:" + channel + " pointNum:" + pointNum + " cameraType:" + cameraType); log.info("预置位NVR:" + ip + " channel:" + channel + " pointNum:" + pointNum + " cameraType:" + cameraType);
//给camera赋值结束 //给camera赋值结束
PtzControlResult ptzControlResult = ptzDetailControl(camera, cameraType);
ptzDetailControl(camera, cameraType);
try { try {
//等待5s开始调用红外 //等待5s开始调用红外
@ -117,7 +122,16 @@ public class IvsCameraServiceImpl implements IvsCameraService {
cameraHw.setUserName(splitArray[10]); cameraHw.setUserName(splitArray[10]);
cameraHw.setPassword(splitArray[11]); 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) { } catch (Exception e) {
// throw new RuntimeException(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; PtzControlResult ptzControlResult = null;
if (ObjectUtil.equals(cameraType, 1)) { if (ObjectUtil.equals(cameraType, 1)) {
log.info("开始登录大华NVR 进行跳转预置位"); log.info("开始登录大华NVR 进行跳转预置位");
String ajaxResult = dahuaService.cameraControl(camera, 0, 0, 0);
ptzControlResult = PtzControlResult.builder()
.resultCode(ajaxResult)
.build();
dahuaService.cameraControl(camera, 0, 0, 0);
} else { } else {
//海康预置位跳转 //海康预置位跳转
log.info("开始登录海康NVR 进行跳转预置位"); 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()); boolean gotoPreset = hcNetSDK.NET_DVR_PTZPreset_Other(lUserID, camera.getChannel(), HCNetSDK.GOTO_PRESET, camera.getPointNum());
if (!gotoPreset) { if (!gotoPreset) {
log.error("海康-获取设备预置位跳转设备参数失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); log.error("海康-获取设备预置位跳转设备参数失败,错误码:" + hcNetSDK.NET_DVR_GetLastError());
return PtzControlResult.builder()
.resultCode("-1")
.build();
} else { } else {
log.info("海康-成功跳转到预置位!"); 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; return ptzControlResult;
} }
/** /**
* 大华红外读数多次读取 * 大华红外读数多次读取
*
* @param camera * @param camera
* @return * @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; boolean success = false;
int retryCount = 0; int retryCount = 0;
while (!success && retryCount < MAX_RETRIES) { while (!success && retryCount < MAX_RETRIES) {
try { try {
retryCount++; retryCount++;
log.info("第{}次尝试读取红外", retryCount); log.info("第{}次尝试读取红外", retryCount);
TemperatureData temperatureData = cameraController.cameraHong(camera);
if(StringUtils.isNull(temperatureData)){
temperatureData = cameraController.cameraHong(camera);
if (StringUtils.isNull(temperatureData)) {
log.warn("第{}次读取红外失败", retryCount); log.warn("第{}次读取红外失败", retryCount);
ptzDetailControl(nvrCamera,cameraType);
Thread.sleep(3000); // 等待2秒后重试
ptzDetailControl(nvrCamera, cameraType);
} else { } else {
success = true; success = true;
return temperatureData; return temperatureData;
} }
} catch (Exception e) { } 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((":")); String[] cameraAddressInfos = rawString.split((":"));
// 从nvr或者camera下载图片, 开发中
// 从nvr或者camera下载图片, 开发中暂时只支持从nvr下载图片
Camera camera = new Camera(); Camera camera = new Camera();
//赋值 //赋值
log.info("DOWNLOAD_FILE ip: {}, port: {}, channel: {}, pointName: {},cameraType: {}, username: {}, password: {}", 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"); lUserID = (Integer) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_userId");
} }
HCNetSDK.NET_DVR_JPEGPARA dvrJpegpara = new HCNetSDK.NET_DVR_JPEGPARA(); HCNetSDK.NET_DVR_JPEGPARA dvrJpegpara = new HCNetSDK.NET_DVR_JPEGPARA();
dvrJpegpara.wPicSize = 3;
dvrJpegpara.wPicSize = 0xff;
dvrJpegpara.wPicQuality = 0; dvrJpegpara.wPicQuality = 0;
dvrJpegpara.write(); dvrJpegpara.write();
@ -293,38 +309,32 @@ public class IvsCameraServiceImpl implements IvsCameraService {
if (!picDir.exists()) { if (!picDir.exists()) {
picDir.mkdirs(); // 如果目录不存在创建它 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 { public byte[] loadDefaultImage() throws IOException {
ClassPathResource imgFile = new ClassPathResource("images/infrared_default.jpg"); ClassPathResource imgFile = new ClassPathResource("images/infrared_default.jpg");
return StreamUtils.copyToByteArray(imgFile.getInputStream()); return StreamUtils.copyToByteArray(imgFile.getInputStream());


+ 2
- 1
src/main/java/com/inspect/nvr/utils/StringHexConverter.java View File

@ -30,7 +30,7 @@ public class StringHexConverter {
// final String rawString = "3139322e3136382e312e3233313a383030303a31313a3231303a61646d696e3a323031362e682e4244"; // final String rawString = "3139322e3136382e312e3233313a383030303a31313a3231303a61646d696e3a323031362e682e4244";
// final String hex = fromHex(rawString); // final String hex = fromHex(rawString);
// log.info(hex); // 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); byte[] bytes = rawString.getBytes(StandardCharsets.UTF_8);
StringBuilder hex = new StringBuilder(); StringBuilder hex = new StringBuilder();
for (byte b : bytes) { for (byte b : bytes) {
@ -40,3 +40,4 @@ public class StringHexConverter {
log.info(fileSessionId); log.info(fileSessionId);
} }
} }

+ 1
- 1
src/main/java/com/inspect/nvr/utils/sftp/SftpFactory.java View File

@ -31,7 +31,7 @@ public class SftpFactory {
try { try {
this.queue.add(this.connect()); this.queue.add(this.connect());
} catch (IOException var2) { } catch (IOException var2) {
;
} }
} }


+ 4
- 0
src/main/resources/application.yml View File

@ -13,3 +13,7 @@ spring:
mode:
retryTimes: 5
delayTime: 5000
retryMode: 0

Loading…
Cancel
Save