前言: 咨询过很多次海康的官方客服,看了操作手册,然后再分析了集成的SDK文档,总结了以下的代码以及结论。
功能:我实现的二维码核验的功能
步骤:
1.设备初始化
2.加载日志
3.设备进行登录
4.配置门禁参数开启远程核验功能和相关参数
5.事件查询
6.设备通道布防,设备回调函数,事件监听报警
7.根据业务远程控门
具体业务需要具体实现,我的思路以及代码仅供参考
上代码:
文件先放进项目中
还要将两个类放入项目中,这个SDK里面有我就不提供了,需要的话私信我
导入依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>examples</artifactId>
<version>0.2.3</version>
</dependency>
<dependency>
<groupId>com.sun.jna</groupId>
<artifactId>jna</artifactId>
<version>3.0.9</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.13.0</version>
</dependency>
<!--工具类依赖-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>6.1.1</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<compilerArguments>
<extdirs>${project.basedir}/src/main/resources/lib</extdirs>
</compilerArguments>
</configuration>
</plugin>
</plugins>
</build>
初始化登录代码:
package com.ruoyi.verify.config;
import com.ruoyi.verify.Commom.osSelect;
import com.ruoyi.verify.SDKDome.HCNetSDK;
import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
/**
* 设备初始化
*/
@Configuration
@Slf4j
public class InitConfig{
public static HCNetSDK hCNetSDK = null;
//用户句柄
public static int lUserID = -1;
//设备字符集
public static int iCharEncodeType = 0;
/**
* 根据不同操作系统选择不同的库文件和库路径
*
* @return
*/
private static boolean createSDKInstance() {
if (hCNetSDK == null) {
synchronized (HCNetSDK.class) {
String strDllPath = "";
try {
//System.setProperty("jna.debug_load", "true");
if (osSelect.isWindows()) {
//win系统加载库路径
strDllPath = System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll";
} else if (osSelect.isLinux()) {
//Linux系统加载库路径
strDllPath = System.getProperty("user.dir") + "/lib/libhcnetsdk.so";
}
hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
} catch (Exception ex) {
log.info("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
return false;
}
}
}
return true;
}
public static int creatUserId() throws Exception {
//开始设备初始化操作
if (hCNetSDK == null) {
if (!createSDKInstance()) {
log.info("Load SDK fail");
return -1;
}
}
//linux系统建议调用以下接口加载组件库
if (osSelect.isLinux()) {
HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
//这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限
String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1";
String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1";
System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
ptrByteArray1.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArray1.getPointer());
System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
ptrByteArray2.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer());
String strPathCom = System.getProperty("user.dir") + "/lib/";
HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
struComPath.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
}
/**初始化*/
hCNetSDK.NET_DVR_Init();
/**加载日志*/
boolean i = hCNetSDK.NET_DVR_SetLogToFile(3, "./sdklog", false);
/**登录*/
int lUserID = login_V40("设备IP", "admin", "设备登录密码", (short) 8000);
return lUserID;
}
/**
* 设备登录
*
* @param ipadress IP地址
* @param user 用户名
* @param psw 密码
* @param port 端口,默认8000
*/
public static int login_V40(String ipadress, String user, String psw, short port) {
//注册
//设备登录信息
HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
//设备ip地址
String m_sDeviceIP = ipadress;
m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
//设备用户名
String m_sUsername = user;
m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
//设备密码
String m_sPassword = psw;
m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
//sdk端口
m_strLoginInfo.wPort = port;
//是否异步登录:0- 否,1- 是
m_strLoginInfo.bUseAsynLogin = false;
m_strLoginInfo.write();
//设备信息
HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
if (lUserID == -1) {
log.info("登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
return -1;
} else {
log.info("登录成功!");
m_strDeviceInfo.read();
iCharEncodeType = m_strDeviceInfo.byCharEncodeType;
return lUserID;
}
}
}
配置门禁参数类
package com.ruoyi.verify.config;
import com.ruoyi.verify.SDKDome.HCNetSDK;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
/**
* 获取门禁参数配置类
*/
@Slf4j
@Configuration
public class DoorParam{
/**
* 配置门禁参数
*
* @param lUserID
* @param szUrl 固定:"PUT /ISAPI/AccessControl/AcsCfg?format=json\r\n"
* @return
*/
public static String doorParam(int lUserID, String szUrl) {
HCNetSDK.NET_DVR_XML_CONFIG_INPUT struXMLInput = new HCNetSDK.NET_DVR_XML_CONFIG_INPUT();
struXMLInput.read();
HCNetSDK.BYTE_ARRAY stringRequest = new HCNetSDK.BYTE_ARRAY(1024);
stringRequest.read();
//输入ISAPI协议命令
System.arraycopy(szUrl.getBytes(), 0, stringRequest.byValue, 0, szUrl.length());
stringRequest.write();
// 输入JSON数据
String pBuf = "{\"AcsCfg\":{\"uploadCapPic\": true,\"remoteCheckDoorEnabled\": false,\"checkChannelType\": \"PrivateSDK\",\"channelIp\" : \"通道IP\"}}";
HCNetSDK.BYTE_ARRAY lpBuf = new HCNetSDK.BYTE_ARRAY(1024);
lpBuf.read();
System.arraycopy(pBuf.getBytes(), 0, lpBuf.byValue, 0, pBuf.length());
lpBuf.write();
struXMLInput.dwSize = struXMLInput.size();
struXMLInput.lpRequestUrl = stringRequest.getPointer();
struXMLInput.dwRequestUrlLen = szUrl.length();
struXMLInput.lpInBuffer = lpBuf.getPointer();
struXMLInput.dwInBufferSize = lpBuf.byValue.length;
struXMLInput.write();
HCNetSDK.BYTE_ARRAY stringXMLOut = new HCNetSDK.BYTE_ARRAY(8 * 1024);
stringXMLOut.read();
HCNetSDK.BYTE_ARRAY struXMLStatus = new HCNetSDK.BYTE_ARRAY(1024);
struXMLStatus.read();
HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT struXMLOutput = new HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT();
struXMLOutput.read();
struXMLOutput.dwSize = struXMLOutput.size();
struXMLOutput.lpOutBuffer = stringXMLOut.getPointer();
struXMLOutput.dwOutBufferSize = stringXMLOut.size();
struXMLOutput.lpStatusBuffer = struXMLStatus.getPointer();
struXMLOutput.dwStatusSize = struXMLStatus.size();
struXMLOutput.write();
//配置门禁参数
if (!InitConfig.hCNetSDK.NET_DVR_STDXMLConfig(lUserID, struXMLInput, struXMLOutput)) {
int iErr = InitConfig.hCNetSDK.NET_DVR_GetLastError();
System.err.println("NET_DVR_STDXMLConfig失败,错误号" + iErr + "----URL:" + szUrl);
return null;
} else {
stringXMLOut.read();
log.info("输出文本大小:" + struXMLOutput.dwReturnedXMLSize);
//打印输出XML文本
String strOutXML = new String(stringXMLOut.byValue).trim();
log.info(strOutXML);
struXMLStatus.read();
String strStatus = new String(struXMLStatus.byValue).trim();
log.info(strStatus);
}
//获取门禁参数
szUrl = "GET /ISAPI/AccessControl/AcsCfg?format=json\r\n";
HCNetSDK.BYTE_ARRAY stringResponse = new HCNetSDK.BYTE_ARRAY(1024);
stringResponse.read();
//输入ISAPI协议命令
System.arraycopy(szUrl.getBytes(), 0, stringResponse.byValue, 0, szUrl.length());
stringResponse.write();
struXMLInput.lpRequestUrl = stringResponse.getPointer();
struXMLInput.dwRequestUrlLen = szUrl.length();
//获取时输入为空
struXMLInput.lpInBuffer = null;
struXMLInput.dwInBufferSize = 0;
//分配输出内存
HCNetSDK.BYTE_ARRAY szGetOutput = new HCNetSDK.BYTE_ARRAY(1024 * 8);
struXMLOutput.lpOutBuffer = szGetOutput.getPointer();
struXMLOutput.dwOutBufferSize = szGetOutput.size();
if (!InitConfig.hCNetSDK.NET_DVR_STDXMLConfig(lUserID, struXMLInput, struXMLOutput)) {
log.info("GET /ISAPI/AccessControl/AcsCfg?format=json failed, error code: " + InitConfig.hCNetSDK.NET_DVR_GetLastError());
return "GET /ISAPI/AccessControl/AcsCfg?format=json failed, error code: " + InitConfig.hCNetSDK.NET_DVR_GetLastError();
} else {
log.info("GET /ISAPI/AccessControl/AcsCfg?format=json successfully!");
System.out.println(szGetOutput);
}
return szGetOutput.toString();
}
}
查询所有事件
package com.ruoyi.verify.config;
import com.ruoyi.verify.SDKDome.HCNetSDK;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
@Slf4j
@Configuration
public class SelectEvent{
/**
* 根据UserID查询事件,查询的是所有事件
* @param lUserID
* @throws UnsupportedEncodingException
* @throws InterruptedException
*/
public static void searchAllEvent(int lUserID) throws UnsupportedEncodingException, InterruptedException {
//事件条数
int i = 0;
HCNetSDK.NET_DVR_ACS_EVENT_COND struAcsEventCond = new HCNetSDK.NET_DVR_ACS_EVENT_COND();
struAcsEventCond.read();
struAcsEventCond.dwSize = struAcsEventCond.size();
//查询全部主次类型的报警
// 主次事件类型设为0,代表查询所有事件
struAcsEventCond.dwMajor = 0;
struAcsEventCond.dwMinor = 0;
//开始时间
struAcsEventCond.struStartTime.dwYear = 2022;
struAcsEventCond.struStartTime.dwMonth = 4;
struAcsEventCond.struStartTime.dwDay = 27;
struAcsEventCond.struStartTime.dwHour = 9;
struAcsEventCond.struStartTime.dwMinute = 0;
struAcsEventCond.struStartTime.dwSecond = 0;
//结束时间
struAcsEventCond.struEndTime.dwYear = 2025;
struAcsEventCond.struEndTime.dwMonth = 4;
struAcsEventCond.struEndTime.dwDay = 30;
struAcsEventCond.struEndTime.dwHour = 16;
struAcsEventCond.struEndTime.dwMinute = 0;
struAcsEventCond.struEndTime.dwSecond = 0;
struAcsEventCond.wInductiveEventType = 1;
struAcsEventCond.byPicEnable = 1; //是否带图片,0-不带图片,1-带图片
struAcsEventCond.write();
Pointer ptrStruEventCond = struAcsEventCond.getPointer();
int m_lSearchEventHandle = InitConfig.hCNetSDK.NET_DVR_StartRemoteConfig(lUserID, HCNetSDK.NET_DVR_GET_ACS_EVENT, ptrStruEventCond, struAcsEventCond.size(), null, null);
if (m_lSearchEventHandle<=-1)
{
log.info("NET_DVR_StartRemoteConfig调用失败,错误码:" + InitConfig.hCNetSDK.NET_DVR_GetLastError());
}
HCNetSDK.NET_DVR_ACS_EVENT_CFG struAcsEventCfg = new HCNetSDK.NET_DVR_ACS_EVENT_CFG();
struAcsEventCfg.read();
struAcsEventCfg.dwSize = struAcsEventCfg.size();
struAcsEventCfg.write();
Pointer ptrStruEventCfg = struAcsEventCfg.getPointer();
while (true) {
log.info("i=" + i);
int dwEventSearch = InitConfig.hCNetSDK.NET_DVR_GetNextRemoteConfig(m_lSearchEventHandle, ptrStruEventCfg, struAcsEventCfg.size());
if (dwEventSearch <= -1) {
log.info("NET_DVR_GetNextRemoteConfig接口调用失败,错误码:" + InitConfig.hCNetSDK.NET_DVR_GetLastError());
}
if (dwEventSearch == HCNetSDK.NET_SDK_GET_NEXT_STATUS_NEED_WAIT) {
log.info("配置等待....");
Thread.sleep(10);
continue;
} else if (dwEventSearch == HCNetSDK.NET_SDK_NEXT_STATUS__FINISH) {
log.info("获取事件完成");
break;
} else if (dwEventSearch == HCNetSDK.NET_SDK_GET_NEXT_STATUS_FAILED) {
log.info("获取事件出现异常");
break;
} else if (dwEventSearch == HCNetSDK.NET_SDK_GET_NEXT_STATUS_SUCCESS) {
struAcsEventCfg.read();
//获取的事件信息通过struAcsEventCfg结构体进行解析,
log.info(i + "获取事件成功, 报警主类型:" + Integer.toHexString(struAcsEventCfg.dwMajor) + "报警次类型:" + Integer.toHexString(struAcsEventCfg.dwMinor) + "卡号:" + new String(struAcsEventCfg.struAcsEventInfo.byCardNo).trim());
/**
* 工号有两个字段,dwEmployeeNo表示工号,当值为0时,表示无效,解析byEmployeeNo参数
*/
log.info("工号1:"+struAcsEventCfg.struAcsEventInfo.dwEmployeeNo);
log.info("工号2:"+new String(struAcsEventCfg.struAcsEventInfo.byEmployeeNo));
//人脸温度数据,需要设备和支持测温功能
log.info("人脸温度:" + struAcsEventCfg.struAcsEventInfo.fCurrTemperature + "是否异常:" + struAcsEventCfg.struAcsEventInfo.byIsAbnomalTemperature);
//口罩功能,需要设备支持此功能 0-保留,1-未知,2-不戴口罩,3-戴口罩
log.info("是否带口罩:"+struAcsEventCfg.struAcsEventInfo.byMask);
//人脸图片保存
if (struAcsEventCfg.dwPicDataLen>0 || struAcsEventCfg.pPicData != null )
{
FileOutputStream fout;
try {
/**
* 人脸图片保存路径
*/
String filename = "..\\pic\\"+i+"_event.jpg";
fout = new FileOutputStream(filename);
//将字节写入文件
long offset = 0;
ByteBuffer buffers = struAcsEventCfg.pPicData.getByteBuffer(offset, struAcsEventCfg.dwPicDataLen);
byte[] bytes = new byte[struAcsEventCfg.dwPicDataLen];
buffers.rewind();
buffers.get(bytes);
fout.write(bytes);
fout.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
i++;
continue;
}
}
i = 0;
if (!InitConfig.hCNetSDK.NET_DVR_StopRemoteConfig(m_lSearchEventHandle)) {
log.info("NET_DVR_StopRemoteConfig接口调用失败,错误码:" + InitConfig.hCNetSDK.NET_DVR_GetLastError());
} else {
log.info("NET_DVR_StopRemoteConfig接口成功");
}
return ;
}
}
通道布防,设置回调函数,实时获取事件
package com.ruoyi.verify.config;
import com.ruoyi.verify.SDKDome.HCNetSDK;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
/**
* 设置通道上传
*/
@Slf4j
@Configuration
public class UpChannel{
// 报警回调函数实现
public static HCNetSDK.FMSGCallBack_V31 fMSFCallBack_V31;
/**
* 建立布防上传通道,用于传输数据
*
* @param lUserID 唯一标识符
* @param lAlarmHandle 报警处理器
*/
public int setupAlarmChan(int lUserID, int lAlarmHandle) {
// 根据设备注册生成的lUserID建立布防的上传通道,即数据的上传通道
if (lUserID == -1) {
log.info("请先注册");
return lUserID;
}
if (lAlarmHandle < 0) {
// 设备尚未布防,需要先进行布防
if (fMSFCallBack_V31 == null) {
fMSFCallBack_V31 = new FMSGCallBack_V31();
Pointer pUser = null;
if (!InitConfig.hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(fMSFCallBack_V31, pUser)) {
log.info("设置回调函数失败!", InitConfig.hCNetSDK.NET_DVR_GetLastError());
}
}
// 这里需要对设备进行相应的参数设置,不设置或设置错误都会导致设备注册失败
HCNetSDK.NET_DVR_SETUPALARM_PARAM m_strAlarmInfo = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
m_strAlarmInfo.dwSize = m_strAlarmInfo.size();
// 智能交通布防优先级:0 - 一等级(高),1 - 二等级(中),2 - 三等级(低)
m_strAlarmInfo.byLevel = 1;
// 智能交通报警信息上传类型:0 - 老报警信息(NET_DVR_PLATE_RESULT), 1 - 新报警信息(NET_ITS_PLATE_RESULT)
m_strAlarmInfo.byAlarmInfoType = 1;
// 布防类型(仅针对门禁主机、人证设备):0 - 客户端布防(会断网续传),1 - 实时布防(只上传实时数据)
m_strAlarmInfo.byDeployType = 1;
// 抓拍,这个类型要设置为 0 ,最重要的一点设置
m_strAlarmInfo.byFaceAlarmDetection = 0;
m_strAlarmInfo.write();
// 布防成功,返回布防成功的数据传输通道号
lAlarmHandle = InitConfig.hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, m_strAlarmInfo);
if (lAlarmHandle == -1) {
log.info("设备布防失败,错误码=========={}", InitConfig.hCNetSDK.NET_DVR_GetLastError());
// 注销 释放sdk资源
logout(lUserID);
return lAlarmHandle;
} else {
log.info("设备布防成功");
return lAlarmHandle;
}
}
return lAlarmHandle;
}
/**
* 设置报警信息回调函数,根据上传的数据进行回调触发
*/
public class FMSGCallBack_V31 implements HCNetSDK.FMSGCallBack_V31 {
// lCommand 上传消息类型,这个是设备上传的数据类型,比如现在测试的门禁设备,回传回来的是 COMM_ALARM_ACS = 0x5002; 门禁主机报警信息
// pAlarmer 报警设备信息
// pAlarmInfo 报警信息 根据 lCommand 来选择接收的报警信息数据结构
// dwBufLen 报警信息缓存大小
// pUser 用户数据
@Override
public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
alarmDataHandle(lCommand, pAlarmer, pAlarmInfo, dwBufLen, pUser);
return true;
}
}
/**
* 报警撤防
*
* @param lAlarmHandle 报警处理器
*/
public int closeAlarmChan(int lAlarmHandle) {
if (lAlarmHandle > -1) {
if (InitConfig.hCNetSDK.NET_DVR_CloseAlarmChan_V30(lAlarmHandle)) {
log.info("撤防成功");
lAlarmHandle = -1;
return lAlarmHandle;
}
return lAlarmHandle;
}
return lAlarmHandle;
}
/**
* 接收设备上传的报警信息,进行上传数据的业务逻辑处理
*
* @param lCommand 上传消息类型
* @param pAlarmer 报警设备信息
* @param pAlarmInfo 报警信息
* @param dwBufLen 报警信息缓存大小
* @param pUser 用户数据
*/
public static Pointer alarmDataHandle(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
System.out.println("报警监听中================================");
AlarmDataHandle(lCommand,pAlarmer,pAlarmInfo,dwBufLen,pUser);
String sAlarmType = new String();
String[] newRow = new String[3];
//报警时间
Date today = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String[] sIP = new String[2];
sAlarmType = new String("lCommand=0x") + Integer.toHexString(lCommand);
// lCommand是传的报警类型
switch (lCommand) {
// 摄像头实时人脸抓拍上传
case HCNetSDK.COMM_UPLOAD_FACESNAP_RESULT:
// 分配存储空间
HCNetSDK.NET_VCA_FACESNAP_RESULT strFaceSnapInfo = new HCNetSDK.NET_VCA_FACESNAP_RESULT();
strFaceSnapInfo.write();
Pointer pFaceSnapInfo = strFaceSnapInfo.getPointer();
// 写入传入数据
pFaceSnapInfo.write(0, pAlarmInfo.getByteArray(0, strFaceSnapInfo.size()), 0, strFaceSnapInfo.size());
strFaceSnapInfo.read();
sAlarmType = sAlarmType + ":人脸抓拍上传[人脸评分:" + strFaceSnapInfo.dwFaceScore + ",抓拍人脸的方式:" + strFaceSnapInfo.struFeature.byRes4 + ",性别:" + strFaceSnapInfo.struFeature.bySex + "]";
newRow[0] = dateFormat.format(today);
// 报警类型
newRow[1] = sAlarmType;
// 报警设备IP地址
sIP = new String(strFaceSnapInfo.struDevInfo.struDevIP.sIpV4).split("\0", 2);
newRow[2] = sIP[0];
log.info("人脸抓拍========{}", Arrays.toString(newRow));
// 设置日期格式
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
// new Date()为获取当前系统时间
String time = df.format(new Date());
// 人脸图片写文件
File file = new File(System.getProperty("user.dir") + "\\pic1\\");
if (!file.exists()) {
file.mkdir();
}
try {
FileOutputStream big = new FileOutputStream(System.getProperty("user.dir") + "\\pic1\\" + time + "background.jpg");
if (strFaceSnapInfo.dwFacePicLen > 0) {
if (strFaceSnapInfo.dwFacePicLen > 0) {
try {
big.write(strFaceSnapInfo.pBuffer2.getByteArray(0, strFaceSnapInfo.dwBackgroundPicLen), 0, strFaceSnapInfo.dwBackgroundPicLen);
big.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
break;
// 门禁主机类型实时人脸抓拍上传,走这里
case HCNetSDK.COMM_ALARM_ACS:
// 分配存储空间
System.out.println("============ 这是门禁主机的报警信息 ============");
HCNetSDK.NET_DVR_ACS_ALARM_INFO strFaceSnapInfo1 = new HCNetSDK.NET_DVR_ACS_ALARM_INFO();
strFaceSnapInfo1.write();
Pointer pFaceSnapInfo1 = strFaceSnapInfo1.getPointer();
// 写入传入数据
pFaceSnapInfo1.write(0, pAlarmInfo.getByteArray(0, strFaceSnapInfo1.size()), 0, strFaceSnapInfo1.size());
strFaceSnapInfo1.read();
// 设置日期格式
SimpleDateFormat df1 = new SimpleDateFormat("yyyyMMddHHmmss");
// new Date()为获取当前系统时间
String time1 = df1.format(new Date());
// 人脸图片写文件
File file1 = new File(System.getProperty("user.dir") + "\\pic3\\");
if (!file1.exists()) {
file1.mkdir();
}
try {
FileOutputStream big = new FileOutputStream(System.getProperty("user.dir") + "\\pic3\\" + time1 + ".jpg");
if (strFaceSnapInfo1.dwPicDataLen > 0) {
System.out.println("========== 图片有数据 ========");
if (strFaceSnapInfo1.dwPicDataLen > 0) {
try {
System.out.println("============ 图片上传成功 =============");
big.write(strFaceSnapInfo1.pPicData.getByteArray(0, strFaceSnapInfo1.dwPicDataLen), 0, strFaceSnapInfo1.dwPicDataLen);
big.close();
System.out.println("设备唯一编码=================" + strFaceSnapInfo1.struAcsEventInfo.byDeviceNo);
System.out.println("数据采集时间=================" + strFaceSnapInfo1.struTime.dwYear + strFaceSnapInfo1.struTime.dwMonth + strFaceSnapInfo1.struTime.dwDay + strFaceSnapInfo1.struTime.dwHour + strFaceSnapInfo1.struTime.dwMinute + strFaceSnapInfo1.struTime.dwSecond);
System.out.println("人员工号=================" + strFaceSnapInfo1.struAcsEventInfo.dwEmployeeNo);
System.out.println("人员姓名=================" + strFaceSnapInfo1.sNetUser);
System.out.println("通进类型(0:入场,1:离场)=================" + strFaceSnapInfo1.struAcsEventInfo.dwDoorNo);
System.out.println("图片唯一标识(工号加时间)=================" + strFaceSnapInfo1.struAcsEventInfo.dwEmployeeNo + time1 + ".jpg");
System.out.println("人员类型(0:白名单,1:访客,2:黑名单)=================" + strFaceSnapInfo1.struAcsEventInfo.byCardType);
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
break;
default:
newRow[0] = dateFormat.format(today);
// 报警类型
newRow[1] = sAlarmType;
// 报警设备IP地址
sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
newRow[2] = sIP[0];
log.info("其他报警信息=========={}", Arrays.toString(newRow));
break;
}
return pAlarmInfo;
}
// 抓拍图片
public static void getDVRPic(int userId) throws IOException {
// 设置通道号,其中 1 正常,-1不正常
NativeLong chanLong = new NativeLong(1);
// 返回Boolean值,判断是否获取设备能力
HCNetSDK.NET_DVR_WORKSTATE_V30 devwork = new HCNetSDK.NET_DVR_WORKSTATE_V30();
if (!InitConfig.hCNetSDK.NET_DVR_GetDVRWorkState_V30(userId, devwork)) {
System.out.println("返回设备状态失败");
}
// JPEG图像信息结构体
HCNetSDK.NET_DVR_JPEGPARA jpeg = new HCNetSDK.NET_DVR_JPEGPARA();
jpeg.wPicSize = 2; // 设置图片的分辨率
jpeg.wPicQuality = 2; // 设置图片质量
IntByReference a = new IntByReference();
SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
Date date = new Date();
int random = (int) (Math.random() * 1000);
String fileNameString = sdf.format(date) + random + ".jpg";
// 设置字节缓存
ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024);
// 抓图到文件
boolean is = InitConfig.hCNetSDK.NET_DVR_CaptureJPEGPicture(userId, chanLong.intValue(), jpeg, fileNameString.getBytes(StandardCharsets.UTF_8));
if (is) {
System.out.println("图片抓取成功,返回长度:" + a.getValue());
} else {
System.out.println("图片抓取失败:" + InitConfig.hCNetSDK.NET_DVR_GetLastError());
}
}
/**
* 获取实时报警的事件
* @param lCommand
* @param pAlarmer
* @param pAlarmInfo
* @param dwBufLen
* @param pUser
*/
public static void AlarmDataHandle(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
HCNetSDK.NET_DVR_ACS_ALARM_INFO strACSInfo;
Pointer pACSInfo;
if (lCommand == 20482) {
System.out.println("===============1111111111111==========");
strACSInfo = new HCNetSDK.NET_DVR_ACS_ALARM_INFO();
strACSInfo.write();
pACSInfo = strACSInfo.getPointer();
pACSInfo.write(0, pAlarmInfo.getByteArray(0, strACSInfo.size()), 0, strACSInfo.size());
strACSInfo.read();
System.out.println("=========22222222=============");
// strACSInfo.byAcsEventInfoExtendV20=1;
// 5代表主事件类型 次事件类型9对应的16进制0x09代表无此卡号
if (strACSInfo.dwMajor == 5 && strACSInfo.dwMinor == 9) {
String deviceIP = (new String(pAlarmer.sDeviceIP)).trim();
String punchTime = strACSInfo.struTime.toStringTime();
String empCode = Integer.toString(strACSInfo.struAcsEventInfo.dwEmployeeNo);
String cardNo = (new String(strACSInfo.struAcsEventInfo.byCardNo)).trim();
System.out.println("======设备ip:====" + deviceIP);
System.out.println("======编号:====" + empCode);
System.out.println("======卡号:====" + cardNo);
System.out.println("======时间:====" + punchTime);
HCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND_V20 v20 = new HCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND_V20();
v20.write();
Pointer pp = v20.getPointer();
pp.write(0, strACSInfo.pAcsEventInfoExtendV20.getByteArray(0, v20.size()), 0, v20.size());
v20.read();
// System.out.println(v20);
System.out.println("======体温:====" + v20.fCurrTemperature);
// 在项目中可以对接数据库,进行自己的业务逻辑操作
}
}
}
/**
* 注销
*
* @param lUserID 设备注册成功唯一标识符
*/
public void logout(int lUserID) {
// 注销
InitConfig.hCNetSDK.NET_DVR_Logout(lUserID);
// 释放sdk资源
InitConfig.hCNetSDK.NET_DVR_Cleanup();
}
}
卡下发删除卡代码
package com.ruoyi.verify.config;
import com.ruoyi.verify.SDKDome.HCNetSDK;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import java.io.UnsupportedEncodingException;
import static com.ruoyi.verify.config.InitConfig.iCharEncodeType;
/**
* 下发卡和删除卡
*/
@Slf4j
@Configuration
public class SendAndDeleteCard{
/**
* 卡下发
*
* @param lUserID 用户登录句柄
* @param CardNo 卡号
* @param EmployeeNo 工号 卡下发的时候可以一起下发工号
* @param iPlanTemplateNumber 关联门计划模板,计划模板的配置可以参考卡计划模板配置模块,(下发卡前要设置好计划模板)
* @throws UnsupportedEncodingException
* @throws InterruptedException
*/
public static void setOneCard(int lUserID, String CardNo, int EmployeeNo, short iPlanTemplateNumber) throws UnsupportedEncodingException, InterruptedException {
HCNetSDK.NET_DVR_CARD_COND struCardCond = new HCNetSDK.NET_DVR_CARD_COND();
struCardCond.read();
struCardCond.dwSize = struCardCond.size();
//下发一张
struCardCond.dwCardNum = 1;
struCardCond.write();
Pointer ptrStruCond = struCardCond.getPointer();
int m_lSetCardCfgHandle = InitConfig.hCNetSDK.NET_DVR_StartRemoteConfig(lUserID, HCNetSDK.NET_DVR_SET_CARD, ptrStruCond, struCardCond.size(), null, null);
if (m_lSetCardCfgHandle == -1) {
log.info("建立下发卡长连接失败,错误码为" + InitConfig.hCNetSDK.NET_DVR_GetLastError());
return;
} else {
log.info("建立下发卡长连接成功!");
}
HCNetSDK.NET_DVR_CARD_RECORD struCardRecord = new HCNetSDK.NET_DVR_CARD_RECORD();
struCardRecord.read();
struCardRecord.dwSize = struCardRecord.size();
for (int i = 0; i < HCNetSDK.ACS_CARD_NO_LEN; i++) {
struCardRecord.byCardNo[i] = 0;
}
for (int i = 0; i < CardNo.length(); i++) {
struCardRecord.byCardNo[i] = CardNo.getBytes()[i];
}
struCardRecord.byCardType = 1; //普通卡
struCardRecord.byLeaderCard = 0; //是否为首卡,0-否,1-是
struCardRecord.byUserType = 0;
struCardRecord.byDoorRight[0] = 1; //门1有权限
struCardRecord.wCardRightPlan[0] = iPlanTemplateNumber; //关联门计划模板,计划模板的配置可以参考卡计划模板配置模块,(下发卡前要设置好计划模板)
struCardRecord.wCardRightPlan[1] = (short) 2;
struCardRecord.struValid.byEnable = 1; //卡有效期使能,下面是卡有效期从2020-1-1 11:11:11到2030-1-1 11:11:11
struCardRecord.struValid.struBeginTime.wYear = 2020;
struCardRecord.struValid.struBeginTime.byMonth = 1;
struCardRecord.struValid.struBeginTime.byDay = 1;
struCardRecord.struValid.struBeginTime.byHour = 11;
struCardRecord.struValid.struBeginTime.byMinute = 11;
struCardRecord.struValid.struBeginTime.bySecond = 11;
struCardRecord.struValid.struEndTime.wYear = 2030;
struCardRecord.struValid.struEndTime.byMonth = 1;
struCardRecord.struValid.struEndTime.byDay = 1;
struCardRecord.struValid.struEndTime.byHour = 11;
struCardRecord.struValid.struEndTime.byMinute = 11;
struCardRecord.struValid.struEndTime.bySecond = 11;
struCardRecord.dwEmployeeNo = EmployeeNo; //工号 卡下发的时候可以一起下发工号
if ((iCharEncodeType == 0) || (iCharEncodeType == 1) || (iCharEncodeType == 2)) {
byte[] strCardName = "jx".getBytes("GBK"); //姓名
for (int i = 0; i < HCNetSDK.NAME_LEN; i++) {
struCardRecord.byName[i] = 0;
}
System.arraycopy(strCardName, 0, struCardRecord.byName, 0, strCardName.length);
}
if (iCharEncodeType == 6) {
byte[] strCardName = "jx".getBytes("UTF-8"); //姓名
for (int i = 0; i < HCNetSDK.NAME_LEN; i++) {
struCardRecord.byName[i] = 0;
}
System.arraycopy(strCardName, 0, struCardRecord.byName, 0, strCardName.length);
}
struCardRecord.write();
HCNetSDK.NET_DVR_CARD_STATUS struCardStatus = new HCNetSDK.NET_DVR_CARD_STATUS();
struCardStatus.read();
struCardStatus.dwSize = struCardStatus.size();
struCardStatus.write();
IntByReference pInt = new IntByReference(0);
while (true) {
int dwState = InitConfig.hCNetSDK.NET_DVR_SendWithRecvRemoteConfig(m_lSetCardCfgHandle, struCardRecord.getPointer(), struCardRecord.size(), struCardStatus.getPointer(), struCardStatus.size(), pInt);
struCardStatus.read();
if (dwState == -1) {
log.info("NET_DVR_SendWithRecvRemoteConfig接口调用失败,错误码:" + InitConfig.hCNetSDK.NET_DVR_GetLastError());
break;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_NEED_WAIT) {
log.info("配置等待");
Thread.sleep(10);
continue;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FAILED) {
log.info("下发卡失败, 卡号: " + new String(struCardStatus.byCardNo).trim() + ", 错误码:" + struCardStatus.dwErrorCode);
break;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_EXCEPTION) {
log.info("下发卡异常, 卡号: " + new String(struCardStatus.byCardNo).trim() + ", 错误码:" + struCardStatus.dwErrorCode);
break;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_SUCCESS) {
if (struCardStatus.dwErrorCode != 0) {
log.info("下发卡成功,但是错误码" + struCardStatus.dwErrorCode + ", 卡号:" + new String(struCardStatus.byCardNo).trim());
} else {
log.info("下发卡成功, 卡号: " + new String(struCardStatus.byCardNo).trim() + ", 状态:" + struCardStatus.byStatus);
}
continue;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FINISH) {
log.info("下发卡完成");
break;
}
}
if (!InitConfig.hCNetSDK.NET_DVR_StopRemoteConfig(m_lSetCardCfgHandle)) {
log.info("NET_DVR_StopRemoteConfig接口调用失败,错误码:" + InitConfig.hCNetSDK.NET_DVR_GetLastError());
} else {
log.info("NET_DVR_StopRemoteConfig接口成功\n");
}
}
/**
* 删除单张卡(删除单张卡号之前要先删除这张卡关联的人脸和指纹信息)
*
* @param lUserID 用户登录句柄
* @param CardNo 卡号
* @throws UnsupportedEncodingException
* @throws InterruptedException
*/
public static void delOneCard(int lUserID, String CardNo) throws UnsupportedEncodingException, InterruptedException {
HCNetSDK.NET_DVR_CARD_COND struCardCond = new HCNetSDK.NET_DVR_CARD_COND();
struCardCond.read();
struCardCond.dwSize = struCardCond.size();
struCardCond.dwCardNum = 1; //删除一张卡号
struCardCond.write();
Pointer ptrStruCond = struCardCond.getPointer();
int m_lDelCardCfgHandle = InitConfig.hCNetSDK.NET_DVR_StartRemoteConfig(lUserID, HCNetSDK.NET_DVR_DEL_CARD, ptrStruCond, struCardCond.size(), null, null);
if (m_lDelCardCfgHandle == -1) {
log.info("建立删除卡长连接失败,错误码为" + InitConfig.hCNetSDK.NET_DVR_GetLastError());
return;
} else {
log.info("建立删除卡长连接成功!");
}
HCNetSDK.NET_DVR_CARD_SEND_DATA struCardData = new HCNetSDK.NET_DVR_CARD_SEND_DATA();
struCardData.read();
struCardData.dwSize = struCardData.size();
for (int i = 0; i < HCNetSDK.ACS_CARD_NO_LEN; i++) {
struCardData.byCardNo[i] = 0;
}
for (int i = 0; i < CardNo.length(); i++) {
struCardData.byCardNo[i] = CardNo.getBytes()[i];
}
struCardData.write();
HCNetSDK.NET_DVR_CARD_STATUS struCardStatus = new HCNetSDK.NET_DVR_CARD_STATUS();
struCardStatus.read();
struCardStatus.dwSize = struCardStatus.size();
struCardStatus.write();
IntByReference pInt = new IntByReference(0);
while (true) {
int dwState = InitConfig.hCNetSDK.NET_DVR_SendWithRecvRemoteConfig(m_lDelCardCfgHandle, struCardData.getPointer(), struCardData.size(), struCardStatus.getPointer(), struCardStatus.size(), pInt);
struCardStatus.read();
if (dwState == -1) {
log.info("NET_DVR_SendWithRecvRemoteConfig接口调用失败,错误码:" + InitConfig.hCNetSDK.NET_DVR_GetLastError());
break;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_NEED_WAIT) {
log.info("配置等待");
Thread.sleep(10);
continue;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FAILED) {
log.info("删除卡失败, 卡号: " + new String(struCardStatus.byCardNo).trim() + ", 错误码:" + struCardStatus.dwErrorCode);
break;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_EXCEPTION) {
log.info("删除卡异常, 卡号: " + new String(struCardStatus.byCardNo).trim() + ", 错误码:" + struCardStatus.dwErrorCode);
break;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_SUCCESS) {
if (struCardStatus.dwErrorCode != 0) {
log.info("删除卡成功,但是错误码" + struCardStatus.dwErrorCode + ", 卡号:" + new String(struCardStatus.byCardNo).trim());
} else {
log.info("删除卡成功, 卡号: " + new String(struCardStatus.byCardNo).trim() + ", 状态:" + struCardStatus.byStatus);
}
continue;
} else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FINISH) {
log.info("删除卡完成");
break;
}
}
if (!InitConfig.hCNetSDK.NET_DVR_StopRemoteConfig(m_lDelCardCfgHandle)) {
log.info("NET_DVR_StopRemoteConfig接口调用失败,错误码:" + InitConfig.hCNetSDK.NET_DVR_GetLastError());
} else {
log.info("NET_DVR_StopRemoteConfig接口成功\n");
}
}
}
远程控门
package com.ruoyi.verify.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
/**
* 远程控制门开关类
*/
@Slf4j
@Configuration
public class DoorGateway{
/**
* 远程控门
*
* @param lUserID 用户登录句柄
* @param lGatewayIndex 门禁序号(楼层编号、锁ID),从1开始,-1表示对所有门(或者梯控的所有楼层)进行操作
* @param dwStaic 命令值:0- 关闭(对于梯控,表示受控),1- 打开(对于梯控,表示开门),2- 常开(对于梯控,表示自由、通道状态),3- 常关(对于梯控,表示禁用),4- 恢复(梯控,普通状态),5- 访客呼梯(梯控),6- 住户呼梯(梯控)
*/
public static void controlGateway(int lUserID, int lGatewayIndex, int dwStaic) {
boolean b_Gate = InitConfig.hCNetSDK.NET_DVR_ControlGateway(lUserID, lGatewayIndex, dwStaic);
if (b_Gate == false) {
log.info("NET_DVR_ControlGateway远程控门失败,错误码为" + InitConfig.hCNetSDK.NET_DVR_GetLastError());
} else {
log.info("远程控门成功");
}
}
}
代码导入之后自己重新导个包,有些代码需要稍微改动,根据自己的业务进行修改