whycxzp
2025-03-29 51d25be2fac930b44a13784c311e7603009d7f6d
更新hik温度读取
4个文件已修改
3个文件已添加
747 ■■■■ 已修改文件
src/main/java/com/whyc/dto/IpInfo.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/listener/ApplicationListener.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/pojo/db_power_rt/BattStationTemp.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/schedule/BattStationTempScheduleService.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/schedule/VideoScheduleService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/BattStationTempService.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/util/HikTempUtil.java 489 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/dto/IpInfo.java
New file
@@ -0,0 +1,18 @@
package com.whyc.dto;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class IpInfo {
    private String ip;
    private String cameraId;
    public IpInfo(String ip, String cameraId) {
        this.ip = ip;
        this.cameraId = cameraId;
    }
}
src/main/java/com/whyc/listener/ApplicationListener.java
@@ -1,67 +1,46 @@
//package com.whyc.listener;
//
//import com.whyc.constant.YamlProperties;
//import com.whyc.dto.Response;
//import com.whyc.service.VideoService;
//import org.springframework.beans.factory.annotation.Autowired;
//
//import javax.servlet.ServletContext;
//import javax.servlet.ServletContextEvent;
//import javax.servlet.ServletContextListener;
//import javax.servlet.annotation.WebListener;
//import java.util.List;
//
//import static java.lang.Thread.sleep;
//
///**
// * 应用启动时初始化
// * 应用关闭时销毁
// */
//@WebListener
//public class ApplicationListener implements ServletContextListener {
//
//    @Autowired
//    private VideoService videoService;
//
//    /**
//     * 1.初始化,开启视频流并启动录像存储
//     * @param servletContextEvent
//     */
//    @Override
//    public void contextInitialized(ServletContextEvent servletContextEvent) {
//        ServletContext application = servletContextEvent.getServletContext();
//        //考虑意外情况:突然程序死机或者电脑断电重启,需要延时启动录像,因为视频推流服务还未完成.
//        try {
//            //延时20s
//            sleep(20000);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
//
//
//        //1.录像存储
//        //获取所有的流id
//        List<String> videoStreamIds = YamlProperties.videoStreamIds;
//        //开启录像存储
//        videoStreamIds.forEach(streamId -> {
//            //添加流
//            Response<String> response = videoService.addStreamProxy(streamId);
//
//            //判断是否在录像,不在的话,开启录像
//
//            Response response2 = videoService.startRecord(streamId);
//            if(!(response2.getCode() ==1 && ((boolean) response2.getData()))){
//                System.out.println("流id为:"+streamId+"的信息:"+response2.getMsg());
//            }else{
//                System.out.println("流id为:"+streamId+"的信息:"+response2.getData());
//            }
//        });
//
//    }
//
//    @Override
//    public void contextDestroyed(ServletContextEvent servletContextEvent) {
//        //关闭所有流
//        //videoService.closeStreams();
//    }
//}
package com.whyc.listener;
import com.whyc.constant.YamlProperties;
import com.whyc.dto.IpInfo;
import com.whyc.dto.Response;
import com.whyc.service.VideoService;
import com.whyc.util.HikTempUtil;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.util.LinkedList;
import java.util.List;
import static java.lang.Thread.sleep;
/**
 * 应用启动时初始化
 * 应用关闭时销毁
 */
@WebListener
public class ApplicationListener implements ServletContextListener {
    @Autowired
    private VideoService videoService;
    /**
     * 1.初始化,开启视频流并启动录像存储
     * @param servletContextEvent
     */
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        ServletContext application = servletContextEvent.getServletContext();
        //初始化hik sdk
        HikTempUtil.init();
    }
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        //关闭hik sdk
        HikTempUtil.logoutAndCleanup(HikTempUtil.lUserIDs);
    }
}
src/main/java/com/whyc/pojo/db_power_rt/BattStationTemp.java
@@ -37,13 +37,13 @@
    private Date recordTime;
    /**最高温度点跟磁条轨道的最短距离的点 x*y */
    private String mtCrossMstPoint;
    //private String mtCrossMstPoint;
    /**最高温度跟磁条的最短距离,垂直距离*/
    private String mtCrossMstDistance;
    //private String mtCrossMstDistance;
    /**最高温度在磁条的左边/右边,值为false或者right*/
    private String mtpMstDirection;
    //private String mtpMstDirection;
    @TableField(exist = false)
    private List<Point> minTempPointList;
src/main/java/com/whyc/schedule/BattStationTempScheduleService.java
New file
@@ -0,0 +1,84 @@
package com.whyc.schedule;
import com.whyc.constant.YamlProperties;
import com.whyc.dto.*;
import com.whyc.factory.ThreadPoolExecutorFactory;
import com.whyc.pojo.db_power_rt.BattStationTemp;
import com.whyc.service.BattStationTempService;
import com.whyc.service.VideoService;
import com.whyc.util.DateUtil;
import com.whyc.util.FileUtil;
import com.whyc.util.HikTempUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
@EnableScheduling
@Component
@Slf4j
public class BattStationTempScheduleService {
    @Autowired
    private BattStationTempService service;
    /**
     * 温度实时
     * */
    @Scheduled(fixedRate = 4000,initialDelay = 2000)
    public void startRecordAndCheck(){
        List<IpInfo> ipInfoList = HikTempUtil.ipInfoList;
        for (int i = 0; i < ipInfoList.size(); i++) {
            IpInfo ipInfo = ipInfoList.get(i);
            ThreadPoolExecutorFactory.getPoolExecutor().execute(()-> {
                String ip = ipInfo.getIp();
                String cameraId = ipInfo.getCameraId();
                Response response = HikTempUtil.getTempPoint(ip);
                if ((Boolean) response.getData()){
                    Map<String, Object> tempMap = (Map<String, Object>) response.getData2();
                    int pixelX = (int) tempMap.get("pixelX");
                    int pixelY = (int) tempMap.get("pixelY");
                    TempPoint minTempPoint = (TempPoint) tempMap.get("minTempPoint");
                    TempPoint maxTempPoint = (TempPoint) tempMap.get("maxTempPoint");
                    BattStationTemp battStationTemp = new BattStationTemp();
                    battStationTemp.setPixelX(pixelX);
                    battStationTemp.setPixelY(pixelY);
                    //最大温度点位
                    battStationTemp.setMaxTemp(maxTempPoint.getTemp());
                    List<Point> maxTempPoints = maxTempPoint.getPoints();
                    //对points,里面的x,y进行x*y的字符串转换,并将所有元素用逗号隔开
                    List<String> maxPointsStr = maxTempPoints.stream().map(item -> item.getX() + "*" + item.getY()).collect(Collectors.toList());
                    String maxPoints = String.join(",", maxPointsStr);
                    battStationTemp.setMaxTempPoint(maxPoints);
                    //最小温度点位
                    battStationTemp.setMinTemp(minTempPoint.getTemp());
                    List<Point> minTempPoints = minTempPoint.getPoints();
                    //对points,里面的x,y进行x*y的字符串转换,并将所有元素用逗号隔开
                    List<String> minPointsStr = minTempPoints.stream().map(item -> item.getX() + "*" + item.getY()).collect(Collectors.toList());
                    String minPoints = String.join(",", minPointsStr);
                    battStationTemp.setMinTempPoint(minPoints);
                    battStationTemp.setCameraId(cameraId);
                    Date date = new Date();
                    battStationTemp.setRecordTime(date);
                    service.addOrUpdate(battStationTemp);
                }else{
                    String msg = response.getMsg();
                    // TODO 报错日志记录
                }
            });
        }
    }
}
src/main/java/com/whyc/schedule/VideoScheduleService.java
@@ -72,9 +72,9 @@
    }
    /**
     * 录像保持2天
     * 录像保持7天
     */
    @Scheduled(cron= "0 0 2 * * ?")
    @Scheduled(cron= "0 0 7 * * ?")
    public void recordRecycle(){
        log.info("-----------执行录像循环----------:"+ DateUtil.YYYY_MM_DD_HH_MM_SS.format(new Date()));
        //文件夹路径 /battery_system/video_system/Debug/www/record/rtp/{streamId}/{day}}
@@ -87,7 +87,7 @@
            List<String> dirList2 = Arrays.asList(dirList);
            for (int i = 0; i < dirList2.size()-3; i++) {
                //按顺序删除,保留最后3个day的视频录像文件夹
                //按顺序删除,保留最后7个day的视频录像文件夹
                String dirPath2Remove = dirPath + File.separator + dirList2.get(i);
                File dir2Remove = new File(dirPath2Remove);
                FileUtil.deleteFile(dir2Remove);
src/main/java/com/whyc/service/BattStationTempService.java
@@ -1,14 +1,19 @@
package com.whyc.service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.whyc.dto.Point;
import com.whyc.dto.Response;
import com.whyc.mapper.BattStationTempMapper;
import com.whyc.pojo.db_power_rt.BattStationTemp;
import com.whyc.util.ActionUtil;
import com.whyc.util.PointUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
@Service
@@ -18,15 +23,23 @@
    private BattStationTempMapper mapper;
    public Response<List<BattStationTemp>> getList() {
        List<BattStationTemp> list = mapper.selectList((Wrapper<BattStationTemp>) ActionUtil.objeNull);
        QueryWrapper<BattStationTemp> query = Wrappers.query();
        query.orderByAsc("camera_id");
        List<BattStationTemp> list = mapper.selectList(query);
        //对温度坐标进行解析,minTempPoint格式为"1*2,2*3",把里面所有的x*y点 拆解到Point(x,y)列表中
        list.stream().forEach(battStationTemp -> {
            String minTempPointStr = battStationTemp.getMinTempPoint();
            List<Point> minTempPointList = battStationTemp.getMinTempPointList();
            minTempPointList = new LinkedList<>();
            List<Point> maxTempPointList = battStationTemp.getMaxTempPointList();
            maxTempPointList =new LinkedList<>();
            if(minTempPointStr!=null&&!minTempPointStr.equals("")){
                String[] split = minTempPointStr.split(",");
                for (String s : split) {
                    String[] split1 = s.split("\\*");
                    battStationTemp.getMinTempPointList().add(new Point(Integer.parseInt(split1[0]),Integer.parseInt(split1[1])));
                    minTempPointList.add(new Point(Integer.parseInt(split1[0]),Integer.parseInt(split1[1])));
                }
            }
            String maxTempPointStr = battStationTemp.getMaxTempPoint();
@@ -38,11 +51,23 @@
                    //对于最高温度点 p(a,b)
                    //TODO 已知坐标点两点为p1(a1,b1)和p2(a2,b2), 求 maxTempPoint点与p1p2组成的线垂直相交的点p3的坐标计算方式
                    battStationTemp.getMaxTempPointList().add(p);
                    maxTempPointList.add(p);
                }
            }
        });
        return new Response<List<BattStationTemp>>().set(1,list);
    }
    public void addOrUpdate(BattStationTemp battStationTemp) {
        QueryWrapper<BattStationTemp> query = Wrappers.query();
        query.eq("camera_id",battStationTemp.getCameraId());
        BattStationTemp tempInDB = mapper.selectOne(query);
        if (tempInDB ==null) {
            mapper.insert(battStationTemp);
        }else{
            battStationTemp.setId(tempInDB.getId());
            mapper.updateById(battStationTemp);
        }
    }
}
src/main/java/com/whyc/util/HikTempUtil.java
New file
@@ -0,0 +1,489 @@
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; // 返回登录结果
    }
}