1.需求
需要做一个指纹登录系统,录入指纹,修改指纹等,指纹比对等。
2.开发
开启指纹采集器,指纹采集器base64数据录入到数据库以及指纹登录登出
package com.iot.modules.biz.fp;
import com.iot.common.util.CommonUtil;
import com.iot.modules.biz.dao.FpMapper;
import com.iot.modules.biz.dao.UserMapper;
import com.iot.modules.biz.entity.Fp;
import com.iot.modules.biz.entity.User;
import com.iot.modules.biz.opc.OpcUaConfig;
import com.iot.modules.biz.quart.ScheduleFrontprocessService;
import com.iot.modules.biz.redis.RedisUtil;
import com.zkteco.biometric.FingerprintSensorErrorCode;
import com.zkteco.biometric.FingerprintSensorEx;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
@Configuration
@Slf4j
@Service
public class FpConfig {
@Autowired
FpMapper fpMapper;
//the width of fingerprint image
int fpWidth = 0;
//the height of fingerprint image
int fpHeight = 0;
//for verify test
private byte[] lastRegTemp = new byte[2048];
//the length of lastRegTemp
private int cbRegTemp = 0;
//pre-register template
private byte[][] regtemparray = new byte[3][2048];
//Register
private boolean bRegister = false;
//Identify
private boolean bIdentify = true;
//finger id
private int iFid = 1;
private int nFakeFunOn = 1;
//must be 3
static final int enroll_cnt = 3;
//the index of pre-register function
private int enroll_idx = 0;
private byte[] imgbuf = null;
private byte[] template = new byte[2048];
private int[] templateLen = new int[1];
private boolean mbStop = true;
private long mhDevice = 0;
private long mhDB = 0;
private WorkThread workThread = null;
@Autowired
private RedisUtil redisUtil;
@Autowired
private UserMapper userMapper;
@Autowired
ScheduleFrontprocessService scheduleFrontprocessService;
@Autowired
OpcUaConfig opcUaConfig;
@Bean
public void actionPerformed() {
// TODO Auto-generated method stub
if (0 != mhDevice) {
//already inited
log.error("请先关闭设备!");
return;
}
int ret = FingerprintSensorErrorCode.ZKFP_ERR_OK;
//Initialize
cbRegTemp = 0;
bRegister = false;
bIdentify = false;
iFid = 1;
enroll_idx = 0;
if (FingerprintSensorErrorCode.ZKFP_ERR_OK != FingerprintSensorEx.Init()) {
log.error("初始化失败!");
;
}
ret = FingerprintSensorEx.GetDeviceCount();
if (ret < 0) {
log.error("未连接任何设备!");
FreeSensor();
return;
}
if (0 == (mhDevice = FingerprintSensorEx.OpenDevice(0))) {
log.error("打开设备失败,状态! = " + ret + "!");
FreeSensor();
return;
}
if (0 == (mhDB = FingerprintSensorEx.DBInit())) {
log.error("初始化数据库失败, 状态! = " + ret + "!");
FreeSensor();
return;
}
//set fakefun off
//FingerprintSensorEx.SetParameter(mhDevice, 2002, changeByte(nFakeFunOn), 4);
byte[] paramValue = new byte[4];
int[] size = new int[1];
//GetFakeOn
//size[0] = 4;
//FingerprintSensorEx.GetParameters(mhDevice, 2002, paramValue, size);
//nFakeFunOn = byteArrayToInt(paramValue);
size[0] = 4;
FingerprintSensorEx.GetParameters(mhDevice, 1, paramValue, size);
fpWidth = byteArrayToInt(paramValue);
size[0] = 4;
FingerprintSensorEx.GetParameters(mhDevice, 2, paramValue, size);
fpHeight = byteArrayToInt(paramValue);
//width = fingerprintSensor.getImageWidth();
//height = fingerprintSensor.getImageHeight();
imgbuf = new byte[fpWidth * fpHeight];
mbStop = false;
// 指纹线程
workThread = new WorkThread();
workThread.start();// 启动线程
log.info("打开成功!");
}
@Service
public class WorkThread extends Thread {
@SneakyThrows
@Override
public void run() {
super.run();
int ret = 0;
while (!mbStop) {
templateLen[0] = 2048;
if (0 == (ret = FingerprintSensorEx.AcquireFingerprint(mhDevice, imgbuf, template, templateLen))) {
if (nFakeFunOn == 1) {
byte[] paramValue = new byte[4];
int[] size = new int[1];
size[0] = 4;
int nFakeStatus = 0;
//GetFakeStatus
ret = FingerprintSensorEx.GetParameters(mhDevice, 2004, paramValue, size);
nFakeStatus = byteArrayToInt(paramValue);
System.out.println("ret = " + ret + ",nFakeStatus=" + nFakeStatus);
if (0 == ret && (byte) (nFakeStatus & 31) != 31) {
log.error("是假货吗?");
return;
}
}
String strBase64 = FingerprintSensorEx.BlobToBase64(template, templateLen[0]);
Fp fp = fpMapper.selectById(1);
fp.setFp(strBase64);
fpMapper.updateById(fp);
System.out.println("strBase64=" + strBase64);
// 登录或者登出信号
String saoMaDengLuTuiChu = redisUtil.pudReidsKeyObject("fycgplc01.saomadengludengchu").toString();
if (saoMaDengLuTuiChu.equals("1.0") || saoMaDengLuTuiChu.equals("2.0")) {
String onExtractOK = OnExtractOK(template, templateLen[0]);
if (onExtractOK.equals("-17")) {
opcUaConfig.writeOpcUa("saomadengludengchu", "0");
continue;
}
if (onExtractOK.length() < 4) {
onExtractOK = CommonUtil.intToBinary2(onExtractOK);
}
User user = userMapper.selectUserNumber(onExtractOK);
// 登录
if (saoMaDengLuTuiChu.equals("1.0")) {
opcUaConfig.writeOpcUa("saomadengludengchu", "0");
log.info("指纹登录成功!{}",user);
scheduleFrontprocessService.authorityRepeat(user);
}
// 登出
if (saoMaDengLuTuiChu.equals("2.0")) {
opcUaConfig.writeOpcUa("saomadengludengchu", "0");
log.info("指纹登出成功!{}",user);
scheduleFrontprocessService.signOutAuthorityRepeat(user);
}
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void runOnUiThread(Runnable runnable) {
// TODO Auto-generated method stub
}
}
private String OnExtractOK(byte[] template, int len) {
int[] fid = new int[1];
int[] score = new int[1];
int ret = FingerprintSensorEx.DBIdentify(mhDB, template, fid, score);
if (ret == 0) {
return String.valueOf(fid[0]);
} else {
log.info("识别失败,错误码=" + ret);
return String.valueOf(ret);
}
}
private void FreeSensor() {
mbStop = true;
try { //wait for thread stopping
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (0 != mhDB) {
FingerprintSensorEx.DBFree(mhDB);
mhDB = 0;
}
if (0 != mhDevice) {
FingerprintSensorEx.CloseDevice(mhDevice);
mhDevice = 0;
}
FingerprintSensorEx.Terminate();
}
public static byte[] intToByteArray(final int number) {
byte[] abyte = new byte[4];
abyte[0] = (byte) (0xff & number);
abyte[1] = (byte) ((0xff00 & number) >> 8);
abyte[2] = (byte) ((0xff0000 & number) >> 16);
abyte[3] = (byte) ((0xff000000 & number) >> 24);
return abyte;
}
public static int byteArrayToInt(byte[] bytes) {
int number = bytes[0] & 0xFF;
number |= ((bytes[1] << 8) & 0xFF00);
number |= ((bytes[2] << 16) & 0xFF0000);
number |= ((bytes[3] << 24) & 0xFF000000);
return number;
}
}
定时器循环更新指纹(需求 多个指纹采集器,一个录入采集器 ,一个比对采集器)
private long mhDB = 0;
/**
* 循环录入指纹
*/
@Scheduled(fixedRate = 30000)
public void fpRealTimeEntry() {
// 获取所有录入过指纹的打开后直接录入
EntityWrapper entityWrapper = new EntityWrapper();
entityWrapper.eq("device_type", "smt");
entityWrapper.eq("status", "1");
List<User> list = userMapper.selectList(entityWrapper);
int ret = FingerprintSensorErrorCode.ZKFP_ERR_OK;
if (0 == (mhDB = FingerprintSensorEx.DBInit())) {
log.error("初始化数据库失败, 状态! = " + ret + "!");
return;
}
for (User fp : list) {
if (StringUtil.isNotBlank(fp.getFingerPrintBase64())) {
String regTemps = fp.getFingerPrintBase64();
int number = Double.valueOf(fp.getNumber()).intValue();
byte[] decoded = Base64.decodeBase64(regTemps.getBytes());
int i1 = FingerprintSensorEx.DBDel(mhDB, number);
System.out.println("删除当前指纹"+i1);
int i = FingerprintSensorEx.DBAdd(mhDB, number, decoded);
System.out.println(i);
}
}
}
3. 打包发布
运行zkdemo注意环境的坑
Java环境配置:
export JAVA_HOME=/home/java/jdk1.8.0_291
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib
:wq!
// 刷新一下
source /etc/profile
打jar包,
libs文件跟jar包同一目录
发布命令: LD_LIBRARY_PATH=./libs nohup java -jar iot.jar &
4.完结: