海康威视道闸系统ISAPI 改写代码 - Controller层

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

公司要求对接海康威视的道闸系统进行数据展示,但是官方sdk中的演示java文件是有交互界面的,不符合controller层代码逻辑,因此需要改写。


一、ISAPI是什么?

ISAPI全称为Intelligent Security API(智能安全API),是基于HTTP(Hypertext Transfer Protocol)的应用层协议,并采用REST架构(Representational State Transfer, 表述性状态转移),实现安防设备(如摄像机、数字录像机、网络录像机等)与平台或客户端软件之间的通信。

二、修改步骤

1.改写的controller代码

代码如下(示例):

package com.jsdhqy.science.controller;

import com.alibaba.nacos.common.http.param.MediaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jsdhqy.science.HCNetSDK;
import com.jsdhqy.science.osSelect;
import com.sun.jna.Native;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.HttpHeaders;

import javax.swing.*;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;

/**
 * 海康威视ISAPI
 *
 * @author ftao
 * @since 2023-08-01
 */

@RestController
@AllArgsConstructor
@RequestMapping("hikvision")
public class HikvisionController {
    static HCNetSDK hCNetSDK = null;
    public static final int ISAPI_DATA_LEN = 1024*1024;
    public static final int ISAPI_STATUS_LEN = 4*4096;
    public static final int BYTE_ARRAY_LEN = 1024;

    /**
     * 加载库,SDK初始化
     */
    public void HikvisionInit() {

        if (hCNetSDK == null) {
            if (!createSDKInstance()) {
                System.out.println("Load SDK fail");
                return;
            }
        }

        // 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/";
            //System.out.println("lib所在目录在: " + 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());
        }

        boolean initSuc = hCNetSDK.NET_DVR_Init();
        if (!initSuc) {
            System.out.println("初始化失败");
        }

        // 加载日志
        boolean setLogSuc = hCNetSDK.NET_DVR_SetLogToFile(3, "./sdklog", false);
        if (!setLogSuc) {
            System.out.println("加载日志失败");
        }
    }

    /**
     * 初始化SDK实例
     *
     * @return 初始化是否成功
     */
    public boolean createSDKInstance() {
        if (hCNetSDK == null) {
            synchronized (HCNetSDK.class) {
                String strDllPath = "";
                try {
                    if (osSelect.isWindows()) {
                        // Win系统加载SDK库路径
                        strDllPath = System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll";
                        System.out.println("SDK所在目录: "+System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll");
                    } else if (osSelect.isLinux()) {
                        // Linux系统加载SDK库路径
                        strDllPath = System.getProperty("user.dir") + "/lib/libhcnetsdk.so";
                    }
                    hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
                } catch (Exception ex) {
                    System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 注册登录用户
     * @return
     */
    @GetMapping("/ISAPI/login")
    public String login() {
        int lUserID = -1; // 用户句柄,将lUserID声明为实例变量并初始化为-1
        //注册之前先注销已注册的用户,预览情况下不可注销
        try {
            hCNetSDK.NET_DVR_Logout(lUserID);
        }
        catch (Exception e){
            System.out.println("未注册");
        }

        HikvisionInit();

        //注册
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
        String sDeviceIP = "10.0.11.100";//登录设备IP地址
        String sUsername = "admin";//设备用户名
        String sPassword = "hik12345+";//设备密码
        int portNumber = 8000;

        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, sDeviceIP.length());

        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, sUsername.length());

        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, sPassword.length());

        m_strLoginInfo.wPort = (short) portNumber;

        m_strLoginInfo.byLoginMode = 0;
        m_strLoginInfo.byHttps = 0;
        m_strLoginInfo.bUseAsynLogin = false;

        m_strLoginInfo.write();
        try {
            lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
            System.out.println(lUserID);
            if(lUserID <= -1){
                System.out.println("注册失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
            }
            else {
                System.out.println("注册成功");
            }
        }
        catch(Exception e){
            System.out.println("lUserID: " + lUserID);
            //System.out.println("注册失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
            return "注册出错";
        }
        //return "";

        //原方法
        if (lUserID == -1)
        {
            return "请先注册";
        }
        HCNetSDK.NET_DVR_XML_CONFIG_INPUT struXMLInput = new HCNetSDK.NET_DVR_XML_CONFIG_INPUT();
        struXMLInput.read();
        struXMLInput.dwSize = struXMLInput.size();
        String strURL = "POST /ISAPI/Parking/server/passVehicleInfo/recordSearch";
        int iURLlen = strURL.length();
        HCNetSDK.BYTE_ARRAY ptrUrl = new HCNetSDK.BYTE_ARRAY(iURLlen+1);
        System.arraycopy(strURL.getBytes(), 0, ptrUrl.byValue, 0, strURL.length());
        ptrUrl.write();
        struXMLInput.lpRequestUrl = ptrUrl.getPointer();
        struXMLInput.dwRequestUrlLen = iURLlen;
        String strInbuffer = "";

        //拉取所有数据保存到数据库中,从6月1到今天,后续查询使用distinct筛除重复
        LocalDate startDate = LocalDate.of(java.time.LocalDate.now().getYear(), 6, 1);
        LocalDate endDate = java.time.LocalDate.now();
        long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
        //查询最大间隔为7天
        for (int j = 0; j <= daysBetween; j += 6) {
            LocalDate currentStartDate = startDate.plusDays(j);
            LocalDateTime currentEndDate = currentStartDate.plusDays(5).atTime(23, 59, 59);
            //每页最大数量为100,平均每天数量为2000+,设置最大为3000
            for (int i = 0; i <= 3000; i += 100) {
                String searchResultPosition = Integer.toString(i);
                String jsonString = "{\"PassVehicleInfoSearchDescription\":{\"searchID\":\"\",\"searchResultPosition\":" + searchResultPosition + ",\"maxResults\":100,\"parkingID\":\"all\",\"gateID\":\"all\",\"laneID\":\"all\",\"licensePlate\":\"\",\"cardNo\":\"\",\"direction\":\"all\",\"operationType\":\"all\",\"parkingType\":\"all\",\"executeControlVehicle\":{\"enabled\":2},\"orderType\":\"DESC\",\"remoteHost\":3,\"sendFlag\":\"all\",\"startTime\":\"" + currentStartDate + "\",\"endTime\":\"" + currentEndDate + "\"}}";
                strInbuffer = jsonString;
                System.out.println(strInbuffer);

                //String strInbuffer = "{\"PassVehicleInfoSearchDescription\":{\"searchID\":\"\",\"searchResultPosition\":0,\"maxResults\":100,\"parkingID\":\"all\",\"gateID\":\"all\",\"laneID\":\"all\",\"licensePlate\":\"\",\"cardNo\":\"\",\"direction\":\"all\",\"operationType\":\"all\",\"parkingType\":\"all\",\"executeControlVehicle\":{\"enabled\":2},\"orderType\":\"DESC\",\"remoteHost\":3,\"sendFlag\":\"all\",\"startTime\":\""+String.format("%d-01-01T00:00:00Z", java.time.LocalDate.now().getYear())+"\",\"endTime\":\""+String.format("%d-12-31T23:59:59Z", java.time.LocalDate.now().getYear())+"\"}}";
                int iInBufLen = strInbuffer.length();
                if (iInBufLen == 0) {
                    struXMLInput.lpInBuffer = null;
                    struXMLInput.dwInBufferSize = 0;
                    struXMLInput.write();
                } else {
                    HCNetSDK.BYTE_ARRAY ptrInBuffer = new HCNetSDK.BYTE_ARRAY(iInBufLen + 1);
                    ptrInBuffer.read();
                    ptrInBuffer.byValue = strInbuffer.getBytes();
                    ptrInBuffer.write();

                    struXMLInput.lpInBuffer = ptrInBuffer.getPointer();
                    struXMLInput.dwInBufferSize = iInBufLen;
                    struXMLInput.write();

                }
                HCNetSDK.BYTE_ARRAY ptrStatusByte = new HCNetSDK.BYTE_ARRAY(ISAPI_STATUS_LEN);
                ptrStatusByte.read();

                HCNetSDK.BYTE_ARRAY ptrOutByte = new HCNetSDK.BYTE_ARRAY(ISAPI_DATA_LEN);
                ptrOutByte.read();

                HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT struXMLOutput = new HCNetSDK.NET_DVR_XML_CONFIG_OUTPUT();
                struXMLOutput.read();
                struXMLOutput.dwSize = struXMLOutput.size();
                struXMLOutput.lpOutBuffer = ptrOutByte.getPointer();
                struXMLOutput.dwOutBufferSize = ptrOutByte.size();
                struXMLOutput.lpStatusBuffer = ptrStatusByte.getPointer();
                struXMLOutput.dwStatusSize = ptrStatusByte.size();
                struXMLOutput.write();

                if (!hCNetSDK.NET_DVR_STDXMLConfig(lUserID, struXMLInput, struXMLOutput)) {
                    int iErr = hCNetSDK.NET_DVR_GetLastError();
                    return "NET_DVR_STDXMLConfig失败,错误号:" + iErr;

                } else {
                    struXMLOutput.read();
                    ptrOutByte.read();
                    ptrStatusByte.read();
                    String strOutXML = new String(ptrOutByte.byValue).trim();
                    //System.out.println(strOutXML);

                    //报错到数据库
                    // 解析JSON
                    ObjectMapper objectMapper = new ObjectMapper();
                    try {
                        JsonNode jsonNode = objectMapper.readTree(strOutXML);
                        JsonNode matchList = jsonNode.get("MatchList");
                        if (matchList.isArray()) {
                            for (JsonNode match : matchList) {
                                // 从JSON中提取字段值
                                String gate_name = match.get("gateName").asText();
                                //System.out.println(gate_name);
                                String lane_name = match.get("laneName").asText();
                                //System.out.println(lane_name);
                                String operation_type = match.get("operationType").asText();
                                String license_plate = match.get("licensePlate").asText();
                                System.out.println(license_plate);
                                String pass_time = match.get("passTime").asText();
                                System.out.println(pass_time);
                                String direction = match.get("direction").asText();
                                String release_reason = match.get("releaseReason").asText();
                                // 这里进行其他的操作
                              
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //System.out.println("strOutXML " + strOutXML);


                    //String strStatus = new String(ptrStatusByte.byValue).trim();
                    //System.out.println("strStatus " + strStatus);
                }
            }
        }


        //退出程序时调用,每一台设备分别注销
        if (hCNetSDK.NET_DVR_Logout(lUserID)) {
            System.out.println("注销成功");
        }

        //SDK反初始化,释放资源,只需要退出时调用一次
        hCNetSDK.NET_DVR_Cleanup();
        return "请求结束";
    }
    
    /**
     * 注销登录用户
     * @return
     */
    @GetMapping("/ISAPI/logout")
    public String loginout() {
        HikvisionInit();
        //录设备的用户数达到最大时,手动清理的方法
        int lUserID;
        for (lUserID=125;lUserID>=1;lUserID--) {
            //退出程序时调用,每一台设备分别注销
            if (hCNetSDK.NET_DVR_Logout(lUserID)) {
                System.out.println("注销成功" + lUserID);
            }

            //SDK反初始化,释放资源,只需要退出时调用一次
            hCNetSDK.NET_DVR_Cleanup();
            System.out.println("清理结束");
        }
        return "定时任务结束";
        }

}

2.HCNetSDK.java

在改动controller层后,HCNetSDK的参数数据上也要改写,不过很简单,在涉及的方法中添加getFieldOrder返回方法即可,可以参考他已经写的getFieldOrder来改写。

3.osSelect.java

原封不动复制过来即可。

最后将Controller文件、HCNetSDK、osSelect放在controller文件夹中即可

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 作为一家领先的智能交通解决方案提供商,海康威视一直致力于为用户提供优质的服务。其PMS系统软件是一款高效的停车管理系统,可以帮助物业公司、停车场等单位实现对停车场的全面管理。如需下载该软件,用户可通过以下步骤进行: 1.访问海康威视官方网站,在“产品与解决方案”栏目中找到“PMS系统”; 2.进入该页面后,可以了解该系统的产品特点和应用场景,同时也可以在页面的下方找到“软件下载”按钮; 3.点击下载按钮后,用户需要填写相应的资料,如公司名称、联系人姓名、联系方式等,同时也可以选择下载该软件的版本和平台; 4.完成表单提交后,用户将会收到海康威视官方推送的下载链接,按照链接所示的步骤进行下载和安装即可。 需要注意的是,用户在使用该软件时需遵循相关的使用规定和操作流程,同时也需要时刻关注系统的安全性和稳定性,保障软件的正常运行和维护。 ### 回答2: 首先,海康威视是一家专注于智能安防领域的企业,其PMS系统软件是用于路交通管理、车辆进出管理的智能系统。下载该软件需要进入海康威视的官网,并找到相关下载页面。下载前需要先注册登录。在该页面可以找到适用于不同系统及版本的软件下载链接,选择相应的版本并进行下载。在下载前一定要确认自己的电脑是否符合该软件的最低硬件及软件要求,并确保下载的软件来自正规渠。一旦下载完成,还需要进行安装及配置,才能正常使用该软件进行车辆进出管理、路交通管理等工作。同时,在使用过程中应该遵守相关规定和标准,确保路交通管理工作的安全、高效和顺畅。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值