‘liusuyi’
2023-11-29 2574db703fa175765394dba9d4e0d623a1bcd16a
修复bug
已添加2个文件
已修改7个文件
已删除1个文件
694 ■■■■■ 文件已修改
Dockerfile 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/external/service/IArdEquipExternalService.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/external/service/impl/ArdEquipExternalServiceImpl.java 143 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/radar/domain/RadarAlarmData.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/hiksdk/domain/FaceMatchEventInfo.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/hiksdk/domain/FaceSnapEventInfo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/hiksdk/service/impl/FMSGCallBack.java 366 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/hiksdk/service/impl/HikClientUtil.java 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/tcp/ClientHandler.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Dockerfile
ÎļþÒÑɾ³ý
pom.xml
@@ -139,17 +139,6 @@
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <repository>${docker.image.prefix}/${project.artifactId}</repository>
                    <buildArgs>
                        <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.4.1</version>
src/main/java/com/ard/alarm/external/service/IArdEquipExternalService.java
@@ -12,13 +12,7 @@
 * @date 2023-03-13
 */
public interface IArdEquipExternalService {
    /**
     * æŸ¥è¯¢external
     *
     * @param id external主键
     * @return external
     */
    public ArdEquipExternal selectArdEquipExternalById(String id);
    /**
     * æŸ¥è¯¢external
@@ -29,11 +23,11 @@
    public ArdEquipExternal selectArdEquipExternal(ArdEquipExternal ardEquipExternal);
    /**
     * æŸ¥è¯¢external列表
     * æŸ¥è¯¢external列表按类型列表
     *
     * @param ardEquipExternal external
     * @param types ç±»åž‹åˆ—表
     * @return external集合
     */
    public List<ArdEquipExternal> selectArdEquipExternalList(ArdEquipExternal ardEquipExternal);
    public List<ArdEquipExternal> selectArdEquipExternalListByTypes(List<String> types);
}
src/main/java/com/ard/alarm/external/service/impl/ArdEquipExternalServiceImpl.java
@@ -35,35 +35,17 @@
    private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    public static List<ArdEquipExternal> ardAlarmHostList = new ArrayList<>();
    public static List<ArdEquipExternal> ardAccessHostList = new ArrayList<>();
    public static List<ArdEquipExternal> ardSuperBrainHostList = new ArrayList<>();
    public static List<ArdEquipExternal> ardEquipExternalList = new ArrayList<>();
    @Resource
    private ArdEquipExternalMapper ardEquipExternalMapper;
    @Override
    public void run(ApplicationArguments args) {
        //获取全部海康报警主机尝试登录
        ArdEquipExternal alarmHost = new ArdEquipExternal();
        alarmHost.setFactory("1");
        alarmHost.setType("1");
        ardAlarmHostList = selectArdEquipExternalList(alarmHost);
        HikClientUtil.loginAllAlarmHost(ardAlarmHostList);
        log.debug("报警主机尝试登录");
        //获取全部门禁主机尝试登录
        ArdEquipExternal accessControlHost = new ArdEquipExternal();
        accessControlHost.setFactory("1");
        accessControlHost.setType("6");
        ardAccessHostList = selectArdEquipExternalList(accessControlHost);
        HikClientUtil.loginAllAccessControlHost(ardAccessHostList);
        log.debug("门禁主机尝试登录");
        //获取全部超脑尝试登录
        ArdEquipExternal superBrainHost = new ArdEquipExternal();
        superBrainHost.setFactory("1");
        superBrainHost.setType("5");
        ardSuperBrainHostList = selectArdEquipExternalList(superBrainHost);
        HikClientUtil.loginAllSuperBrainHost(ardSuperBrainHostList);
        log.debug("超脑尝试登录");
        List<String> targetTypes = Arrays.asList("1", "5", "6");
        List<ArdEquipExternal> ardEquipExternals = selectArdEquipExternalListByTypes(targetTypes);
        HikClientUtil.loginAllArdEquipExternals(ardEquipExternals);
        ardEquipExternalList.addAll(ardEquipExternals);
        log.debug("外联设备尝试登录");
        //同步任务
        syncTask();
    }
@@ -76,94 +58,31 @@
    private void syncTask() {
        scheduler.scheduleAtFixedRate(() -> {
            try {
                //region å®šæ—¶åŒæ­¥æŠ¥è­¦ä¸»æœº
                ArdEquipExternal alarmHost = new ArdEquipExternal();
                alarmHost.setFactory("1");
                alarmHost.setType("1");
                List<ArdEquipExternal> newAlarmHostList = selectArdEquipExternalList(alarmHost);
                //region å®šæ—¶åŒæ­¥å¤–联设备
                List<String> targetTypes = Arrays.asList("1", "5", "6");
                List<ArdEquipExternal> ardEquipExternalsNew = selectArdEquipExternalListByTypes(targetTypes);
                //需要更新的数据
                List<ArdEquipExternal> updateList = sameListWithDifferent(ardAlarmHostList, newAlarmHostList);
                List<ArdEquipExternal> updateList = sameListWithDifferent(ardEquipExternalList, ardEquipExternalsNew);
                if (updateList.size() > 0) {
                    HikClientUtil.logoutAllAlarmHost(updateList);
                    HikClientUtil.loginAllAlarmHost(updateList);
                    ardAlarmHostList.clear();
                    ardAlarmHostList.addAll(newAlarmHostList);
                    HikClientUtil.logoutAllArdEquipExternals(updateList);
                    HikClientUtil.loginAllArdEquipExternals(updateList);
                    ardEquipExternalList.clear();
                    ardEquipExternalList.addAll(ardEquipExternalsNew);
                }
                //需要删除的数据
                List<ArdEquipExternal> delList = diffList(ardAlarmHostList, newAlarmHostList);
                List<ArdEquipExternal> delList = diffList(ardEquipExternalList, ardEquipExternalsNew);
                if (delList.size() > 0) {
                    HikClientUtil.logoutAllAlarmHost(delList);
                    HikClientUtil.logoutAllArdEquipExternals(delList);
                    for (ArdEquipExternal ardEquipExternal : delList) {
                        ardAlarmHostList.remove(ardEquipExternal);
                        ardEquipExternalList.remove(ardEquipExternal);
                    }
                }
                //需要新增的数据
                List<ArdEquipExternal> inserList = diffList(newAlarmHostList, ardAlarmHostList);
                List<ArdEquipExternal> inserList = diffList(ardEquipExternalsNew, ardEquipExternalList);
                if (inserList.size() > 0) {
                    HikClientUtil.loginAllAlarmHost(inserList);
                    HikClientUtil.loginAllArdEquipExternals(inserList);
                    for (ArdEquipExternal ardEquipExternal : inserList) {
                        ardAlarmHostList.add(ardEquipExternal);
                    }
                }
                //endregion
                //region å®šæ—¶åŒæ­¥é—¨ç¦ä¸»æœº
                ArdEquipExternal accessHost = new ArdEquipExternal();
                accessHost.setFactory("1");
                accessHost.setType("6");
                List<ArdEquipExternal> newAccessHostList = selectArdEquipExternalList(accessHost);
                //需要更新的数据
                updateList = sameListWithDifferent(ardAccessHostList, newAccessHostList);
                if (updateList.size() > 0) {
                    HikClientUtil.logoutAllAlarmHost(updateList);
                    HikClientUtil.loginAllAlarmHost(updateList);
                    ardAccessHostList.clear();
                    ardAccessHostList.addAll(newAccessHostList);
                }
                //需要删除的数据
                delList = diffList(ardAccessHostList, newAccessHostList);
                if (delList.size() > 0) {
                    HikClientUtil.logoutAllAccessControlHost(delList);
                    for (ArdEquipExternal ardEquipExternal : delList) {
                        ardAccessHostList.remove(ardEquipExternal);
                    }
                }
                //需要新增的数据
                inserList = diffList(newAccessHostList, ardAccessHostList);
                if (inserList.size() > 0) {
                    HikClientUtil.loginAllAccessControlHost(inserList);
                    for (ArdEquipExternal ardEquipExternal : inserList) {
                        ardAccessHostList.add(ardEquipExternal);
                    }
                }
                //endregion
                //region å®šæ—¶åŒæ­¥è¶…è„‘
                ArdEquipExternal superBrainHost = new ArdEquipExternal();
                superBrainHost.setFactory("1");
                superBrainHost.setType("5");
                List<ArdEquipExternal> newSuperBrainList = selectArdEquipExternalList(superBrainHost);
                //需要更新的数据
                updateList = sameListWithDifferent(ardSuperBrainHostList, newSuperBrainList);
                if (updateList.size() > 0) {
                    HikClientUtil.logoutAllSuperBrainHost(updateList);
                    HikClientUtil.loginAllSuperBrainHost(updateList);
                    ardSuperBrainHostList.clear();
                    ardSuperBrainHostList.addAll(newSuperBrainList);
                }
                //需要删除的数据
                delList = diffList(ardSuperBrainHostList, newSuperBrainList);
                if (delList.size() > 0) {
                    HikClientUtil.logoutAllSuperBrainHost(delList);
                    for (ArdEquipExternal ardEquipExternal : delList) {
                        ardSuperBrainHostList.remove(ardEquipExternal);
                    }
                }
                //需要新增的数据
                inserList = diffList(newSuperBrainList, ardSuperBrainHostList);
                if (inserList.size() > 0) {
                    HikClientUtil.loginAllSuperBrainHost(inserList);
                    for (ArdEquipExternal ardEquipExternal : inserList) {
                        ardSuperBrainHostList.add(ardEquipExternal);
                        ardEquipExternalList.add(ardEquipExternal);
                    }
                }
                //endregion
@@ -173,18 +92,12 @@
        }, 10, 10, TimeUnit.SECONDS);
    }
    /**
     * æŸ¥è¯¢external
     *
     * @param id external主键
     * @return external
     * @param ardEquipExternal external
     * @return external集合
     */
    @Override
    public ArdEquipExternal selectArdEquipExternalById(String id) {
        return ardEquipExternalMapper.selectById(id);
    }
    @Override
    public ArdEquipExternal selectArdEquipExternal(ArdEquipExternal ardEquipExternal) {
        QueryWrapper<ArdEquipExternal> queryWrapper = new QueryWrapper<>(ardEquipExternal);
@@ -192,17 +105,17 @@
    }
    /**
     * æŸ¥è¯¢external列表
     * æŒ‰ç±»åž‹åˆ—表查询external列表
     *
     * @param ardEquipExternal external
     * @param types ç±»åž‹åˆ—表
     * @return external
     */
    @Override
    public List<ArdEquipExternal> selectArdEquipExternalList(ArdEquipExternal ardEquipExternal) {
        QueryWrapper<ArdEquipExternal> queryWrapper = new QueryWrapper<>(ardEquipExternal);
    public List<ArdEquipExternal> selectArdEquipExternalListByTypes(List<String> types) {
        QueryWrapper<ArdEquipExternal> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("type", types);
        return ardEquipExternalMapper.selectList(queryWrapper);
    }
    //求两个对象List的交集字段不同Id相同
    private List<ArdEquipExternal> sameListWithDifferent(List<ArdEquipExternal> oldList, List<ArdEquipExternal> newList) {
@@ -224,8 +137,6 @@
        return differentFieldsList;
    }
    //  æ±‚两个对象List的差集
    private List<ArdEquipExternal> diffList(List<ArdEquipExternal> oldArrayList, List<ArdEquipExternal> newArrayList) {
        List<ArdEquipExternal> resultList = oldArrayList.stream()
src/main/java/com/ard/alarm/radar/domain/RadarAlarmData.java
@@ -17,4 +17,5 @@
    String radarName;
    String alarmTime;
    List<ArdAlarmRadar> ardAlarmRadars;
    List<ArdAlarmRadar> ardFollowRadars;
}
src/main/java/com/ard/utils/hiksdk/domain/FaceMatchEventInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.ard.utils.hiksdk.domain;
import lombok.Data;
/**
 * @Description: äººè„¸æ¯”对事件信息
 * @Version: 1.0
 * @ClassName: FaceSnapEventInfo
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´11月10日13:03:22
 **/
@Data
public class FaceMatchEventInfo {
    private String alarmType;
    private String status;
    private String alarmTime;
    private String picUrl;
}
src/main/java/com/ard/utils/hiksdk/domain/FaceSnapEventInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ard.utils.hiksdk.domain;
import lombok.Data;
/**
 * @Description:
 * @ClassName: FaceSnapEventInfo
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´11月10日13:03:22
 **/
@Data
public class FaceSnapEventInfo {
    private String eventId;
    private String alarmTime;
    private String picUrl;
}
src/main/java/com/ard/utils/hiksdk/service/impl/FMSGCallBack.java
@@ -3,19 +3,16 @@
import com.alibaba.fastjson2.JSON;
import com.ard.alarm.camera.domain.ArdCameras;
import com.ard.alarm.camera.domain.CameraCmd;
import com.ard.alarm.camera.service.IArdCamerasService;
import com.ard.alarm.camera.service.impl.ArdCamerasServiceImpl;
import com.ard.alarm.external.domain.ArdEquipExternal;
import com.ard.alarm.external.service.IArdEquipExternalService;
import com.ard.alarm.external.service.impl.ArdEquipExternalServiceImpl;
import com.ard.utils.hiksdk.domain.*;
import com.ard.utils.minio.MinioUtil;
import com.ard.utils.other.ByteUtils;
import com.ard.utils.hiksdk.common.GlobalVariable;
import com.ard.utils.hiksdk.domain.AccessControlHostEventInfo;
import com.ard.utils.hiksdk.domain.CameraEventInfo;
import com.ard.utils.hiksdk.domain.ExternalAlarmEventInfo;
import com.ard.utils.hiksdk.util.hikSdkUtil.HCNetSDK;
import com.ard.utils.other.DateUtils;
import com.ard.utils.mqtt.MqttProducer;
import com.ard.utils.spring.SpringUtils;
import com.ard.utils.uuid.IdUtils;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
@@ -24,7 +21,9 @@
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import static com.ard.utils.hiksdk.util.hikSdkUtil.HCNetSDK.*;
/**
 * @ClassName: FMSGCallBack
@@ -50,27 +49,41 @@
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sDeviceIP = ByteUtils.bytesToStringZh(pAlarmer.sDeviceIP).trim();//设备IP地址
        Integer wLinkPort = Integer.valueOf(pAlarmer.wLinkPort);//设备通讯端口
        //通过ip和端口查询设备
        Optional<ArdCameras> foundCamera = findArdCameraByIpAndPort(sDeviceIP, wLinkPort);
        Optional<ArdEquipExternal> foundExternal = findArdEquipExternalByIpAndPort(sDeviceIP, wLinkPort);
        ArdCameras camera = null;
        ArdEquipExternal ardEquipExternal = null;
        if (foundCamera.isPresent()) {
            camera = foundCamera.get();
        } else {
            if (foundExternal.isPresent()) {
                ardEquipExternal = foundExternal.get();
            }
        }
        //如果没有找到设备,直接返回
        if (camera == null && ardEquipExternal == null) {
            return false;
        }
        CameraEventInfo info;
        String sTime;//事件时间
        String url = "";//事件图片
        String alarmTime;//事件时间
        String alarmType = "";//报警类型
        String picUrl = "";//事件图片
        String facePicUrl = "";//人脸图片
        //lCommand是传的报警类型
        log.debug("报警事件类型:lCommand:" + Integer.toHexString(lCommand));
        ArdCameras ardCameras = new ArdCameras();
        ardCameras.setIp(sDeviceIP);
        ardCameras.setPort(wLinkPort);
        IArdCamerasService ardCamerasService = SpringUtils.getBean(IArdCamerasService.class);
        List<ArdCameras> ardCamerasList = ardCamerasService.selectArdCamerasList(ardCameras);
        log.debug("【" + sDeviceIP + ":" + wLinkPort + "】报警事件类型:lCommand:" + Integer.toHexString(lCommand));
        switch (lCommand) {
            //region ç§»åŠ¨ä¾¦æµ‹ã€è§†é¢‘ä¸¢å¤±ã€é®æŒ¡ã€IO信号量等报警信息(V3.0以上版本支持的设备)
            case HCNetSDK.COMM_ALARM_V30:
            case COMM_ALARM_V30:
                log.debug("移动侦测报警信息上报");
                if (camera == null) {
                    return false;
                }
                //region ç§»åŠ¨ä¾¦æµ‹ã€è§†é¢‘ä¸¢å¤±ã€é®æŒ¡ã€IO信号量等报警信息(V3.0以上版本支持的设备)
                HCNetSDK.NET_DVR_ALARMINFO_V30 netDvrAlarminfoV30 = new HCNetSDK.NET_DVR_ALARMINFO_V30();
                netDvrAlarminfoV30.write();
                Pointer pNDAInfo = netDvrAlarminfoV30.getPointer();
                pNDAInfo.write(0, pAlarmInfo.getByteArray(0, netDvrAlarminfoV30.size()), 0, netDvrAlarminfoV30.size());
                netDvrAlarminfoV30.read();
                if (ardCamerasList.size() > 0) {
                    ArdCameras camera = ardCamerasService.selectArdCamerasList(ardCameras).get(0);
                    switch (netDvrAlarminfoV30.dwAlarmType) {
                        case 3:
                            info = new CameraEventInfo();
@@ -86,16 +99,15 @@
                            info.setLatitude(camera.getLatitude());
                            info.setAlarmType("移动侦测");
                            //图片存入minio
                            url = savePicture(info);
                            info.setPicUrl(url);
                            publishMqtt(info);
                        picUrl = snapPicture(info);
                        info.setPicUrl(picUrl);
                        publishMqtt(info, "camera");
                            break;
                    }
                }
                //endregion
                break;
            case HCNetSDK.COMM_ALARM_RULE:
                //log.debug("行为分析信息报警信息上报");
            case COMM_ALARM_RULE:
                log.debug("异常行为识别信息报警信息上报");
                //region å¼‚常行为识别信息
                HCNetSDK.NET_VCA_RULE_ALARM strVcaAlarm = new HCNetSDK.NET_VCA_RULE_ALARM();
                strVcaAlarm.write();
@@ -103,14 +115,11 @@
                pVCAInfo.write(0, pAlarmInfo.getByteArray(0, strVcaAlarm.size()), 0, strVcaAlarm.size());
                strVcaAlarm.read();
                Integer ruleID = Integer.valueOf(strVcaAlarm.struRuleInfo.byRuleID);
                sTime = DateUtils.parseTime(strVcaAlarm.dwAbsTime);//事件时间
                String ipaddr = new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4).trim();//设备ip
                alarmTime = DateUtils.parseTime(strVcaAlarm.dwAbsTime);//事件时间
                Integer channel = Integer.valueOf(strVcaAlarm.struDevInfo.byChannel);//通道
                info = new CameraEventInfo();
                info.setAlarmName("人员行为分析");
                info.setAlarmTime(sTime);
                if (ardCamerasList.size() > 0) {
                    ArdCameras camera = ardCamerasService.selectArdCamerasList(ardCameras).get(0);
                info.setAlarmTime(alarmTime);
                    info.setCameraName(camera.getName());
                    info.setCameraId(camera.getId());
                    info.setCameraIp(camera.getIp());
@@ -125,9 +134,9 @@
                            info.setAlarmType("越界侦测报警");
                            strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_TRAVERSE_PLANE.class);
                            //图片存入minio
                            url = savePicture(info);
                            info.setPicUrl(url);
                            publishMqtt(info);
                        picUrl = snapPicture(info);
                        info.setPicUrl(picUrl);
                        publishMqtt(info, "camera");
                            //endregion
                            break;
//                    case 2: //region ç›®æ ‡è¿›å…¥åŒºåŸŸ
@@ -144,9 +153,9 @@
                            info.setAlarmType("周界入侵报警");
                            strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_INTRUSION.class);
                            //图片存入minio
                            url = savePicture(info);
                            info.setPicUrl(url);
                            publishMqtt(info);
                        picUrl = snapPicture(info);
                        info.setPicUrl(picUrl);
                        publishMqtt(info, "camera");
                            //endregion
                            break;
//                    case 5: //region å¾˜å¾Š
@@ -174,27 +183,211 @@
//                        //endregion
//                        break;
                        default:
                            // log.debug("未知行为事件类型:" + strVcaAlarm.struRuleInfo.wEventTypeEx);
                        log.debug("未知异常行为事件类型:" + strVcaAlarm.struRuleInfo.wEventTypeEx);
                            break;
                    }
                }
                //endregion
                break;
            case HCNetSDK.COMM_UPLOAD_FACESNAP_RESULT:
                //log.debug("人脸检测事件上报(暂不解析)");
            case COMM_UPLOAD_FACESNAP_RESULT:
                log.debug("人脸抓拍报警信息(暂不解析)");
                //region äººè„¸æŠ“拍报警信息
                HCNetSDK.NET_VCA_FACESNAP_RESULT struFaceSnap = new HCNetSDK.NET_VCA_FACESNAP_RESULT();
                struFaceSnap.write();
                Pointer vcaInfo = struFaceSnap.getPointer();
                vcaInfo.write(0, pAlarmInfo.getByteArray(0, struFaceSnap.size()), 0, struFaceSnap.size());
                struFaceSnap.read();
                alarmTime = DateUtils.parseTime(struFaceSnap.dwAbsTime);
                String facePicTyp;
                switch (struFaceSnap.byUploadEventDataType) {
                    case 0:
                        facePicTyp = "二进制数据";
                break;
            case HCNetSDK.COMM_GISINFO_UPLOAD:
                //log.debug("GPS报警信息上报(暂不解析)");
                    case 1:
                        facePicTyp = "URL";
                break;
            case HCNetSDK.COMM_ALARMHOST_CID_ALARM:
                    default:
                        facePicTyp = "";
                        break;
                }
                if (struFaceSnap.dwFacePicLen > 0 && struFaceSnap.pBuffer1 != null) {
                    //将字节写入文件
                    long offset = 0;
                    ByteBuffer buffers = struFaceSnap.pBuffer1.getByteBuffer(offset, struFaceSnap.dwBackgroundPicLen);
                    byte[] bytes = new byte[struFaceSnap.dwBackgroundPicLen];
                    buffers.rewind();
                    buffers.get(bytes);
                    InputStream input = new ByteArrayInputStream(bytes);
                    try {
                        String bucketName = "pic";
                        String objectName = "alarm/" + IdUtils.simpleUUID() + ".jpeg";
                        boolean uploadObject = MinioUtil.uploadObject(bucketName, objectName, input, input.available(), "image/JPEG");
                        if (uploadObject) {
                            facePicUrl = MinioUtil.getBucketObjectUrl(bucketName, objectName);
                            //log.debug("上传文件成功!" + url);
                        }
                    } catch (Exception e) {
                        log.error("人脸抓拍报警信息图片保存失败" + e.getMessage());
                    }
                }
                if (struFaceSnap.dwBackgroundPicLen > 0 && struFaceSnap.pBuffer2 != null) {
                    //将字节写入文件
                    long offset = 0;
                    ByteBuffer buffers = struFaceSnap.pBuffer2.getByteBuffer(offset, struFaceSnap.dwBackgroundPicLen);
                    byte[] bytes = new byte[struFaceSnap.dwBackgroundPicLen];
                    buffers.rewind();
                    buffers.get(bytes);
                    InputStream input = new ByteArrayInputStream(bytes);
                    try {
                        String bucketName = "pic";
                        String objectName = "alarm/" + IdUtils.simpleUUID() + ".jpeg";
                        boolean uploadObject = MinioUtil.uploadObject(bucketName, objectName, input, input.available(), "image/JPEG");
                        if (uploadObject) {
                            picUrl = MinioUtil.getBucketObjectUrl(bucketName, objectName);
                            //log.debug("上传文件成功!" + url);
                        }
                    } catch (Exception e) {
                        log.error("人脸抓拍报警信息图片保存失败" + e.getMessage());
                    }
                }
                log.debug("【人脸抓拍报警信息】: alarmTime:" + alarmTime + " picUrl:" + picUrl + " facePicType:" + facePicTyp + " facePicUrl:" + facePicUrl);
                FaceSnapEventInfo faceSnapEventInfo = new FaceSnapEventInfo();
                faceSnapEventInfo.setAlarmTime(alarmTime);
                faceSnapEventInfo.setPicUrl(picUrl);
                publishMqtt(faceSnapEventInfo, "superbrain");
                //endregion
                break;
            case COMM_SNAP_MATCH_ALARM:
                log.debug("人脸比对报警信息");
                //region äººè„¸æ¯”对报警信息
                HCNetSDK.NET_VCA_FACESNAP_MATCH_ALARM struFaceMatchAlarm = new HCNetSDK.NET_VCA_FACESNAP_MATCH_ALARM();
                struFaceMatchAlarm.write();
                Pointer fmaInfo = struFaceMatchAlarm.getPointer();
                fmaInfo.write(0, pAlarmInfo.getByteArray(0, struFaceMatchAlarm.size()), 0, struFaceMatchAlarm.size());
                struFaceMatchAlarm.read();
                alarmTime = DateUtils.parseTime(struFaceMatchAlarm.struSnapInfo.dwAbsTime);//报警时间
                int byMatchPicNum = struFaceMatchAlarm.byMatchPicNum;//匹配图片数量
                String picTransType = "";
                switch (struFaceMatchAlarm.byPicTransType) {
                    case 0:
                        picTransType = "二进制图片";
                        break;
                    case 1:
                        picTransType = "URL路径图片";
                        break;
                }
                String contrastStatus = "";
                switch (struFaceMatchAlarm.byContrastStatus) {
                    case 1:
                        contrastStatus = "比对成功";
                        break;
                    case 2:
                        contrastStatus = "比对失败";
                        break;
                    default:
                        contrastStatus = "未知";
                        break;
                }
                switch (struFaceMatchAlarm.struBlockListInfo.struBlockListInfo.byType) {
                    case 1:
                        alarmType = "陌生人报警";
                        break;
                    case 2:
                        alarmType = "人脸比对报警";
                        break;
                    default:
                        alarmType = "未知";
                        break;
                }
                if (struFaceMatchAlarm.dwSnapPicLen > 0 && struFaceMatchAlarm.pSnapPicBuffer != null && struFaceMatchAlarm.byPicTransType == 0) {
                    //将字节写入文件
                    long offset = 0;
                    ByteBuffer buffers = struFaceMatchAlarm.pSnapPicBuffer.getByteBuffer(offset, struFaceMatchAlarm.dwSnapPicLen);
                    byte[] bytes = new byte[struFaceMatchAlarm.dwSnapPicLen];
                    buffers.rewind();
                    buffers.get(bytes);
                    InputStream input = new ByteArrayInputStream(bytes);
                    try {
                        String bucketName = "pic";
                        String objectName = "alarm/" + IdUtils.simpleUUID() + ".jpeg";
                        boolean uploadObject = MinioUtil.uploadObject(bucketName, objectName, input, input.available(), "image/JPEG");
                        if (uploadObject) {
                            picUrl = MinioUtil.getBucketObjectUrl(bucketName, objectName);
                            //log.debug("上传文件成功!" + url);
                        }
                    } catch (Exception e) {
                        log.error("人脸抓拍报警信息图片保存失败" + e.getMessage());
                    }
                }
                if (struFaceMatchAlarm.struBlockListInfo.dwBlockListPicLen > 0 && struFaceMatchAlarm.struBlockListInfo.pBuffer1 != null) {
                    //将字节写入文件
                    long offset = 0;
                    ByteBuffer buffers = struFaceMatchAlarm.struBlockListInfo.pBuffer1.getByteBuffer(offset, struFaceMatchAlarm.struBlockListInfo.dwBlockListPicLen);
                    byte[] bytes = new byte[struFaceMatchAlarm.struBlockListInfo.dwBlockListPicLen];
                    buffers.rewind();
                    buffers.get(bytes);
                    InputStream input = new ByteArrayInputStream(bytes);
                    try {
                        String bucketName = "pic";
                        String objectName = "alarm/" + IdUtils.simpleUUID() + ".jpeg";
                        boolean uploadObject = MinioUtil.uploadObject(bucketName, objectName, input, input.available(), "image/JPEG");
                        if (uploadObject) {
                            picUrl = MinioUtil.getBucketObjectUrl(bucketName, objectName);
                            //log.debug("上传文件成功!" + url);
                        }
                    } catch (Exception e) {
                        log.error("人脸抓拍报警信息图片保存失败" + e.getMessage());
                    }
                }
                String sAlarmType = "";
                try {
                    sAlarmType = "人脸黑名单比对报警,相识度:" + struFaceMatchAlarm.fSimilarity + ",黑名单姓名:" +
                            new String(struFaceMatchAlarm.struBlockListInfo.struBlockListInfo.struAttribute.byName, "GBK").trim() + ",黑名单证件信息:" +
                            new String(struFaceMatchAlarm.struBlockListInfo.struBlockListInfo.struAttribute.byCertificateNumber).trim();
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                log.debug(sAlarmType);
                log.debug("【人脸比对报警信息】:" + " æ¯”对结果:" + contrastStatus + " æ¯”对类型:" + alarmType + " æŠ¥è­¦æ—¶é—´:" + alarmTime + " åŒ¹é…å›¾ç‰‡æ•°é‡ï¼š" + byMatchPicNum + " å›¾ç‰‡ç±»åž‹ï¼š" + picTransType + " æ¯”对图片:" + picUrl);
                FaceMatchEventInfo faceMatchEventInfo = new FaceMatchEventInfo();
                faceMatchEventInfo.setAlarmTime(alarmTime);
                faceMatchEventInfo.setStatus(contrastStatus);
                faceMatchEventInfo.setAlarmType(alarmType);
                publishMqtt(faceMatchEventInfo, "faceMatch");
                //endregion
                break;
            case COMM_UPLOAD_AIOP_VIDEO:
                log.debug("设备支持AI开放平台接入,上传视频检测数据(暂不解析)");
                break;
            case COMM_ISAPI_ALARM:
                log.debug("安全帽检测报警信息");
                //region å®‰å…¨å¸½æ£€æµ‹æŠ¥è­¦ä¿¡æ¯
                HCNetSDK.NET_DVR_ALARM_ISAPI_INFO struEventISAPI = new HCNetSDK.NET_DVR_ALARM_ISAPI_INFO();
                struEventISAPI.write();
                Pointer pEventISAPI = struEventISAPI.getPointer();
                pEventISAPI.write(0, pAlarmInfo.getByteArray(0, struEventISAPI.size()), 0, struEventISAPI.size());
                struEventISAPI.read();
                int dwAlarmDataLen = struEventISAPI.dwAlarmDataLen;
                int byDataType = struEventISAPI.byDataType;
                int byPicturesNumber = struEventISAPI.byPicturesNumber;
                //处理安全帽检测上传的照片数据
                HCNetSDK.NET_DVR_ALARM_ISAPI_PICDATA struPicData = new HCNetSDK.NET_DVR_ALARM_ISAPI_PICDATA();
                struPicData.write();
                Pointer pPicData = struPicData.getPointer();
                pPicData.write(0, struEventISAPI.pPicPackData.getByteArray(0, struPicData.size()), 0,
                        struPicData.size());
                struPicData.read();
                log.debug("检测到安全帽事件");
                //endregion
                break;
            case COMM_GISINFO_UPLOAD:
                log.debug("GPS报警信息上报(暂不解析)");
                break;
            case COMM_ALARMHOST_CID_ALARM:
                log.debug("报警主机CID报告报警上报");
                //region æŠ¥è­¦ä¸»æœºæŠ¥è­¦å¤„理
                ArdEquipExternal ardEquipExternal = new ArdEquipExternal();
                ardEquipExternal.setIp(sDeviceIP);
                ardEquipExternal.setPort(wLinkPort);
                IArdEquipExternalService ardEquipExternalService = SpringUtils.getBean(IArdEquipExternalService.class);
                ardEquipExternal = ardEquipExternalService.selectArdEquipExternal(ardEquipExternal);
                HCNetSDK.NET_DVR_CID_ALARM netDvrCidAlarm = new HCNetSDK.NET_DVR_CID_ALARM();
                netDvrCidAlarm.write();
                Pointer pCIDInfo = netDvrCidAlarm.getPointer();
@@ -267,36 +460,29 @@
                externalAlarmEventInfo.setAlarmType(byReportType);
                externalAlarmEventInfo.setAlarmTime(struTriggerTime);
                externalAlarmEventInfo.setAlarmHostId(ardEquipExternal.getId());
                publishMqtt(externalAlarmEventInfo);
                publishMqtt(externalAlarmEventInfo, "external");
                //endregion
                break;
            case HCNetSDK.COMM_ALARM_ACS:
                log.debug("门禁主机报警上报");
                //region é—¨ç¦ä¸»æœºæŠ¥è­¦å¤„理
                ArdEquipExternal accessControlHost = new ArdEquipExternal();
                accessControlHost.setIp(sDeviceIP);
                accessControlHost.setPort(wLinkPort);
                ardEquipExternalService = SpringUtils.getBean(IArdEquipExternalService.class);
                accessControlHost = ardEquipExternalService.selectArdEquipExternal(accessControlHost);
                HCNetSDK.NET_DVR_ACS_ALARM_INFO strACSInfo = new HCNetSDK.NET_DVR_ACS_ALARM_INFO();
                strACSInfo.write();
                Pointer acsInfo = strACSInfo.getPointer();
                acsInfo.write(0, pAlarmInfo.getByteArray(0, strACSInfo.size()), 0, strACSInfo.size());
                strACSInfo.read();
                int dwMajor = strACSInfo.dwMajor;
                if (dwMajor != 5) {
                    //只获取事件
                    // log.debug("非事件报警数据上报(暂不解析)");
                    break;
                }
                int dwMinor = strACSInfo.dwMinor;
                if (dwMinor != 80 && dwMinor != 104) {
                    //只解析真人检测失败和人脸抓拍失败的次类型事件
                    break;
                }
                String alarmType = "";
                switch (dwMinor) {
                    case 104:
                        alarmType = "真人检测失败";
@@ -306,7 +492,7 @@
                        break;
                }
                log.debug("门禁主机报警上传:" + alarmType);
                String alarmTime = DateUtils.convertDate(parseAlarmTime(strACSInfo.struTime), "yyyy-M-d H:m:s");
                alarmTime = DateUtils.convertDate(parseAlarmTime(strACSInfo.struTime), "yyyy-M-d H:m:s");
                //事件图片处理
                int dwPicDataLen = strACSInfo.dwPicDataLen;
@@ -323,7 +509,7 @@
                        String objectName = "alarm/" + IdUtils.simpleUUID() + ".jpeg";
                        boolean uploadObject = MinioUtil.uploadObject(bucketName, objectName, input, input.available(), "image/JPEG");
                        if (uploadObject) {
                            url = MinioUtil.getBucketObjectUrl(bucketName, objectName);
                            picUrl = MinioUtil.getBucketObjectUrl(bucketName, objectName);
                            //log.debug("上传文件成功!" + url);
                        }
                    } catch (Exception e) {
@@ -380,9 +566,9 @@
                accessControlHostEventInfo.setDoorNo(struAcsEventInfo.dwDoorNo);
                accessControlHostEventInfo.setDefenseType(defenseType);
                accessControlHostEventInfo.setAlarmTime(alarmTime);
                accessControlHostEventInfo.setPicUrl(url);
                accessControlHostEventInfo.setAcsId(accessControlHost.getId());
                publishMqtt(accessControlHostEventInfo);
                accessControlHostEventInfo.setPicUrl(picUrl);
                accessControlHostEventInfo.setAcsId(ardEquipExternal.getId());
                publishMqtt(accessControlHostEventInfo, "accessControl");
                //endregion
                break;
            default:
@@ -393,11 +579,37 @@
        return true;
    }
    /**
     * æ ¹æ®ç»™å®šçš„IP地址和端口查找ArdEquipExternal对象
     *
     * @param ip   IP地址
     * @param port ç«¯å£
     * @return ArdEquipExternal对象的Optional,如果找到则有值,否则为空
     */
    public static Optional<ArdEquipExternal> findArdEquipExternalByIpAndPort(String ip, int port) {
        return ArdEquipExternalServiceImpl.ardEquipExternalList.stream()
                .filter(equip -> equip.getIp().equals(ip) && equip.getPort() == port)
                .findFirst();
    }
    /**
     * æ ¹æ®IP地址和端口查找ArdCamera对象。
     *
     * @param ip   IP地址
     * @param port ç«¯å£
     * @return ArdCamera对象的Optional,如果找不到则为空
     */
    public static Optional<ArdCameras> findArdCameraByIpAndPort(String ip, int port) {
        return ArdCamerasServiceImpl.ardCameraList.stream()
                .filter(camera -> camera.getIp().equals(ip) && camera.getPort() == port)
                .findFirst();
    }
    /**
     * ç›¸æœºæˆªå›¾
     */
    private String savePicture(CameraEventInfo info) {
    private String snapPicture(CameraEventInfo info) {
        CameraCmd cmd = new CameraCmd();
        String key = info.getCameraIp() + ":" + info.getCameraPort();
        ArdCameras Cameras = GlobalVariable.cameraMap.get(key);
@@ -443,27 +655,13 @@
    }
    /**
     * é€šç”¨å…‰ç”µæŠ¥è­¦æŽ¨é€mqtt
     * å‘布MQTT消息
     *
     * @param info  æ¶ˆæ¯å†…容
     * @param topic ä¸»é¢˜
     */
    private void publishMqtt(CameraEventInfo info) {
        printLog(info);
        MqttProducer.publish(2, false, "camera", JSON.toJSONString(info));
    }
    /**
     * æŠ¥è­¦ä¸»æœºäº‹ä»¶æŽ¨é€mqtt
     */
    private void publishMqtt(ExternalAlarmEventInfo info) {
        printLog(info);
        MqttProducer.publish(2, false, "external", JSON.toJSONString(info));
    }
    /**
     * é—¨ç¦äº‹ä»¶æŽ¨é€mqtt
     */
    private void publishMqtt(AccessControlHostEventInfo info) {
        printLog(info);
        MqttProducer.publish(2, false, "accessControl", JSON.toJSONString(info));
    private <T> void publishMqtt(T info, String topic) {
        MqttProducer.publish(2, false, topic, JSON.toJSONString(info));
    }
    /**
src/main/java/com/ard/utils/hiksdk/service/impl/HikClientUtil.java
@@ -265,9 +265,6 @@
                info.setUsername(accessControlHost.getUsername());
                info.setPassword(accessControlHost.getPassword());
                login(info);
//
//                String key=accessControlHost.getIp()+":"+accessControlHost.getPort();
//                GlobalVariable.accessHostMap.put(key, accessControlHost);
            }
        } catch (Exception ex) {
            log.error("登录所有门禁主机异常:" + ex.getMessage());
@@ -290,13 +287,12 @@
                info.setUsername(accessControlHost.getUsername());
                info.setPassword(accessControlHost.getPassword());
                logout(info);
//                String key=accessControlHost.getIp()+":"+accessControlHost.getPort();
//                GlobalVariable.accessHostMap.remove(key);
            }
        } catch (Exception ex) {
            log.error("登出所有门禁主机异常:" + ex.getMessage());
        }
    }
    /**
     * @描述 ç™»å½•所有超脑
     * @创建人 åˆ˜è‹ä¹‰
@@ -313,9 +309,6 @@
                info.setUsername(superBrainHost.getUsername());
                info.setPassword(superBrainHost.getPassword());
                login(info);
//
//                String key=accessControlHost.getIp()+":"+accessControlHost.getPort();
//                GlobalVariable.accessHostMap.put(key, accessControlHost);
            }
        } catch (Exception ex) {
            log.error("登录所有超脑异常:" + ex.getMessage());
@@ -345,6 +338,50 @@
            log.error("登出所有超脑异常:" + ex.getMessage());
        }
    }
    /**
     * @描述 ç™»å½•所有外联设备
     * @创建人 åˆ˜è‹ä¹‰
     * @创建时间 2023/2/3 10:10
     */
    public static void loginAllArdEquipExternals(List<ArdEquipExternal> ardEquipExternals) {
        try {
            for (ArdEquipExternal ardEquipExternal : ardEquipExternals) {
                Thread.sleep(100);
                DeviceInfo info = new DeviceInfo();
                info.setDeviceId(ardEquipExternal.getId());
                info.setIp(ardEquipExternal.getIp());
                info.setPort(ardEquipExternal.getPort());
                info.setUsername(ardEquipExternal.getUsername());
                info.setPassword(ardEquipExternal.getPassword());
                login(info);
            }
        } catch (Exception ex) {
            log.error("登录所有外联设备异常:" + ex.getMessage());
        }
    }
    /**
     * @描述 ç™»å‡ºæ‰€æœ‰å¤–联设备
     * @创建人 åˆ˜è‹ä¹‰
     * @创建时间 2023/2/3 10:10
     */
    public static void logoutAllArdEquipExternals(List<ArdEquipExternal> ardEquipExternals) {
        try {
            for (ArdEquipExternal ardEquipExternal : ardEquipExternals) {
                Thread.sleep(100);
                DeviceInfo info = new DeviceInfo();
                info.setDeviceId(ardEquipExternal.getId());
                info.setIp(ardEquipExternal.getIp());
                info.setPort(ardEquipExternal.getPort());
                info.setUsername(ardEquipExternal.getUsername());
                info.setPassword(ardEquipExternal.getPassword());
                logout(info);
            }
        } catch (Exception ex) {
            log.error("登出所有超脑异常:" + ex.getMessage());
        }
    }
    /**
     * å»ºç«‹å¸ƒé˜²ä¸Šä¼ é€šé“,用于传输数据
@@ -375,6 +412,8 @@
            m_strAlarmInfo.byAlarmInfoType = 1;
            // å¸ƒé˜²ç±»åž‹(仅针对门禁主机、人证设备):0 - å®¢æˆ·ç«¯å¸ƒé˜²(会断网续传),1 - å®žæ—¶å¸ƒé˜²(只上传实时数据)
            m_strAlarmInfo.byDeployType = 1;
            //人脸报警信息类型:1- äººè„¸ä¾¦æµ‹æŠ¥è­¦ 0- äººè„¸æŠ“拍报警
            m_strAlarmInfo.byFaceAlarmDetection = 0;
            m_strAlarmInfo.write();
            // å¸ƒé˜²æˆåŠŸï¼Œè¿”å›žå¸ƒé˜²æˆåŠŸçš„æ•°æ®ä¼ è¾“é€šé“å·
            lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, m_strAlarmInfo);
src/main/java/com/ard/utils/tcp/ClientHandler.java
@@ -21,6 +21,8 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import static com.ard.utils.other.ByteUtils.toLittleEndian;
/**
 * @Description: å®¢æˆ·ç«¯å¤„理器
 * @ClassName: ClientHandler
@@ -187,27 +189,29 @@
            byte[] cmdId = Arrays.copyOfRange(data, 1, 2);//命令ID
            //  log.info("命令ID:" + DatatypeConverter.printHexBinary(cmdId));
            byte[] payloadSize = Arrays.copyOfRange(data, 2, 4);//有效负载大小
            payloadSize = ByteUtils.toLittleEndian(payloadSize);
            payloadSize = toLittleEndian(payloadSize);
            //log.info("payloadSize:" + DatatypeConverter.printHexBinary(payloadSize));
            int payloadSizeToDecimal = ByteUtils.bytesToDecimal(payloadSize);
            // log.info("有效负载大小(转整型):" + payloadSizeToDecimal);
            //endregion
            List<ArdAlarmRadar> radarAlarmInfos = new ArrayList<>();
            List<ArdAlarmRadar> radarFollowInfos = new ArrayList<>();
            //抽油机状态雷达推送集合
            List<ArdAlarmRadar> well = new ArrayList<>();
            String alarmTime = "";
            Integer targetNum = 0;
            //雷达移动防火报警
            if (Arrays.equals(cmdId, new byte[]{0x01})) {
                //region å‘Šè­¦ä¿¡æ¯åé¦ˆ
                byte[] dwTim = Arrays.copyOfRange(data, 4, 8);
                dwTim = ByteUtils.toLittleEndian(dwTim);
                dwTim = toLittleEndian(dwTim);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                long l = ByteUtils.bytesToDecimal(dwTim);
                alarmTime = sdf.format(l * 1000);
                // log.info("周视图像的出现时间(转date):" + alarmTime);
                byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
                wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
                wTargetNum = toLittleEndian(wTargetNum);
                targetNum = ByteUtils.bytesToDecimal(wTargetNum);
                if (targetNum == 0) {
                    return;
@@ -223,12 +227,12 @@
                    Integer index = 68 + uintSize * i;
                    byte[] dwID = Arrays.copyOfRange(data, index, index + 4);
                    // log.info("目标ID:" + DatatypeConverter.printHexBinary(cmdId));
                    dwID = ByteUtils.toLittleEndian(dwID);
                    dwID = toLittleEndian(dwID);
                    int id = ByteUtils.bytesToDecimal(dwID);
                    // log.info("目标ID号:" + id);
                    byte[] iDistance = Arrays.copyOfRange(data, index + 8, index + 12);
                    iDistance = ByteUtils.toLittleEndian(iDistance);
                    iDistance = toLittleEndian(iDistance);
                    double Distance = ByteUtils.bytesToDecimal(iDistance);
                    log.debug("目标当前直线距离(m):" + Distance);
@@ -279,9 +283,7 @@
                    //endregion
                    String alarmType = "";
                    byte[] cStat = Arrays.copyOfRange(data, index + 23, index + 24);
                    cStat = ByteUtils.toLittleEndian(cStat);
                    String binaryString = String.format("%8s", Integer.toBinaryString(cStat[0] & 0xFF)).replace(' ', '0');
                    // log.info("目标当前状态:" + binaryString);
                    cStat = toLittleEndian(cStat);
                    // æå–第4位至第6位的值
                    int extractedValue = (cStat[0] >> 4) & 0b00001111;
                    // åˆ¤æ–­æå–的值
@@ -291,16 +293,15 @@
                        alarmType = "热源检测";
                    }
                    // log.info("报警类型:" + alarmType);
                    byte[] szName = Arrays.copyOfRange(data, index + 64, index + 96);
                    String alarmPointName = ByteUtils.bytesToStringZh(szName);
                    // log.info("所属告警区域名称:" + alarmPointName);
                    byte[] afTx = Arrays.copyOfRange(data, index + 96, index + 100);
                    afTx = ByteUtils.toLittleEndian(afTx);
                    afTx = toLittleEndian(afTx);
                    float fTx = ByteUtils.bytesToFloat(afTx);
                    //  log.info("水平角度:" + fTx);
                    byte[] afTy = Arrays.copyOfRange(data, index + 112, index + 116);
                    afTy = ByteUtils.toLittleEndian(afTy);
                    afTy = toLittleEndian(afTy);
                    float fTy = ByteUtils.bytesToFloat(afTy);
                    log.debug("垂直角度:" + fTy);
                    // å°†è§’度转换为弧度
@@ -319,6 +320,12 @@
                    ardAlarmRadar.setLatitude(alarmXY[1]);
                    ardAlarmRadar.setAlarmType(alarmType);
                    radarAlarmInfos.add(ardAlarmRadar);
                    int bit1 = (cStat[0]>>1) & 0x1;;
                    //目标的B1=1 é”å®š
                    if(bit1==1) {
                        //将锁定目标放入锁定list
                        radarFollowInfos.add(ardAlarmRadar);
                    }
                }
                //endregion
                if (StringUtils.isEmpty(alarmTime)) {
@@ -333,24 +340,30 @@
                radarAlarmData.setAlarmTime(alarmTime);
                radarAlarmData.setArdAlarmRadars(radarAlarmInfos);
                MqttProducer.publish(2, false, "radar", JSON.toJSONString(radarAlarmData));
                if(radarFollowInfos.size()>0) {
                    radarAlarmData.setArdFollowRadars(radarFollowInfos);
                    MqttProducer.publish(2, false, "radarFollowGuide", JSON.toJSONString(radarAlarmData));
                }
                //抽油机状态MQTT队列
                radarAlarmData.setArdAlarmRadars(well);
                MqttProducer.publish(2, false, "radarWellData", JSON.toJSONString(radarAlarmData));
            }
            //抽油机AI状态反馈
            if (Arrays.equals(cmdId, new byte[]{0x04})) {
                //region抽油机AI状态反馈
                String hexString = DatatypeConverter.printHexBinary(data);
                //log.info(hexString);
                byte[] dwTim = Arrays.copyOfRange(data, 4, 8);
                dwTim = ByteUtils.toLittleEndian(dwTim);
                dwTim = toLittleEndian(dwTim);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                long l = ByteUtils.bytesToDecimal(dwTim);
                alarmTime = sdf.format(l * 1000);
                //log.info("周视图像的出现时间(转date):" + alarmTime);
                byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
                wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
                wTargetNum = toLittleEndian(wTargetNum);
                targetNum = ByteUtils.bytesToDecimal(wTargetNum);
                log.debug("目标总点数(转整型):" + targetNum);
                if (targetNum == 0) {
@@ -363,36 +376,36 @@
                    Integer index = 68 + uintSize * i;
                    byte[] dwID = Arrays.copyOfRange(data, index, index + 4);
                    //log.info("目标ID:" + DatatypeConverter.printHexBinary(dwID));
                    dwID = ByteUtils.toLittleEndian(dwID);
                    dwID = toLittleEndian(dwID);
                    int id = ByteUtils.bytesToDecimal(dwID);
                    //log.info("目标ID号:" + id);
                    //region ä¸éœ€è¦çš„字段
                    byte[] iTw = Arrays.copyOfRange(data, index + 4, index + 8);
                    iTw = ByteUtils.toLittleEndian(iTw);
                    iTw = toLittleEndian(iTw);
                    int Tw = ByteUtils.bytesToDecimal(iTw);
                    // log.info("目标当前的像素宽度:" + Tw);
                    byte[] iTh = Arrays.copyOfRange(data, index + 8, index + 12);
                    iTh = ByteUtils.toLittleEndian(iTh);
                    iTh = toLittleEndian(iTh);
                    int Th = ByteUtils.bytesToDecimal(iTh);
                    //log.info("目标当前的像素高度:" + Th);
                    byte[] fTx = Arrays.copyOfRange(data, index + 12, index + 16);
                    fTx = ByteUtils.toLittleEndian(fTx);
                    fTx = toLittleEndian(fTx);
                    float fTxAngle = ByteUtils.bytesToFloat(fTx);
                    log.debug("p角度:" + fTxAngle);
                    byte[] fTy = Arrays.copyOfRange(data, index + 16, index + 20);
                    fTy = ByteUtils.toLittleEndian(fTy);
                    fTy = toLittleEndian(fTy);
                    float fTyAngle = ByteUtils.bytesToFloat(fTy);
                    log.debug("t角度:" + fTyAngle);
                    byte[] sAreaNo = Arrays.copyOfRange(data, index + 20, index + 22);
                    sAreaNo = ByteUtils.toLittleEndian(sAreaNo);
                    sAreaNo = toLittleEndian(sAreaNo);
                    int AreaNo = ByteUtils.bytesToDecimal(sAreaNo);
                    log.debug("目标归属的告警区域号:" + AreaNo);
                    byte[] cGrp = Arrays.copyOfRange(data, index + 22, index + 23);
                    cGrp = ByteUtils.toLittleEndian(cGrp);
                    cGrp = toLittleEndian(cGrp);
                    int Grp = ByteUtils.bytesToDecimal(cGrp);
                    //log.info("所属组:" + Grp);
                    //endregion
@@ -400,7 +413,7 @@
                    //抽油机状态变量
                    String wellType;
                    byte[] cStat = Arrays.copyOfRange(data, index + 23, index + 24);
                    cStat = ByteUtils.toLittleEndian(cStat);
                    cStat = toLittleEndian(cStat);
                    //String binaryString = String.format("%8s", Integer.toBinaryString(cStat[0] & 0xFF)).replace(' ', '0');
                    //log.info("目标当前状态:" + binaryString);
                    // æå–第0位值
@@ -450,18 +463,19 @@
                radarAlarmData.setArdAlarmRadars(well);
                MqttProducer.publish(2, false, "radarWellData", JSON.toJSONString(radarAlarmData));
            }
            //强制引导
            if (Arrays.equals(cmdId, new byte[]{0x02})) {
                //region å‘Šè­¦å‰ç«¯å‘送的强制引导信息
                byte[] iDistance = Arrays.copyOfRange(data, 4, 8);
                iDistance = ByteUtils.toLittleEndian(iDistance);
                iDistance = toLittleEndian(iDistance);
                long distance = ByteUtils.bytesToDecimal(iDistance);
                log.info("目标当前距离(m):" + distance);
                byte[] fTx = Arrays.copyOfRange(data, 8, 12);
                fTx = ByteUtils.toLittleEndian(fTx);
                fTx = toLittleEndian(fTx);
                float tx = ByteUtils.bytesToFloat(fTx);
                log.debug("方位:" + tx);
                byte[] fTy = Arrays.copyOfRange(data, 12, 16);
                fTy = ByteUtils.toLittleEndian(fTy);
                fTy = toLittleEndian(fTy);
                float ty = ByteUtils.bytesToFloat(fTy);
                if (ty < 0) {
                    ty += 360;