New file |
| | |
| | | package com.whyc.util; |
| | | |
| | | import com.sun.jna.Native; |
| | | import com.sun.jna.Pointer; |
| | | import com.whyc.dto.IpInfo; |
| | | import com.whyc.dto.Point; |
| | | import com.whyc.dto.Response; |
| | | import com.whyc.dto.TempPoint; |
| | | import com.whyc.hik.Commom.osSelect; |
| | | import com.whyc.hik.NetSDKDemo.HCNetSDK; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.RandomAccessFile; |
| | | import java.math.BigDecimal; |
| | | import java.nio.ByteBuffer; |
| | | import java.nio.ByteOrder; |
| | | import java.util.*; |
| | | |
| | | @Service |
| | | public class HikTempUtil { |
| | | |
| | | |
| | | |
| | | static HCNetSDK hCNetSDK = null; |
| | | //static int lUserID = -1; //用户句柄 |
| | | public static List<Integer> lUserIDs = new LinkedList<>(); |
| | | public static Map<String,Integer> ipLUserIdMap = new HashMap<>(); |
| | | public static FExceptionCallBack_Imp fExceptionCallBack; |
| | | public static List<IpInfo> ipInfoList = new LinkedList<>(); |
| | | static { |
| | | //TODO 暂时定义,后续要改成对应的 |
| | | ipInfoList.add(new IpInfo("192.168.10.11","1")); |
| | | ipInfoList.add(new IpInfo("192.168.10.12","2")); |
| | | ipInfoList.add(new IpInfo("192.168.10.13","3")); |
| | | ipInfoList.add(new IpInfo("192.168.10.14","4")); |
| | | ipInfoList.add(new IpInfo("192.168.10.15","5")); |
| | | ipInfoList.add(new IpInfo("192.168.10.16","6")); |
| | | ipInfoList.add(new IpInfo("192.168.10.17","7")); |
| | | ipInfoList.add(new IpInfo("192.168.10.18","8")); |
| | | } |
| | | |
| | | |
| | | public static Response getTempPoint(String ip){ |
| | | Integer lUserID = ipLUserIdMap.get(ip); |
| | | //hCNetSDK.NET_DVR_STDXMLConfig(lUserID, "<?xml version=\"1.0\" encoding=\"GB2312\"?><GetDeviceInfo><dwSize>0</dwSize></GetDeviceInfo>", "GetDeviceInfo", 1000); |
| | | |
| | | /*========== 红外 抓图测温 Start==========*/ |
| | | //抓热图 |
| | | HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA m_strJpegWithAppendData = new HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA(); |
| | | m_strJpegWithAppendData.dwSize = m_strJpegWithAppendData.size(); |
| | | HCNetSDK.BYTE_ARRAY ptrJpegByte = new HCNetSDK.BYTE_ARRAY(2*1024*1024); |
| | | HCNetSDK.BYTE_ARRAY ptrP2PDataByte = new HCNetSDK.BYTE_ARRAY(2*1024*1024); |
| | | m_strJpegWithAppendData.pJpegPicBuff = ptrJpegByte.getPointer(); |
| | | m_strJpegWithAppendData.pP2PDataBuff = ptrP2PDataByte.getPointer(); |
| | | m_strJpegWithAppendData.dwJpegPicLen = 2*1024*1024; |
| | | m_strJpegWithAppendData.dwP2PDataLen = 2*1024*1024; |
| | | m_strJpegWithAppendData.write(); |
| | | Map<String, Object> tempPointMap; |
| | | boolean resBoolean = hCNetSDK.NET_DVR_CaptureJPEGPicture_WithAppendData(lUserID, 2, m_strJpegWithAppendData); |
| | | if (resBoolean) { |
| | | System.out.println("抓图成功"); |
| | | //m_strJpegWithAppendData.read(); |
| | | // 定义文件名 |
| | | String cFilename = "Jpegwithappend_"+ip+".data"; |
| | | String cFilename2 = "Jpegwithappend_"+ip+".csv"; |
| | | |
| | | // 创建文件输出流 |
| | | try { |
| | | FileOutputStream fos = new FileOutputStream(cFilename); |
| | | // 将数据写入文件 |
| | | //fos.write(m_strJpegWithAppendData.pP2PDataBuff, 0, m_strJpegWithAppendData.dwP2PDataLen); |
| | | Pointer pP2PDataBuff = m_strJpegWithAppendData.pP2PDataBuff; |
| | | fos.write(pP2PDataBuff.getByteArray(0, m_strJpegWithAppendData.dwP2PDataLen), 0, m_strJpegWithAppendData.dwP2PDataLen); |
| | | |
| | | //获取红外结果并解析 |
| | | tempPointMap = analyzeData(m_strJpegWithAppendData, cFilename, cFilename2); |
| | | }catch (Exception e){ |
| | | return new Response().set(1,false,e.toString()); |
| | | } |
| | | }else { |
| | | System.out.printf("抓热图失败:%s",hCNetSDK.NET_DVR_GetLastError()); |
| | | return new Response().set(1,false,String.format("抓热图失败:%s",hCNetSDK.NET_DVR_GetLastError())); |
| | | } |
| | | /*========== 红外 抓图测温 End==========*/ |
| | | /*for (boolean exit = false; !exit; ) { |
| | | System.out.println("请输入您想要执行的demo实例! (退出请输入yes)"); |
| | | Scanner input = new Scanner(System.in); |
| | | String str = input.next(); |
| | | // 转换为标准输入 |
| | | str = str.toLowerCase(); |
| | | if (str.equals("yes")) { |
| | | // 退出程序 |
| | | exit = true; |
| | | break; |
| | | } |
| | | switch (str) { |
| | | case "1": |
| | | { |
| | | System.out.println("\n[Module]手动获取设备在线状态"); |
| | | DevManager.getDeviceStatus(lUserID); |
| | | break; |
| | | } |
| | | case "2": |
| | | { |
| | | System.out.println("\n[Module]获取设备工作状态代码"); |
| | | DevManager.getWorkS(lUserID); |
| | | break; |
| | | } |
| | | case "3": |
| | | { |
| | | System.out.println("\n[Module]获取设备基本信息"); |
| | | DevManager.getDeviceInfo(lUserID); |
| | | break; |
| | | } |
| | | |
| | | case "4": |
| | | { |
| | | |
| | | System.out.println("\n[Module]设备抓图代码"); |
| | | ChannelParamCfg.CaptureJPEGPicture(lUserID); |
| | | break; |
| | | } |
| | | case "5": |
| | | { |
| | | //适用NVR等硬盘录像机设备 |
| | | System.out.println("\n[Module]查询设备通道状态代码"); |
| | | ChannelParamCfg.GetIPChannelInfo(lUserID); |
| | | break; |
| | | } |
| | | case "6": |
| | | { |
| | | //获取和设置前端扩展参数 |
| | | System.out.println("\n[Module]获取和设置前端扩展参数"); |
| | | ChannelParamCfg.GetCameraPara(lUserID); |
| | | break; |
| | | } |
| | | case "7": |
| | | { |
| | | //获取和设置网络参数 |
| | | System.out.println("\n[Module]获取和设置网络参数"); |
| | | ChannelParamCfg.GetNetCfg(lUserID); |
| | | break; |
| | | } |
| | | case "8": |
| | | { |
| | | //获取和设置录像参数 |
| | | System.out.println("\n[Module]获取和设置录像参数"); |
| | | ChannelParamCfg.GetRecordCfg(lUserID); |
| | | break; |
| | | } |
| | | case "9": |
| | | { |
| | | //获取和设置图像参数 |
| | | System.out.println("\n[Module]获取和设置图像参数"); |
| | | ChannelParamCfg.GetandSetPicCfg(lUserID); |
| | | break; |
| | | } |
| | | case "10": |
| | | { |
| | | //获取和设置时间参数 |
| | | System.out.println("\n[Module]获取和设置时间参数"); |
| | | SdkSysCfg.GetandSetDevTime(lUserID); |
| | | break; |
| | | } |
| | | case "11": |
| | | { |
| | | //获取设备软硬件能力信息 |
| | | System.out.println("\n[Module]获取设备软硬件能力"); |
| | | DevManager.GetSofthardware_Ability(lUserID); |
| | | break; |
| | | } |
| | | case "12": |
| | | { |
| | | //获取设备JPEG抓图能力 |
| | | System.out.println("\n[Module]获取设备JPEG抓图能力"); |
| | | DevManager.GetJPEG_Cap_Ability(lUserID); |
| | | break; |
| | | } |
| | | case "13": |
| | | { |
| | | //日志查找 |
| | | System.out.println("\n[Module]日志查找"); |
| | | DevManager.FindLog(lUserID); |
| | | break; |
| | | } |
| | | default: |
| | | { |
| | | System.out.println("\n未知的指令操作!请重新输入!\n"); |
| | | } |
| | | } |
| | | }*/ |
| | | |
| | | //logoutAndCleanup(lUserIDs); |
| | | return new Response().setII(1,true,tempPointMap,null); |
| | | } |
| | | |
| | | public static void init(){ |
| | | if (hCNetSDK == null) { |
| | | if (!createSDKInstance()) { |
| | | System.out.println("Load SDK fail"); |
| | | //return new Response().set(1,false,"Load SDK fail"); |
| | | } |
| | | } |
| | | //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(HCNetSDK.NET_SDK_INIT_CFG_LIBEAY_PATH, ptrByteArray1.getPointer()); |
| | | System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length()); |
| | | ptrByteArray2.write(); |
| | | hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SSLEAY_PATH, 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(HCNetSDK.NET_SDK_INIT_CFG_SDK_PATH, struComPath.getPointer()); |
| | | } |
| | | //SDK初始化,一个程序进程只需要调用一次 |
| | | hCNetSDK.NET_DVR_Init(); |
| | | |
| | | if (fExceptionCallBack == null) { |
| | | fExceptionCallBack = new FExceptionCallBack_Imp(); |
| | | } |
| | | Pointer pUser = null; |
| | | if (!hCNetSDK.NET_DVR_SetExceptionCallBack_V30(0, 0, fExceptionCallBack, pUser)) { |
| | | //return new Response().set(1,false,"设置异常消息回调失败"); |
| | | System.out.println("设置异常消息回调失败"); |
| | | } |
| | | System.out.println("设置异常消息回调成功"); |
| | | |
| | | //启用SDK写日志 |
| | | hCNetSDK.NET_DVR_SetLogToFile(3, "./sdkLog", false); |
| | | //登录设备,每一台设备只需要登录一次 |
| | | //lUserID = TestDemo.loginDevice("10.9.137.21", (short) 8000, "admin", "Cpfwb518+"); |
| | | //int lUserID = HikTempUtil.loginDevice("192.168.10.16", (short) 8000, "admin", "fg001@hdw"); |
| | | for (int i = 0; i < ipInfoList.size(); i++) { |
| | | String ip = ipInfoList.get(i).getIp(); |
| | | int lUserID = HikTempUtil.loginDevice(ip, (short) 8000, "admin", "fg001@hdw"); |
| | | lUserIDs.add(lUserID); |
| | | ipLUserIdMap.put(ip,lUserID); |
| | | } |
| | | |
| | | } |
| | | |
| | | public static void logoutAndCleanup(List<Integer> lUserIDs) { |
| | | for (int i = 0; i < lUserIDs.size(); i++) { |
| | | int lUserID = lUserIDs.get(i); |
| | | //程序退出的时候调用注销登录接口,每一台设备分别调用一次 |
| | | if (hCNetSDK.NET_DVR_Logout(lUserID)) { |
| | | System.out.println("注销成功"); |
| | | } |
| | | } |
| | | |
| | | //释放SDK资源,程序退出时调用,只需要调用一次 |
| | | hCNetSDK.NET_DVR_Cleanup(); |
| | | } |
| | | |
| | | static class FExceptionCallBack_Imp implements HCNetSDK.FExceptionCallBack { |
| | | public void invoke(int dwType, int lUserID, int lHandle, Pointer pUser) { |
| | | System.out.println("异常事件类型:" + dwType); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 动态库加载 |
| | | * |
| | | * @return |
| | | */ |
| | | private static boolean createSDKInstance() { |
| | | if (hCNetSDK == null) { |
| | | synchronized (HCNetSDK.class) { |
| | | String strDllPath = ""; |
| | | try { |
| | | if (osSelect.isWindows()) { |
| | | //win系统加载SDK库路径 |
| | | strDllPath = System.getProperty("user.dir") + "\\src\\main\\resources\\lib\\Hik\\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; |
| | | } |
| | | |
| | | public static Map<String,Object> analyzeData(HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA m_strJpegWithAppendData, String cFilename, String cFilename2) throws IOException { |
| | | Map<String,Object> tempMap = new LinkedHashMap<>(); |
| | | // 打开本地保存的文件 |
| | | String inputFilename = cFilename; |
| | | String outputFilename = cFilename2; |
| | | |
| | | //int m_AnalysisHotPic_W = 384; // 根据抓热图接口返回的图像宽dwJpegPicWidth进行赋值 |
| | | //int m_AnalysisHotPic_H = 288; // 根据抓热图接口返回的图像高dwJpegPicHeight进行赋值 |
| | | int m_AnalysisHotPic_W = m_strJpegWithAppendData.dwJpegPicWidth; // 根据抓热图接口返回的图像宽dwJpegPicWidth进行赋值 |
| | | int m_AnalysisHotPic_H = m_strJpegWithAppendData.dwJpegPicHeight; // 根据抓热图接口返回的图像高dwJpegPicHeight进行赋值 |
| | | int bufSize = m_AnalysisHotPic_H * m_AnalysisHotPic_W * 4; |
| | | |
| | | try (RandomAccessFile datafilefp = new RandomAccessFile(inputFilename, "r"); |
| | | FileOutputStream fp = new FileOutputStream(outputFilename)) { |
| | | |
| | | // 读取文件里面所有数据 |
| | | byte[] pDataBuf = new byte[bufSize]; |
| | | int bytesRead = datafilefp.read(pDataBuf); |
| | | if (bytesRead != bufSize) { |
| | | System.out.println("Failed to read the entire file"); |
| | | return tempMap; |
| | | } |
| | | |
| | | float minTemp = 10000.0f; |
| | | float maxTemp = -10000.0f; |
| | | //存储极值温度的坐标,如果是相同的极值温度,就也同步添加坐标点 |
| | | TempPoint minTempPoint = new TempPoint(); |
| | | TempPoint maxTempPoint = new TempPoint(); |
| | | |
| | | ByteBuffer buffer = ByteBuffer.wrap(pDataBuf); |
| | | buffer.order(ByteOrder.LITTLE_ENDIAN); // 根据实际情况调整字节序 |
| | | |
| | | for (int iWriteHeight = 0; iWriteHeight < m_AnalysisHotPic_H; ++iWriteHeight) { |
| | | for (int iWriteWidth = 0; iWriteWidth < m_AnalysisHotPic_W; ++iWriteWidth) { |
| | | float fTemp = buffer.getFloat(); |
| | | // 判断fTemp是否是一个正常值,不是则赋值最大或最小,防止设备崩溃 |
| | | fTemp = (9999 < fTemp) ? 9999 : ((-9999 > fTemp) ? -9999 : fTemp); |
| | | //只保留以为小数 |
| | | fTemp = BigDecimal.valueOf(fTemp).setScale(1, BigDecimal.ROUND_HALF_UP).floatValue(); |
| | | |
| | | //minTemp = (minTemp > fTemp) ? fTemp : minTemp; |
| | | if(minTemp >= fTemp){ |
| | | minTemp = fTemp; |
| | | //查看存的最低温度是不是当前温度,不是的话,要清空最低温度map, |
| | | //同时把最新的最低温度和坐标保存 |
| | | Float minTempOld = minTempPoint.getTemp(); |
| | | if(minTempOld == null || minTempOld!=minTemp){ //首次赋值 或者 需要重置最低温度 |
| | | minTempPoint.setTemp(minTemp); |
| | | List<Point> points = new ArrayList<>(); |
| | | Point point = new Point(iWriteWidth,iWriteHeight); |
| | | points.add(point); |
| | | minTempPoint.setPoints(points); |
| | | }else { //存在最低温度相同的另外一个点,保存下来进入最低温度列表 |
| | | List<Point> points = minTempPoint.getPoints(); |
| | | points.add(new Point(iWriteWidth,iWriteHeight)); |
| | | } |
| | | } |
| | | //maxTemp = (maxTemp < fTemp) ? fTemp : maxTemp; |
| | | if(maxTemp <= fTemp){ |
| | | maxTemp = fTemp; |
| | | //查看存的最高温度是不是当前温度,不是的话,要清空最高温度map, |
| | | //同时把最新的最高温度和坐标保存 |
| | | Float maxTempOld = maxTempPoint.getTemp(); |
| | | if(maxTempOld == null || maxTempOld!=maxTemp){ //首次赋值 或者 需要重置最高温度 |
| | | maxTempPoint.setTemp(maxTemp); |
| | | List<Point> points = new ArrayList<>(); |
| | | Point point = new Point(iWriteWidth,iWriteHeight); |
| | | points.add(point); |
| | | maxTempPoint.setPoints(points); |
| | | }else { //存在最高温度相同的另外一个点,保存下来进入最高温度列表 |
| | | List<Point> points = maxTempPoint.getPoints(); |
| | | points.add(new Point(iWriteWidth,iWriteHeight)); |
| | | } |
| | | } |
| | | |
| | | String temp = String.format("%.2f,", fTemp); |
| | | |
| | | fp.write(temp.getBytes()); |
| | | } |
| | | |
| | | fp.write("\n".getBytes()); |
| | | } |
| | | |
| | | System.out.println("Min Temperature: " + minTempPoint); |
| | | System.out.println("Max Temperature: " + maxTempPoint); |
| | | tempMap.put("pixelX",m_strJpegWithAppendData.dwJpegPicWidth); |
| | | tempMap.put("pixelY",m_strJpegWithAppendData.dwJpegPicHeight); |
| | | tempMap.put("minTempPoint",minTempPoint); |
| | | tempMap.put("maxTempPoint",maxTempPoint); |
| | | } |
| | | |
| | | return tempMap; |
| | | } |
| | | |
| | | /** |
| | | * 设备登录V30 |
| | | * |
| | | * @param ip 设备IP |
| | | * @param port SDK端口,默认设备的8000端口 |
| | | * @param user 设备用户名 |
| | | * @param psw 设备密码 |
| | | */ |
| | | /*public static int login_V30(String ip, short port, String user, String psw) { |
| | | HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30(); |
| | | int iUserID = hCNetSDK.NET_DVR_Login_V30(ip, port, user, psw, m_strDeviceInfo); |
| | | System.out.println("UserID:" + lUserID); |
| | | if ((iUserID == -1) || (iUserID == 0xFFFFFFFF)) { |
| | | System.out.println("登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError()); |
| | | return iUserID; |
| | | } else { |
| | | System.out.println(ip + ":设备登录成功!"); |
| | | return iUserID; |
| | | } |
| | | }*/ |
| | | |
| | | /** |
| | | * 登录设备,支持 V40 和 V30 版本,功能一致。 |
| | | * |
| | | * @param ip 设备IP地址 |
| | | * @param port SDK端口,默认为设备的8000端口 |
| | | * @param user 设备用户名 |
| | | * @param psw 设备密码 |
| | | * @return 登录成功返回用户ID,失败返回-1 |
| | | */ |
| | | public static int loginDevice(String ip, short port, String user, String psw) { |
| | | // 创建设备登录信息和设备信息对象 |
| | | HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO(); |
| | | HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40(); |
| | | |
| | | // 设置设备IP地址 |
| | | byte[] deviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN]; |
| | | byte[] ipBytes = ip.getBytes(); |
| | | System.arraycopy(ipBytes, 0, deviceAddress, 0, Math.min(ipBytes.length, deviceAddress.length)); |
| | | loginInfo.sDeviceAddress = deviceAddress; |
| | | |
| | | // 设置用户名和密码 |
| | | byte[] userName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN]; |
| | | byte[] password = psw.getBytes(); |
| | | System.arraycopy(user.getBytes(), 0, userName, 0, Math.min(user.length(), userName.length)); |
| | | System.arraycopy(password, 0, loginInfo.sPassword, 0, Math.min(password.length, loginInfo.sPassword.length)); |
| | | loginInfo.sUserName = userName; |
| | | |
| | | // 设置端口和登录模式 |
| | | loginInfo.wPort = port; |
| | | loginInfo.bUseAsynLogin = false; // 同步登录 |
| | | loginInfo.byLoginMode = 0; // 使用SDK私有协议 |
| | | |
| | | // 执行登录操作 |
| | | int userID = hCNetSDK.NET_DVR_Login_V40(loginInfo, deviceInfo); |
| | | if (userID == -1) { |
| | | System.err.println("登录失败,错误码为: " + hCNetSDK.NET_DVR_GetLastError()); |
| | | } else { |
| | | System.out.println(ip + " 设备登录成功!"); |
| | | // 处理通道号逻辑 |
| | | int startDChan = deviceInfo.struDeviceV30.byStartDChan; |
| | | System.out.println("预览起始通道号: " + startDChan); |
| | | } |
| | | return userID; // 返回登录结果 |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | |