对接海康门禁-下发人员信息和人脸

对接海康门禁-下发人员信息和人脸

海康下发人员信息和人脸信息,采用的是两个接口,需要先下发人员信息,然后在下发人脸。

文中登录 退出登录 长连接和海康hCNetSDK等接口 见文章 初始SDK和登录

标题批量添加人脸

camera 设备信息含 设备账号 和IP端口

faceList 用户信息 包含人员信息和base64人脸图

java 复制代码
 /**
     * 批量添加人脸
     *
     * @param camera   摄像头信息
     * @param faceList 人脸参数
     * @return
     */
    @Override
    public List<IotCommDataResult> addFace(IotCameraParam camera, List<IotAddFaceParam> faceList) {
        //登录
        int lUserID = login_V40(camera.getIp(), new Short(String.valueOf(camera.getPort())), camera.getUsername(), camera.getPassword());
        if (lUserID == -1) {
            log.warn("登录失败,错误码为 :{}", hCNetSDK.NET_DVR_GetLastError());
            return faceList.stream().map(user -> IotCommDataResult.FAIL_RESULT(user.getUserId())).collect(Collectors.toList());
        }
        //添加用户信息
        List<IotCommDataResult> userInfoResults = this.addUserInfo(faceList, lUserID);
        try {
            Thread.sleep(500);
        } catch (Exception e) {
            log.error("休眠异常", e);
        }
        //添加人脸
        List<IotCommDataResult> userFaceResults = this.addUserFace(faceList, lUserID);

        //处理集合数据 用户成功 人脸成功才是成功
        if (CollUtil.isEmpty(userFaceResults) || CollUtil.isEmpty(userInfoResults)) {
            log.warn("添加人脸失败 userInfoResults:{} ,userFaceResults:{}", userInfoResults.size(), userFaceResults.size());
            return faceList.stream().map(user -> IotCommDataResult.FAIL_RESULT(user.getUserId())).collect(Collectors.toList());
        }
        Map<Long, IotCommDataResult> userFaceMap = userFaceResults.stream().collect(AbsCollector.toMap(IotCommDataResult::getId));
        //退出登录
        logout(lUserID);
        List<Long> delUserIds = new ArrayList<>();
        // IotCommDataResult 自定义类用来获取执行结果
        List<IotCommDataResult> userInfoResultList = userInfoResults.stream().map(user -> {
            IotCommDataResult result = new IotCommDataResult();
            if (userFaceMap.get(user.getId()) != null) {
                IotCommDataResult dataResult = userFaceMap.get(user.getId());
                if (dataResult.getCode() == 500) {
                    delUserIds.add(user.getId());
                    result.setId(user.getId());
                    result.setCode(500);
                    result.setMsg(dataResult.getMsg());
                } else {
                    result.setId(user.getId());
                    result.setCode(200);
                    result.setMsg("添加成功");
                }
            } else {
                result.setId(user.getId());
                result.setCode(500);
                result.setMsg("添加失败");
            }
            return result;
        }).collect(Collectors.toList());

        if (CollUtil.isNotEmpty(delUserIds)) {
        // 删除人员信息,删除人员信息下发成功且人脸信息下发失败的用户信息
            deleteFace(camera, delUserIds);
        }
        return userInfoResultList;
    }

添加用户信息

java 复制代码
 /**
     * 添加用户信息
     * employeeNo 设备中用户编号唯一,文中采用的是用户id
     */
    private List<IotCommDataResult> addUserInfo(List<IotAddFaceParam> paramList, int lUserID) {
        //创建连接
        String strUserInBuffer = "PUT /ISAPI/AccessControl/UserInfo/SetUp?format=json";
        // 创建长连接
        int startUserRemoteConfig = getLongConnt(strUserInBuffer, IotHikNetConstant.NET_DVR_JSON_CONFIG, lUserID);

        List<IotCommDataResult> resultList = new ArrayList<>();
        for (int i = 0; i < paramList.size(); i++) {
            IotAddFaceParam param = paramList.get(i);
            IotCommDataResult result = new IotCommDataResult();
            result.setId(param.getUserId());

            if (startUserRemoteConfig < 0) {
                log.warn("AddUserInfo NET_DVR_StartRemoteConfig 失败,错误码为 : {}", hCNetSDK.NET_DVR_GetLastError());
                result.setCode(500);
                result.setMsg("添加用户失败");
                continue;
            }
            try {
                //下发用户信息
                byte[] Name = param.getUserName().getBytes("utf-8"); //根据iCharEncodeType判断,如果iCharEncodeType返回6,则是UTF-8编码。
                //如果是0或者1或者2,则是GBK编码
                //将中文字符编码之后用数组拷贝的方式,避免因为编码导致的长度问题
                String strInBuffer1 = "{\n" + "    \"UserInfo\":{\n" + "        \"employeeNo\":\"" + param.getUserId() + "\",\n" + "        \"name\":\"";
                String strInBuffer2 = "\",\n" + "        \"userType\":\"normal\",\n" + "        \"Valid\":{\n" + "            \"enable\":false,\n" + "            \"beginTime\":\"2019-08-01T17:30:08\",\n" + "            \"endTime\":\"2030-08-01T17:30:08\",\n" + "            \"timeType\":\"local\"\n" + "        },\n" + "        \"belongGroup\":\"1\",\n" + "        \"doorRight\":\"1\",\n" + "        \"RightPlan\":[\n" + "            {\n" + "                \"doorNo\":1,\n" + "                \"planTemplateNo\":\"1\"\n" + "            }\n" + "        ]\n" + "    }\n" + "}";
                int iStringSize = Name.length + strInBuffer1.length() + strInBuffer2.length();
                BYTE_ARRAY ptrByte = new BYTE_ARRAY(iStringSize);
                System.arraycopy(strInBuffer1.getBytes(), 0, ptrByte.byValue, 0, strInBuffer1.length());
                System.arraycopy(Name, 0, ptrByte.byValue, strInBuffer1.length(), Name.length);
                System.arraycopy(strInBuffer2.getBytes(), 0, ptrByte.byValue, strInBuffer1.length() + Name.length, strInBuffer2.length());

                ptrByte.write();
                log.info("添加参数:{}", new String(ptrByte.byValue));
                BYTE_ARRAY ptrOutuff = new BYTE_ARRAY(1024);
                IntByReference pInt = new IntByReference(0);

                int dwState = hCNetSDK.NET_DVR_SendWithRecvRemoteConfig(startUserRemoteConfig, ptrByte.getPointer(), iStringSize, ptrOutuff.getPointer(), 1024, pInt);
                if (dwState == -1) {
                    log.error("NET_DVR_SendWithRecvRemoteConfig接口调用失败,错误码:{}", hCNetSDK.NET_DVR_GetLastError());
                    result.setCode(500);
                    result.setMsg("添加用户失败");
                    continue;
                }
                //读取返回的json并解析
                ptrOutuff.read();
                String strResult = new String(ptrOutuff.byValue).trim();
                log.info("addUserInfo dwState: {} ,strResult:{}", dwState, strResult);
                JSONObject jsonResult = JSONUtil.parseObj(strResult);
                int statusCode = jsonResult.getInt("statusCode");
                String statusString = jsonResult.getStr("statusString");
                responStatusMsg(dwState, param.getUserId(), statusCode, strResult);
                if (dwState == IotHikNetConstant.NET_SDK_CONFIG_STATUS_SUCCESS) {//返回NET_SDK_CONFIG_STATUS_SUCCESS代表流程走通了,但并不代表下发成功,比如有些设备可能因为人员已存在等原因下发失败,所以需要解析Json报文
                    if (statusCode != 1) {
                        result.setCode(500);
                        result.setMsg("添加用户失败");
                    } else {
                        result.setCode(200);
                        result.setMsg("添加用户成功");
                    }
                } else {
                    result.setCode(500);
                    result.setMsg("添加用户失败");
                }
            } catch (Exception e) {
                log.error("添加用户异常:", e);
                result.setCode(500);
                result.setMsg("添加用户失败");
            }
            resultList.add(result);
        }
        //关闭长连接,释放资源
        if (!hCNetSDK.NET_DVR_StopRemoteConfig(startUserRemoteConfig)) {
            log.warn("NET_DVR_StopRemoteConfig接口调用失败,错误码:{}", hCNetSDK.NET_DVR_GetLastError());
        } else {
            log.info("NET_DVR_StopRemoteConfig接口成功");
        }
        return resultList;
    }

添加人脸

java 复制代码
/**
     * 添加人脸
     * 根据工号添加人脸
     */
    private List<IotCommDataResult> addUserFace(List<IotAddFaceParam> paramList, int lUserID) {
        //创建长连接
        String strFaceInBuffer = "PUT /ISAPI/Intelligent/FDLib/FDSetUp?format=json";
//        String strFaceInBuffer = "POST /ISAPI/Intelligent/FDLib/FaceDataRecord?format=json";
        int startFaceRemoteConfig = this.getLongConnt(strFaceInBuffer, IotHikNetConstant.NET_DVR_FACE_DATA_RECORD, lUserID);
        FileInputStream picfile = null;
        //下发人脸
        List<IotCommDataResult> resultList = new ArrayList<>();
        for (int i = 0; i < paramList.size(); i++) {
            IotAddFaceParam faceParam = paramList.get(i);
            IotCommDataResult result = new IotCommDataResult();
            result.setId(faceParam.getUserId());

            if (startFaceRemoteConfig < 0) {
                log.warn("addUserFace NET_DVR_StartRemoteConfig 失败,错误码为 : {}", hCNetSDK.NET_DVR_GetLastError());
                result.setCode(500);
                result.setMsg("添加人脸失败");
            } else {
                try {
                    BYTE_ARRAY ptrByteArray = new BYTE_ARRAY(1024);    //数组

                    NET_DVR_JSON_DATA_CFG struAddFaceDataCfg = new NET_DVR_JSON_DATA_CFG();
                    struAddFaceDataCfg.read();

                    JSONObject jsonObject = new JSONObject();
                    jsonObject.set("faceLibType", "blackFD");
                    jsonObject.set("FDID", "1");
                    jsonObject.set("FPID", String.valueOf(faceParam.getUserId()));//人脸下发关联的工号

                    String strJsonData = jsonObject.toString();
                    System.arraycopy(strJsonData.getBytes(), 0, ptrByteArray.byValue, 0, strJsonData.length());//字符串拷贝到数组中
                    ptrByteArray.write();

                    struAddFaceDataCfg.dwSize = struAddFaceDataCfg.size();
                    struAddFaceDataCfg.lpJsonData = ptrByteArray.getPointer();
                    struAddFaceDataCfg.dwJsonDataSize = strJsonData.length();

                    /*****************************************
                     * 从本地文件里面读取JPEG图片二进制数据
                     *****************************************/
                    //将base64 转为二进制
                    String fileName = IdWorker.getId() + ".jpg";
                    String downloadImgPath = downloadImg(faceParam.getFaceImage(), fileName);
                    if (StrUtil.isEmpty(downloadImgPath)) {
                        log.warn("图片解析失败");
                        result.setCode(500);
                        result.setMsg("添加人脸失败");
                        continue;
                    }
                    int picdataLength = 0;
                    picfile = new FileInputStream(new File(downloadImgPath));
                    picdataLength = picfile.available();
                    if (picdataLength < 0) {
                        log.warn("input file dataSize < 0");
                    }
                    BYTE_ARRAY ptrpicByte = new BYTE_ARRAY(picdataLength);
                    picfile.read(ptrpicByte.byValue);
                    ptrpicByte.write();
                    struAddFaceDataCfg.dwPicDataSize = picdataLength;
                    struAddFaceDataCfg.lpPicData = ptrpicByte.getPointer();
                    struAddFaceDataCfg.write();

                    BYTE_ARRAY ptrOutuff = new BYTE_ARRAY(1024);

                    IntByReference pInt = new IntByReference(0);

                    int dwState = hCNetSDK.NET_DVR_SendWithRecvRemoteConfig(startFaceRemoteConfig, struAddFaceDataCfg.getPointer(), struAddFaceDataCfg.dwSize, ptrOutuff.getPointer(), 1024, pInt);

                    if (dwState == -1) {
                        log.warn("NET_DVR_SendWithRecvRemoteConfig接口调用失败,错误码:{}", hCNetSDK.NET_DVR_GetLastError());
                        result.setCode(500);
                        continue;
                    }
                    //读取返回的json并解析
                    ptrOutuff.read();
                    String strResult = new String(ptrOutuff.byValue).trim();
                    log.info("addUserFace  dwState: {} ,strResult: {}", dwState, strResult);
                    if (StrUtil.isNotEmpty(strResult) && JSONUtil.isJson(strResult)) {
                        JSONObject jsonResult = JSONUtil.parseObj(strResult);
                        int statusCode = jsonResult.getInt("statusCode");
                        String statusString = jsonResult.getStr("statusString");
                        responStatusMsg(dwState, faceParam.getUserId(), statusCode, strResult);
                        if (dwState == IotHikNetConstant.NET_SDK_CONFIG_STATUS_SUCCESS) {//返回NET_SDK_CONFIG_STATUS_SUCCESS代表流程走通了,但并不代表下发成功,比如有些设备可能因为人员已存在等原因下发失败,所以需要解析Json报文
                            if (statusCode != 1) {
                                result.setCode(500);
                                result.setMsg("添加人脸失败");
                            } else {
                                result.setCode(200);
                                result.setMsg("添加用户成功");
                            }
                        } else {
                            result.setCode(500);
                            result.setMsg("添加人脸失败");
                        }
                    } else {
                        result.setCode(500);
                        result.setMsg("添加人脸失败");
                    }

                } catch (Exception e) {
                    log.error("下发人脸异常:", e);
                    result.setCode(500);
                }
            }

            resultList.add(result);
        }

        //关闭长连接,释放资源
        if (!hCNetSDK.NET_DVR_StopRemoteConfig(startFaceRemoteConfig)) {
            log.warn("NET_DVR_StopRemoteConfig接口调用失败,错误码:{}", hCNetSDK.NET_DVR_GetLastError());
        } else {
            log.info("NET_DVR_StopRemoteConfig接口成功");
        }

        if (picfile != null) {
            try {
                picfile.close();
            } catch (IOException ioException) {
                log.info("FileInputStream 关闭异常");
            }
        }

        return resultList;
    }
相关推荐
努力的布布17 分钟前
Spring源码-从源码层面讲解声明式事务的运行流程
java·spring
程序员大金23 分钟前
基于SpringBoot的旅游管理系统
java·vue.js·spring boot·后端·mysql·spring·旅游
小丁爱养花25 分钟前
记忆化搜索专题——算法简介&力扣实战应用
java·开发语言·算法·leetcode·深度优先
大汉堡~31 分钟前
代理模式-动态代理
java·代理模式
爱上语文36 分钟前
Springboot三层架构
java·开发语言·spring boot·spring·架构
loveLifeLoveCoding1 小时前
Java List sort() 排序
java·开发语言
草履虫·1 小时前
【Java集合】LinkedList
java
AngeliaXue1 小时前
Java集合(List篇)
java·开发语言·list·集合
世俗ˊ1 小时前
Java中ArrayList和LinkedList的比较
java·开发语言
zhouyiddd1 小时前
Maven Helper 插件
java·maven·intellij idea