hik sdk 对接人脸抓拍

This commit is contained in:
lxj 2025-07-12 13:52:44 +08:00
parent 2347d46a9b
commit 5ad50d96b9
8 changed files with 183 additions and 58 deletions

View File

@ -91,8 +91,10 @@
<properties>
<!-- 环境标识,需要与配置文件的名称相对应 -->
<profiles.active>dev</profiles.active>
<nacos.server>192.168.110.207:8848</nacos.server>
<logstash.address>192.168.110.207:4560</logstash.address>
<nacos.server>47.109.37.87:8848</nacos.server>
<logstash.address>47.109.37.87:4560</logstash.address>
<!-- <nacos.server>192.168.110.207:8848</nacos.server>-->
<!-- <logstash.address>192.168.110.207:4560</logstash.address>-->
<nacos.discovery.group>DEFAULT_GROUP</nacos.discovery.group>
<nacos.config.group>DEFAULT_GROUP</nacos.config.group>
<nacos.username>nacos</nacos.username>

View File

@ -3,11 +3,14 @@ package org.dromara.sis.runner;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.sis.domain.vo.SisElevatorInfoVo;
import org.dromara.sis.sdk.hik.HikApiService;
import org.dromara.sis.sdk.hik.calback.HikAlarmCallBack;
import org.dromara.sis.service.ISisElevatorInfoService;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.List;
@ -18,11 +21,22 @@ import java.util.List;
public class HikDeviceApplicationRunner implements ApplicationRunner {
private final ISisElevatorInfoService elevatorInfoService;
private final HikAlarmCallBack hikAlarmCallBack;
@Override
public void run(ApplicationArguments args) throws Exception {
// 先布放在登录
HikApiService.getInstance().setAlarmCallBack(0, hikAlarmCallBack);
// 现在查询全部后面要更具需要查询指定厂商的设备
HikDeviceApplicationRunner runner = SpringUtils.getAopProxy(this);
// 梯控登录
runner.hikElevatorInfoLogin();
// 网络摄像头登录
hikNetCameraLogin();
}
@Async
public void hikElevatorInfoLogin() {
List<SisElevatorInfoVo> sisElevatorInfoVos = elevatorInfoService.queryAll();
if (CollUtil.isNotEmpty(sisElevatorInfoVos)) {
sisElevatorInfoVos.forEach(item -> {
@ -31,6 +45,17 @@ public class HikDeviceApplicationRunner implements ApplicationRunner {
// todo 更新设备心跳信息
});
}
}
public void hikNetCameraLogin() {
String ip = "192.168.24.17";
short port = 8000;
String account = "admin";
String pwd = "xzf13579";
int handler = HikApiService.getInstance().login(ip, port, account, pwd);
if(handler != -1){
HikApiService.getInstance().setAlarmChan(handler);
}
}
}

View File

@ -25,6 +25,7 @@ public class HikApiService {
}
private static volatile HikApiService instance;
public static HikApiService getInstance() {
if (instance == null) {
synchronized (HikApiService.class) {
@ -36,6 +37,9 @@ public class HikApiService {
return instance;
}
public static void init() {
SdkBaseServer.initSdk();
}
/**
@ -47,13 +51,22 @@ public class HikApiService {
* @param psw 设备密码
* @return 返回会否登录成功
*/
public Boolean login(String ip, short port, String user, String psw) {
public int login(String ip, short port, String user, String psw) {
int i = LoginService.loginDevice(ip, port, user, psw);
boolean result = (i != SdkBaseServer.LOGIN_FAIL_CODE);
if (result) {
CACHE.put(ip, i);
}
return result;
return i;
}
/**
* 注册报警信息回调函数
*
* @param callBack 报警信回调
*/
public boolean setAlarmCallBack(int iIndex, HCNetSDK.FMSGCallBack_V31 callBack) {
return SdkBaseServer.setAlarmCallBack(iIndex, callBack);
}
/**
@ -107,4 +120,8 @@ public class HikApiService {
}
return logout;
}
public void setAlarmChan(int handler) {
SdkBaseServer.setAlarmChan(handler);
}
}

View File

@ -0,0 +1,44 @@
package org.dromara.sis.sdk.hik.calback;
import cn.hutool.core.codec.Base64Encoder;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sis.sdk.hik.HCNetSDK;
import org.springframework.stereotype.Component;
import java.nio.ByteBuffer;
@Slf4j
@Component
public class HikAlarmCallBack implements HCNetSDK.FMSGCallBack_V31 {
private static final int COMM_UPLOAD_FACESNAP_RESULT = 0x1112;
@Override
public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
if (lCommand == COMM_UPLOAD_FACESNAP_RESULT) {// 读取抓拍人脸数据
log.info("hik 抓拍信息上报完成,lCommand={}", lCommand);
HCNetSDK.NET_VCA_FACESNAP_RESULT result = new HCNetSDK.NET_VCA_FACESNAP_RESULT();
result.write();
Pointer pItsPlateInfo = result.getPointer();
pItsPlateInfo.write(0, pAlarmInfo.getByteArray(0, result.size()), 0, result.size());
result.read();
// 读取人脸小图
ByteBuffer buffers = result.pBuffer1.getByteBuffer(0, result.dwFacePicLen);
byte[] smallImg = new byte[result.dwFacePicLen];
buffers.rewind();
buffers.get(smallImg);
// 读取人脸大图
// ByteBuffer buffers1 = result.pBuffer2.getByteBuffer(0, result.dwBackgroundPicLen);
// byte[] bigImg = new byte[result.dwBackgroundPicLen];
// buffers1.rewind();
// buffers1.get(bigImg);
// todo 进行人脸比对
String smallImgBase64Str = Base64Encoder.encode(smallImg);
} else {
log.info("未知报警类型,lCommand={}", lCommand);
}
return true;
}
}

View File

@ -182,6 +182,7 @@ public class DoorService extends SdkBaseServer {
public static boolean controlGateway(int lUserID, int lGatewayIndex, int dwStaic) {
boolean b = getHcNetSDK().NET_DVR_ControlGateway(lUserID, lGatewayIndex, dwStaic);
log.info("楼层数据下发结果,楼层={}result={}", lGatewayIndex, b);
if (!b) {
int i = getHcNetSDK().NET_DVR_GetLastError();
log.error("梯控控制失败, errCode={}", i);

View File

@ -1,6 +1,7 @@
package org.dromara.sis.sdk.hik.service;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sis.sdk.hik.HCNetSDK;
import org.springframework.util.Assert;
@ -18,7 +19,6 @@ public class SdkBaseServer {
*/
public static final int LOGIN_FAIL_CODE = -1;
public static HCNetSDK getHcNetSDK() {
if (hcNetSDK == null) {
throw new RuntimeException("HIK sdk 初始化失败!");
@ -83,6 +83,41 @@ public class SdkBaseServer {
return state;
}
/**
* 开启hik 设备报警
*
* @param iIndex 回调函数索引取值范围[0,15]
* @param callBack 回调函数
* @return
*/
public static boolean setAlarmCallBack(int iIndex, HCNetSDK.FMSGCallBack_V31 callBack) {
boolean b = hcNetSDK.NET_DVR_SetDVRMessageCallBack_V50(iIndex, callBack, null);
if (b) {
log.info("hik 报警回调函数设置完成iIndex={}", iIndex);
}
return b;
}
public static boolean setAlarmChan(int lUserID){
//报警布防参数设置
HCNetSDK.NET_DVR_SETUPALARM_PARAM_V50 m_strAlarmInfoV50 = new HCNetSDK.NET_DVR_SETUPALARM_PARAM_V50();
m_strAlarmInfoV50.dwSize = m_strAlarmInfoV50.size();
m_strAlarmInfoV50.byLevel = 0; //布防等级
m_strAlarmInfoV50.byAlarmInfoType = 1; // 智能交通报警信息上传类型0- 老报警信息NET_DVR_PLATE_RESULT1- 新报警信息(NET_ITS_PLATE_RESULT)
m_strAlarmInfoV50.byRetAlarmTypeV40 = 1; //0- 移动侦测视频丢失遮挡IO信号量等报警信息以普通方式上传报警类型COMM_ALARM_V30报警信息结构体NET_DVR_ALARMINFO_V30
// 1- 报警信息以数据可变长方式上传报警类型COMM_ALARM_V40报警信息结构体NET_DVR_ALARMINFO_V40设备若不支持则仍以普通方式上传
m_strAlarmInfoV50.byDeployType = 0; //布防类型0-客户端布防1-实时布防
m_strAlarmInfoV50.write();
int lAlarmHandle = hcNetSDK.NET_DVR_SetupAlarmChan_V50(lUserID, m_strAlarmInfoV50, Pointer.NULL, 0);
if (lAlarmHandle == -1) {
System.err.println("布防失败,错误码为" + hcNetSDK.NET_DVR_GetLastError());
return false;
} else {
System.out.println("布防成功");
return true;
}
}
/**
* 登出操作

View File

@ -3,11 +3,8 @@ package org.dromara.sis.sdk.unview.service;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sis.domain.SisDeviceBindRef;
import org.dromara.sis.domain.enums.ControlTypeEnum;
import org.dromara.sis.domain.vo.SisAuthRecordVo;
import org.dromara.sis.sdk.e8.AccessControlService;
import org.dromara.sis.sdk.e8.domain.accessControl.req.RemoteOpenDoorReq;
import org.dromara.sis.sdk.hik.HikApiService;
import org.dromara.sis.sdk.unview.model.UvModel;
import org.dromara.sis.sdk.unview.model.enums.AlarmTypeEnum;
import org.dromara.sis.service.ISisAccessControlService;
@ -16,8 +13,8 @@ import org.dromara.sis.service.ISisDeviceBindRefService;
import org.dromara.sis.service.ISisDeviceManageService;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* 宇视人体设备告警数据处理
@ -111,6 +108,7 @@ public class VideoAlarmService {
*/
private void handleFacialCapture(UvModel.AlarmReportInfo alarmReportData) {
}
/**
@ -130,54 +128,57 @@ public class VideoAlarmService {
log.info("上报设备信息不存在,不处理词条数据。");
return;
}
log.info("开始电梯权限下发。。。。。。。。。。。。。。。。。。。。。。");
compareResults.forEach(result -> {
// 查询设备绑定关联关系表
SisDeviceBindRef ref = deviceBindRefService.queryByDeviceIp(channelInfo.getIpc_addr());
if (ref == null) {
return;
}
// 门禁
if (Objects.equals(ref.getControlType(), ControlTypeEnum.ACCESS_CONTROL.getCode())) {
// SisAccessControlVo controlVo = sisAccessControlService.queryById(ref.getBindId());
// if (controlVo == null) {
// log.info("设备[{}]未和门禁绑定,不处理此条数据。", channelInfo.getIpc_addr());
// return;
// }
// 人像库id
// Integer libId = result.getLib_id();
// 宇视人员id
Integer personId = result.getPerson_id();
// 门禁id
Long accessControlId = ref.getBindId();
// 校验人脸是偶有同行此门禁的权限
SisAuthRecordVo recordVo = authRecordService.checkAuth(personId, accessControlId);
// 如果有通行权限则打开门禁
if (recordVo == null) {
log.info("此人像[{}]没有门禁[{}]的通行权限。", personId, accessControlId);
}
// 打开门禁
RemoteOpenDoorReq remoteOpenDoorReq = new RemoteOpenDoorReq();
remoteOpenDoorReq.setType(0);
remoteOpenDoorReq.setReason("宇视人像识别,人像id=" + recordVo.getImgId());
remoteOpenDoorReq.setOperatorId(0L);
RemoteOpenDoorReq.ControlData data = new RemoteOpenDoorReq.ControlData();
data.setDoorId(recordVo.getDoorId());
data.setDeviceId(recordVo.getDeviceId());
remoteOpenDoorReq.setControlList(List.of(data));
log.info("远程开门参数params={}", JSONObject.toJSONString(remoteOpenDoorReq));
Boolean b = accessControlService.remoteOpenDoor(remoteOpenDoorReq);
log.info("远程开门完成, result={}", b);
}
// 远程呼梯
if (Objects.equals(ref.getControlType(), ControlTypeEnum.REMOTE_CALL_ELEVATOR.getCode())) {
// TODO 待实现
// 下发梯控权限数据
// List<Integer> arrs = Arrays.asList(2, 2, 2, 3, 3, 3 ,3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
List<Integer> arrs = Arrays.asList(3, 3, 3, 2, 2, 2 ,2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
for (int i = 0; i < arrs.size(); i++) {
HikApiService.getInstance().controlGateway("192.168.24.188", (i + 1), arrs.get(i));
}
// 梯控
if (Objects.equals(ref.getControlType(), ControlTypeEnum.ELEVATOR_CONTROL.getCode())) {
// TODO 待实现
}
});
// compareResults.forEach(result -> {
// // 查询设备绑定关联关系表
// SisDeviceBindRef ref = deviceBindRefService.queryByDeviceIp(channelInfo.getIpc_addr());
// if (ref == null) {
// return;
// }
// // 门禁
// if (Objects.equals(ref.getControlType(), ControlTypeEnum.ACCESS_CONTROL.getCode())) {
// // 宇视人员id
// Integer personId = result.getPerson_id();
// // 门禁id
// Long accessControlId = ref.getBindId();
// // 校验人脸是偶有同行此门禁的权限
// SisAuthRecordVo recordVo = authRecordService.checkAuth(personId, accessControlId);
// // 如果有通行权限则打开门禁
// if (recordVo == null) {
// log.info("此人像[{}]没有门禁[{}]的通行权限。", personId, accessControlId);
// }
// // 打开门禁
// RemoteOpenDoorReq remoteOpenDoorReq = new RemoteOpenDoorReq();
// remoteOpenDoorReq.setType(0);
// remoteOpenDoorReq.setReason("宇视人像识别,人像id=" + recordVo.getImgId());
// remoteOpenDoorReq.setOperatorId(0L);
// RemoteOpenDoorReq.ControlData data = new RemoteOpenDoorReq.ControlData();
// data.setDoorId(recordVo.getDoorId());
// data.setDeviceId(recordVo.getDeviceId());
// remoteOpenDoorReq.setControlList(List.of(data));
// log.info("远程开门参数params={}", JSONObject.toJSONString(remoteOpenDoorReq));
// Boolean b = accessControlService.remoteOpenDoor(remoteOpenDoorReq);
// log.info("远程开门完成, result={}", b);
// }
// // 远程呼梯
// if (Objects.equals(ref.getControlType(), ControlTypeEnum.REMOTE_CALL_ELEVATOR.getCode())) {
// // TODO 待实现
// }
//
// // 梯控
// if (Objects.equals(ref.getControlType(), ControlTypeEnum.ELEVATOR_CONTROL.getCode())) {
// // TODO 待实现
// }
// });
}
/**

View File

@ -40,8 +40,8 @@ spring.sql.init.platform=mysql
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://47.109.37.87:3002/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
db.user.0=by
db.url.0=jdbc:mysql://192.168.24.98:3306/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
db.user.0=root
db.password.0=123456
### the maximum retry times for push