背景
有个项目,需要对海康的门禁设备进行集成,后台统一管理设备,进行设备人脸数据的下发、删除等操作
技术调研
一开始没有接触过物联网这块,走了很多弯路,后面还是自己一点点摸索出来的。话不多说,直接去海康的开放平台(点这里)、然后点击【设备集成SDK】
选中 设备网络SDK---->资源下载
然后我下载了window版本 以及 Linux版本的。(window 是为了调试,Linux是正式使用)
下载后,解压文件。会得到以下的文件目录
开始集成
1.把库文件夹下的.dll文件以及HCNetSDKCom文件夹找个地方放着,千万注意路径不要有中文(我放到了项目中)
2.把demo中代码复制进来,后续需要使用(我对接的是门禁设备)
我新建了个haikang文件夹。大家可以参考我这种方式,
也可以让 Common、NetSDKDdemo这两个文件与 Acs文件夹同级。
3. 由于AcsMain的代码是直接main方法调用,需要进行改造。
下面是改造后代码,注意 HCNetSDK以及 osSelect的包名安装自己的实际位置来。
在linux系统中,sdk我使用的是绝对路径,把Linux版本的文件放到服务时,一定要给该文件夹以及下面的子文件授权。路径也不要有中文,切记!!!
import com.bgyfw.bcsc.modules.haikang.Acs.Commom.osSelect;
import com.bgyfw.bcsc.modules.haikang.Acs.NetSDKDemo.HCNetSDK;
import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Slf4j
@Component
public class AcsMain {
public static HCNetSDK hCNetSDK = null;
@PostConstruct
public void initSdk(){
String strDllPath = "";
log.info("开始初始化:{}","HCNetSDK");
try {
if(osSelect.isWindows()){
//win系统加载库路径
strDllPath = System.getProperty("user.dir") + "\\file\\hkfile\\window\\HCNetSDK.dll";
//log.info("获取到的系统是:{}","win");
}
else if(osSelect.isLinux()){
//Linux系统加载库路径
strDllPath ="/home/NetSDK/linux64/libhcnetsdk.so";
//log.info("获取到的系统是:{}","Linux");
}
log.info("获取到SDK路径是:{}",strDllPath);
hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
log.info("Load SDK SUCCESS====================================================================");
//linux系统建议调用以下接口加载组件库
if (osSelect.isLinux()) {
HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
//这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限
String strPath1 = "/home/NetSDK/linux64/libcrypto.so.1.1";
String strPath2 = "/home/NetSDK/linux64/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 = "/home/NetSDK/linux64/";
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());
}
//开启SDK日志打印
boolean i= hCNetSDK.NET_DVR_SetLogToFile(3, "./sdklog", false);
//设置报警回调函数
log.info("SDK INIT SUCCESS====================================================================");
}catch (Exception ex) {
log.info("Load SDK FAIL====================================================================");
}
}
}
4. 改造ACSManage,增加 设备的登录 以及 注销 的方法
注意 HCNetSDK以及 osSelect的包名安装自己的实际位置来。
import com.bgyfw.bcsc.modules.haikang.Acs.NetSDKDemo.HCNetSDK;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
/**
* 门禁设备管理:
* 1、获取(设置)门禁主机参数
* 2、获取门禁主机工作状态
*/
@Slf4j
public final class ACSManage {
static int iCharEncodeType;
// 之前的代码不变---------------------
/**
* 登出操作
*
*/
public static void logoutById(int lUserID){
/**登出和清理,释放SDK资源*/
if (lUserID>=0) {
if (!AcsMain.hCNetSDK.NET_DVR_Logout(lUserID)) {
log.info("设备注销失败,错误码:{}" ,AcsMain.hCNetSDK.NET_DVR_GetLastError());
return;
}
//释放SDK,程序退出前调用
AcsMain.hCNetSDK.NET_DVR_Cleanup();
log.info("设备注销成功!!!");
}
}
/**
* 设备登录
* @param ipadress IP地址
* @param user 用户名
* @param psw 密码
* @param port 端口,默认8000
*/
public static int login_V40(String ipadress, String user, String psw, short port) {
AcsMain.hCNetSDK.NET_DVR_Init();
int lUserID=-1;
//注册
HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
String m_sDeviceIP = ipadress;//设备ip地址
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());
m_strLoginInfo.wPort = port; //sdk端口
m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
m_strLoginInfo.write();
HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
lUserID = AcsMain.hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
if (lUserID == -1) {
System.out.println("登录失败,错误码为" + AcsMain.hCNetSDK.NET_DVR_GetLastError());
return lUserID;
} else {
System.out.println("登录成功!");
m_strDeviceInfo.read();
iCharEncodeType = m_strDeviceInfo.byCharEncodeType;
//System.out.println("字符集::"+iCharEncodeType);
return lUserID;
}
}
}
5.把demo 中 lib下的三个jar包也放到项目中
在pom.xml中引入。
<dependency>
<groupId>net.java.jna</groupId>
<artifactId>jna</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../file/lib/jna.jar</systemPath>
</dependency>
<dependency>
<groupId>net.java.examples</groupId>
<artifactId>examples</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../file/lib/examples.jar</systemPath>
</dependency>
<dependency>
<groupId>net.java.json</groupId>
<artifactId>json</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../file/lib/json.jar</systemPath>
</dependency>
在pom.xml 需要增加以下配置 <includeSystemScope>true</includeSystemScope>
不然无法把刚才的三个jar包一并打包部署。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
<!--设置为true,以便把本地的system的jar也包括进来-->
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
启动项目,出现 sdk init success 说明初始化成功了。接下来可以根据开发文档进行业务开发了。
Acs文件夹下的 各个Manage都有现成的代码,可以根据自己的需要调用即可。
登录设备, userID不为-1,说明登录成功
int userID = ACSManage.login_V40(a.getDeviceIp(),
a.getDeviceUser(),
a.getDevicePwd(),
Short.parseShort(a.getDevicePort()));
操作完毕后,请一定记得释放资源
ACSManage.logoutById(userID);
在sdk文件下有个开发文档,最下面有个使用手册,开发之前最好是先看一下。
后续
1.每个人碰到的问题不同,如果无法处理或者有疑问,欢迎留言。
2.sdk的存放路径不要有中文,不然会出现很多奇怪的问题
3.我还接入了门禁设备的事件监听,门禁所有的事件都会上报到后台服务,这块代码有需要的可以找我。