From 5ad50d96b98fc3a1fa69aa9dc91ec6d67608cf49 Mon Sep 17 00:00:00 2001 From: lxj <15683799673@163.com> Date: Sat, 12 Jul 2025 13:52:44 +0800 Subject: [PATCH] =?UTF-8?q?hik=20sdk=20=E5=AF=B9=E6=8E=A5=E4=BA=BA?= =?UTF-8?q?=E8=84=B8=E6=8A=93=E6=8B=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 +- .../runner/HikDeviceApplicationRunner.java | 29 +++++- .../dromara/sis/sdk/hik/HikApiService.java | 21 +++- .../sis/sdk/hik/calback/HikAlarmCallBack.java | 44 +++++++++ .../sis/sdk/hik/service/DoorService.java | 1 + .../sis/sdk/hik/service/SdkBaseServer.java | 37 ++++++- .../sdk/unview/service/VideoAlarmService.java | 99 ++++++++++--------- .../src/main/resources/application.properties | 4 +- 8 files changed, 183 insertions(+), 58 deletions(-) create mode 100644 ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/calback/HikAlarmCallBack.java diff --git a/pom.xml b/pom.xml index 121b2d4..360d154 100644 --- a/pom.xml +++ b/pom.xml @@ -91,8 +91,10 @@ dev - 192.168.110.207:8848 - 192.168.110.207:4560 + 47.109.37.87:8848 + 47.109.37.87:4560 + + DEFAULT_GROUP DEFAULT_GROUP nacos diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/runner/HikDeviceApplicationRunner.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/runner/HikDeviceApplicationRunner.java index 5adfabe..268f874 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/runner/HikDeviceApplicationRunner.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/runner/HikDeviceApplicationRunner.java @@ -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 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); + } + } + } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikApiService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikApiService.java index f4003e9..4280851 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikApiService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikApiService.java @@ -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); + } } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/calback/HikAlarmCallBack.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/calback/HikAlarmCallBack.java new file mode 100644 index 0000000..fedfff0 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/calback/HikAlarmCallBack.java @@ -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; + } +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/service/DoorService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/service/DoorService.java index 59c5524..1f218a9 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/service/DoorService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/service/DoorService.java @@ -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); diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/service/SdkBaseServer.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/service/SdkBaseServer.java index 9353671..cad9ba8 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/service/SdkBaseServer.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/service/SdkBaseServer.java @@ -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_RESULT),1- 新报警信息(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; + } + } + /** * 登出操作 diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/unview/service/VideoAlarmService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/unview/service/VideoAlarmService.java index a3b3f2d..4f02b8f 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/unview/service/VideoAlarmService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/unview/service/VideoAlarmService.java @@ -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 arrs = Arrays.asList(2, 2, 2, 3, 3, 3 ,3, 3, 3, 3, 3, 3, 3, 3, 3, 3); + List 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 待实现 +// } +// }); } /** diff --git a/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties b/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties index 7793dd7..a76b51d 100644 --- a/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties +++ b/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties @@ -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