过滤通用光电报警只保留移动侦测、周界入侵报警、越界侦测报警
增加报警主机、门禁主机、通用光电数据同步
已修改12个文件
647 ■■■■ 文件已修改
src/main/java/com/ard/alarm/camera/domain/ArdCameras.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/camera/service/impl/ArdCamerasServiceImpl.java 101 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/external/domain/ArdEquipExternal.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/external/service/impl/ArdEquipExternalServiceImpl.java 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/hiksdk/common/GlobalVariable.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/hiksdk/service/impl/FMSGCallBack.java 206 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/hiksdk/service/impl/HikClientUtil.java 124 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/hiksdk/service/impl/LoginResultCallBack.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/tcp/ClientHandler.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/logback-spring.xml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ArdCamerasMapper.xml 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ArdEquipExternalMapper.xml 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/camera/domain/ArdCameras.java
@@ -17,10 +17,7 @@
@NoArgsConstructor
public class ArdCameras {
    private static final long serialVersionUID = 1L;
    public ArdCameras(String gdtype)
    {
        this.gdtype=gdtype;
    }
    /**
     * id
     */
@@ -172,4 +169,8 @@
    private Integer loginId;
    private String operatorId;
    private Date operatorExpired;
    /**
     * 更新时间
     */
    private Date updateTime;
}
src/main/java/com/ard/alarm/camera/service/impl/ArdCamerasServiceImpl.java
@@ -1,6 +1,10 @@
package com.ard.alarm.camera.service.impl;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import com.ard.alarm.camera.domain.ArdCameras;
import com.ard.alarm.camera.mapper.ArdCamerasMapper;
@@ -27,30 +31,62 @@
@Slf4j(topic = "camera")
@Order(4)
public class ArdCamerasServiceImpl implements IArdCamerasService, ApplicationRunner {
    private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    public static List<ArdCameras> ardCameraList = new ArrayList<>();
    @Resource
    private ArdCamerasMapper ardCamerasMapper;
    @Resource
    private ArdEquipExternalMapper ardEquipExternalMapper;
    @Override
    public void run(ApplicationArguments args)  {
    public void run(ApplicationArguments args) {
        //加载sdk库
        HikClientUtil.loadHCNetSDKLib();
        //获取全部海康光电尝试登录
        List<ArdCameras> ardCameras = ardCamerasMapper.selectArdCamerasList(new ArdCameras());
        HikClientUtil.loginAllCamera(ardCameras);
        //获取全部海康报警主机尝试登录
        ArdEquipExternal alarmHost = new ArdEquipExternal();
        alarmHost.setFactory("1");
        alarmHost.setType("1");
        List<ArdEquipExternal> alarmHosts = ardEquipExternalMapper.selectArdEquipExternalList(alarmHost);
        HikClientUtil.loginAllAlarmHost(alarmHosts);
        //获取全部门禁主机尝试登录
        ArdEquipExternal accessControlHost = new ArdEquipExternal();
        accessControlHost.setFactory("1");
        accessControlHost.setType("6");
        List<ArdEquipExternal>accessControlHosts = ardEquipExternalMapper.selectArdEquipExternalList(accessControlHost);
        HikClientUtil.loginAllAccessControlHost(accessControlHosts);
        ardCameraList = ardCamerasMapper.selectArdCamerasList(new ArdCameras());
        HikClientUtil.loginAllCamera(ardCameraList);
        syncTask();
    }
    /**
     * 同步任务
     * 刘苏义
     * 2023/8/11 9:09:27
     */
    private void syncTask() {
        scheduler.scheduleAtFixedRate(() -> {
            try {
                //region 定时同步相机
                List<ArdCameras> newArdCameraList = ardCamerasMapper.selectArdCamerasList(new ArdCameras());
                //需要更新的数据
                List<ArdCameras> updateList = sameListWithDifferent(ardCameraList, newArdCameraList);
                if (updateList.size() > 0) {
                    HikClientUtil.logoutAllCamera(updateList);
                    HikClientUtil.loginAllCamera(updateList);
                    ardCameraList.clear();
                    ardCameraList.addAll(newArdCameraList);
                }
                //需要删除的数据
                List<ArdCameras> delList = diffList(ardCameraList, newArdCameraList);
                if (delList.size() > 0) {
                    HikClientUtil.logoutAllCamera(delList);
                    for (ArdCameras ardCameras : delList) {
                        ardCameraList.remove(ardCameras);
                    }
                }
                //需要新增的数据
                List<ArdCameras> inserList = diffList(newArdCameraList, ardCameraList);
                if (inserList.size() > 0) {
                    HikClientUtil.loginAllCamera(inserList);
                    for (ArdCameras ardCameras : inserList) {
                        ardCameraList.add(ardCameras);
                    }
                }
                //endregion
            } catch (Exception e) {
                log.error("同步相机任务执行出错" + e.getMessage());
            }
        }, 10, 10, TimeUnit.SECONDS);
    }
    /**
@@ -74,4 +110,35 @@
    public List<ArdCameras> selectArdCamerasList(ArdCameras ardCameras) {
        return ardCamerasMapper.selectArdCamerasList(ardCameras);
    }
    //  求两个对象List的差集
    private List<ArdCameras> diffList(List<ArdCameras> oldArrayList, List<ArdCameras> newArrayList) {
        List<ArdCameras> resultList = oldArrayList.stream()
                .filter(item -> !newArrayList.stream().map(e -> e.getId()).collect(Collectors.toList()).contains(item.getId()))
                .collect(Collectors.toList());
        return resultList;
    }
    //求两个对象List的交集字段不同Id相同
    private List<ArdCameras> sameListWithDifferent(List<ArdCameras> oldList, List<ArdCameras> newList) {
        List<ArdCameras> differentFieldsList = newList.stream()
                .filter(newItem -> {
                    ArdCameras oldItem = oldList.stream()
                            .filter(item -> item.getId().equals(newItem.getId()))
                            .findFirst()
                            .orElse(null);
                    return oldItem == null ||
                            !Objects.equals(oldItem.getUpdateTime(), newItem.getUpdateTime()) ||
                            !Objects.equals(oldItem.getIp(), newItem.getIp()) ||
                            !Objects.equals(oldItem.getPort(), newItem.getPort()) ||
                            !Objects.equals(oldItem.getUsername(), newItem.getUsername()) ||
                            !Objects.equals(oldItem.getPassword(), newItem.getPassword());
                })
                .collect(Collectors.toList());
        return differentFieldsList;
    }
}
src/main/java/com/ard/alarm/external/domain/ArdEquipExternal.java
@@ -2,6 +2,8 @@
import lombok.Data;
import java.util.Date;
/**
 * 外联设备管理对象 ard_equip_external
 *
@@ -52,4 +54,6 @@
    /** 用户id */
    private String userId;
    private Date updateTime;
}
src/main/java/com/ard/alarm/external/service/impl/ArdEquipExternalServiceImpl.java
@@ -1,35 +1,171 @@
package com.ard.alarm.external.service.impl;
import java.util.List;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import com.ard.alarm.camera.domain.ArdCameras;
import com.ard.alarm.external.domain.ArdEquipExternal;
import com.ard.alarm.external.mapper.ArdEquipExternalMapper;
import com.ard.alarm.external.service.IArdEquipExternalService;
import com.ard.utils.hiksdk.service.impl.HikClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
/**
 * externalService业务层处理
 *
 *
 * @author zj
 * @date 2023-03-13
 */
@Service
public class ArdEquipExternalServiceImpl implements IArdEquipExternalService
{
@Slf4j(topic = "external")
@Order(5)
public class ArdEquipExternalServiceImpl implements IArdEquipExternalService, ApplicationRunner {
    private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    public static List<ArdEquipExternal> ardAlarmHostList = new ArrayList<>();
    public static List<ArdEquipExternal> ardAccessHostList = new ArrayList<>();
    @Autowired
    private ArdEquipExternalMapper ardEquipExternalMapper;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        //获取全部海康报警主机尝试登录
        ArdEquipExternal alarmHost = new ArdEquipExternal();
        alarmHost.setFactory("1");
        alarmHost.setType("1");
        ardAlarmHostList = ardEquipExternalMapper.selectArdEquipExternalList(alarmHost);
        HikClientUtil.loginAllAlarmHost(ardAlarmHostList);
        //获取全部门禁主机尝试登录
        ArdEquipExternal accessControlHost = new ArdEquipExternal();
        accessControlHost.setFactory("1");
        accessControlHost.setType("6");
        ardAccessHostList = ardEquipExternalMapper.selectArdEquipExternalList(accessControlHost);
        HikClientUtil.loginAllAccessControlHost(ardAccessHostList);
        syncTask();
    }
    /**
     * 同步任务
     * 刘苏义
     * 2023/8/11 9:09:27
     */
    private void syncTask() {
        scheduler.scheduleAtFixedRate(() -> {
            try {
                //region 定时同步报警主机
                ArdEquipExternal alarmHost = new ArdEquipExternal();
                alarmHost.setFactory("1");
                alarmHost.setType("1");
                List<ArdEquipExternal> newAlarmHostList = ardEquipExternalMapper.selectArdEquipExternalList(alarmHost);
                //需要更新的数据
                List<ArdEquipExternal> updateList = sameListWithDifferent(ardAlarmHostList, newAlarmHostList);
                if (updateList.size() > 0) {
                    HikClientUtil.logoutAllAlarmHost(updateList);
                    HikClientUtil.loginAllAlarmHost(updateList);
                    ardAlarmHostList.clear();
                    ardAlarmHostList.addAll(newAlarmHostList);
                }
                //需要删除的数据
                List<ArdEquipExternal> delList = diffList(ardAlarmHostList, newAlarmHostList);
                if (delList.size() > 0) {
                    HikClientUtil.logoutAllAlarmHost(delList);
                    for (ArdEquipExternal ardEquipExternal : delList) {
                        ardAlarmHostList.remove(ardEquipExternal);
                    }
                }
                //需要新增的数据
                List<ArdEquipExternal> inserList = diffList(newAlarmHostList, ardAlarmHostList);
                if (inserList.size() > 0) {
                    HikClientUtil.loginAllAlarmHost(inserList);
                    for (ArdEquipExternal ardEquipExternal : inserList) {
                        ardAlarmHostList.add(ardEquipExternal);
                    }
                }
                //endregion
                //region 定时同步门禁主机
                alarmHost = new ArdEquipExternal();
                alarmHost.setFactory("1");
                alarmHost.setType("6");
                List<ArdEquipExternal> newAccessHostList = ardEquipExternalMapper.selectArdEquipExternalList(alarmHost);
                //需要更新的数据
                 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
            } catch (Exception e) {
                log.error("同步外联任务执行出错" + e.getMessage());
            }
        }, 10, 10, TimeUnit.SECONDS);
    }
    //求两个对象List的交集字段不同Id相同
    private List<ArdEquipExternal> sameListWithDifferent(List<ArdEquipExternal> oldList, List<ArdEquipExternal> newList) {
        List<ArdEquipExternal> differentFieldsList = newList.stream()
                .filter(newItem -> {
                    ArdEquipExternal oldItem = oldList.stream()
                            .filter(item -> item.getId().equals(newItem.getId()))
                            .findFirst()
                            .orElse(null);
                    return oldItem == null ||
                            !Objects.equals(oldItem.getUpdateTime(), newItem.getUpdateTime()) ||
                            !Objects.equals(oldItem.getIp(), newItem.getIp()) ||
                            !Objects.equals(oldItem.getPort(), newItem.getPort()) ||
                            !Objects.equals(oldItem.getUsername(), newItem.getUsername()) ||
                            !Objects.equals(oldItem.getPassword(), newItem.getPassword());
                })
                .collect(Collectors.toList());
        return differentFieldsList;
    }
    //  求两个对象List的差集
    private List<ArdEquipExternal> diffList(List<ArdEquipExternal> oldArrayList, List<ArdEquipExternal> newArrayList) {
        List<ArdEquipExternal> resultList = oldArrayList.stream()
                .filter(item -> !newArrayList.stream().map(e -> e.getId()).collect(Collectors.toList()).contains(item.getId()))
                .collect(Collectors.toList());
        return resultList;
    }
    /**
     * 查询external
     *
     *
     * @param id external主键
     * @return external
     */
    @Override
    public ArdEquipExternal selectArdEquipExternalById(String id)
    {
    public ArdEquipExternal selectArdEquipExternalById(String id) {
        return ardEquipExternalMapper.selectArdEquipExternalById(id);
    }
@@ -40,14 +176,14 @@
    /**
     * 查询external列表
     *
     *
     * @param ardEquipExternal external
     * @return external
     */
    @Override
    public List<ArdEquipExternal> selectArdEquipExternalList(ArdEquipExternal ardEquipExternal)
    {
    public List<ArdEquipExternal> selectArdEquipExternalList(ArdEquipExternal ardEquipExternal) {
        return ardEquipExternalMapper.selectArdEquipExternalList(ardEquipExternal);
    }
}
src/main/java/com/ard/utils/hiksdk/common/GlobalVariable.java
@@ -19,6 +19,10 @@
    public static Map<String, ArdCameras> cameraMap = new HashMap<>();
    //保存相机信息key:ip value:报警主机对象
    public static Map<String, ArdEquipExternal> alarmHostMap = new HashMap<>();
    //保存相机信息key:ip value:门禁主机对象
    public static Map<String, ArdEquipExternal> accessHostMap = new HashMap<>();
    //保存相机登录信息key:cameraId value:loginId
    public static Map<String, Integer> loginMap = new HashMap<>();
    //保存相机的布防信息key:cameraId value:lAlarmHandle
    public static Map<String, Integer> alarmMap = new HashMap<>();
}
src/main/java/com/ard/utils/hiksdk/service/impl/FMSGCallBack.java
@@ -46,26 +46,56 @@
     */
    @Override
    public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        String sDeviceIP = ByteUtils.bytesToStringZh(pAlarmer.sDeviceIP);
        Integer wLinkPort = Integer.valueOf(pAlarmer.wLinkPort);
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sDeviceIP = ByteUtils.bytesToStringZh(pAlarmer.sDeviceIP);//设备IP地址
        Integer wLinkPort = Integer.valueOf(pAlarmer.wLinkPort);//设备通讯端口
        CameraEventInfo info;
        String sTime;//事件时间
        String url = "";//事件图片
        Boolean isSnapPic=true;
        //lCommand是传的报警类型
        log.debug("报警事件类型:lCommand:" + Integer.toHexString(lCommand));
        //log.debug("报警事件类型:lCommand:" + Integer.toHexString(lCommand));
        switch (lCommand) {
            case HCNetSDK.COMM_ALARM_V30:
                log.debug("移动侦测、视频丢失、遮挡、IO信号量等报警信息(暂不解析)");
            case HCNetSDK.COMM_ALARM_RULE:
                log.debug("行为分析信息报警信息上报");
                //region 行为分析信息
                log.debug("移动侦测");
                ArdCameras ardCameras = new ArdCameras();
                ardCameras.setIp(sDeviceIP);
                ardCameras.setPort(wLinkPort);
                IArdCamerasService ardCamerasService = SpringTool.getApplicationContext().getBean(IArdCamerasService.class);
                ArdCameras ardcamere = ardCamerasService.selectArdCamerasList(ardCameras).get(0);
                ArdCameras camera = ardCamerasService.selectArdCamerasList(ardCameras).get(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();
                switch (netDvrAlarminfoV30.dwAlarmType) {
                    case 3:
                        info = new CameraEventInfo();
                        info.setAlarmName("移动侦测");
                        info.setAlarmTime(fmt.format(new Date()));
                        info.setCameraName(camera.getName());
                        info.setCameraId(camera.getId());
                        info.setCameraIp(camera.getIp());
                        info.setCameraType(camera.getGdtype());
                        info.setCameraChannel(Integer.valueOf(netDvrAlarminfoV30.byChannel[0]));
                        info.setLongitude(camera.getLongitude());
                        info.setLatitude(camera.getLatitude());
                        info.setAlarmType("移动侦测");
                        printLog(info);
                        //图片存入minio
                        url = savePicture(info);
                        info.setPicUrl(url);
                        publishMqtt(info);
                        break;
                }
            case HCNetSDK.COMM_ALARM_RULE:
                log.debug("行为分析信息报警信息上报");
                //region 行为分析信息
                ardCameras = new ArdCameras();
                ardCameras.setIp(sDeviceIP);
                ardCameras.setPort(wLinkPort);
                ardCamerasService = SpringTool.getApplicationContext().getBean(IArdCamerasService.class);
                ArdCameras ardCamera = ardCamerasService.selectArdCamerasList(ardCameras).get(0);
                HCNetSDK.NET_VCA_RULE_ALARM strVcaAlarm = new HCNetSDK.NET_VCA_RULE_ALARM();
                strVcaAlarm.write();
@@ -79,80 +109,81 @@
                info = new CameraEventInfo();
                info.setAlarmName("人员行为分析");
                info.setAlarmTime(sTime);
                info.setCameraName(ardcamere.getName());
                info.setCameraId(ardcamere.getId());
                info.setCameraName(ardCamera.getName());
                info.setCameraId(ardCamera.getId());
                info.setCameraIp(ipaddr);
                info.setCameraType(ardcamere.getGdtype());
                info.setCameraType(ardCamera.getGdtype());
                info.setCameraChannel(channel);
                info.setLongitude(ardcamere.getLongitude());
                info.setLatitude(ardcamere.getLatitude());
                info.setAlarmType(ardcamere.getGdtype());
                info.setLongitude(ardCamera.getLongitude());
                info.setLatitude(ardCamera.getLatitude());
                info.setRuleId(ruleID);
                switch (strVcaAlarm.struRuleInfo.wEventTypeEx) {
                    case 1: //region穿越警戒面 (越界侦测)
                        info.setAlarmType("越界侦测报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_TRAVERSE_PLANE.class);
                        printLog(info);
                        //图片存入minio
                        url = savePicture(info);
                        info.setPicUrl(url);
                        publishMqtt(info);
                        //endregion
                        break;
                    case 2: //region 目标进入区域
                        info.setAlarmType("目标进入区域报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_AREA.class);
                        //endregion
                        break;
                    case 3: //region 目标离开区域
                        info.setAlarmType("目标离开区域报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_AREA.class);
                        //endregion
                        break;
//                    case 2: //region 目标进入区域
//                        info.setAlarmType("目标进入区域报警");
//                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_AREA.class);
//                        //endregion
//                        break;
//                    case 3: //region 目标离开区域
//                        info.setAlarmType("目标离开区域报警");
//                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_AREA.class);
//                        //endregion
//                        break;
                    case 4: //region 周界入侵
                        info.setAlarmType("周界入侵报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_INTRUSION.class);
                        printLog(info);
                        //图片存入minio
                        url = savePicture(info);
                        info.setPicUrl(url);
                        publishMqtt(info);
                        //endregion
                        break;
                    case 5: //region 徘徊
                        info.setAlarmType("徘徊事件报警");
                        //endregion
                        break;
                    case 8: //region 快速移动(奔跑)
                        info.setAlarmType("快速移动(奔跑)事件报警");
                        //endregion
                        break;
                    case 13: //region 物品遗留事件
                        info.setAlarmType("物品遗留事件报警");
                        //endregion
                        break;
                    case 14: //region 物品拿取事件
                        info.setAlarmType("物品拿取事件事件报警");
                        //endregion
                        break;
                    case 20: //region 倒地检测
                        info.setAlarmType("倒地事件触发");
                        //endregion
                        break;
                    case 44: //region 玩手机
                        info.setAlarmType("玩手机报警事件");
                        //endregion
                        break;
//                    case 5: //region 徘徊
//                        info.setAlarmType("徘徊事件报警");
//                        //endregion
//                        break;
//                    case 8: //region 快速移动(奔跑)
//                        info.setAlarmType("快速移动(奔跑)事件报警");
//                        //endregion
//                        break;
//                    case 13: //region 物品遗留事件
//                        info.setAlarmType("物品遗留事件报警");
//                        //endregion
//                        break;
//                    case 14: //region 物品拿取事件
//                        info.setAlarmType("物品拿取事件事件报警");
//                        //endregion
//                        break;
//                    case 20: //region 倒地检测
//                        info.setAlarmType("倒地事件触发");
//                        //endregion
//                        break;
//                    case 44: //region 玩手机
//                        info.setAlarmType("玩手机报警事件");
//                        //endregion
//                        break;
                    default:
                       // log.debug("未知行为事件类型:" + strVcaAlarm.struRuleInfo.wEventTypeEx);
                        isSnapPic=false;
                        // log.debug("未知行为事件类型:" + strVcaAlarm.struRuleInfo.wEventTypeEx);
                        break;
                }
                //endregion
                //图片存入minio
                if(isSnapPic) {
                    url = savePicture(info);
                    info.setPicUrl(url);
                    publishMqtt(info);
                }
                break;
            case HCNetSDK.COMM_UPLOAD_FACESNAP_RESULT:
                log.debug("人脸检测事件上报(暂不解析)");
                break;
            case HCNetSDK.COMM_GISINFO_UPLOAD:
                log.debug("GPS报警信息上报(暂不解析)");
                break;
//            case HCNetSDK.COMM_UPLOAD_FACESNAP_RESULT:
//                log.debug("人脸检测事件上报(暂不解析)");
//                break;
//            case HCNetSDK.COMM_GISINFO_UPLOAD:
//                log.debug("GPS报警信息上报(暂不解析)");
//                break;
            case HCNetSDK.COMM_ALARMHOST_CID_ALARM:
                log.debug("报警主机CID报告报警上报");
                //region 报警主机报警处理
@@ -256,7 +287,7 @@
                if (dwMajor != 5) {
                    //只获取事件
                    log.debug("非事件报警数据上报(暂不解析)");
                    // log.debug("非事件报警数据上报(暂不解析)");
                    break;
                }
                int dwMinor = strACSInfo.dwMinor;
@@ -357,47 +388,13 @@
                //endregion
                break;
            default:
                log.debug("未知报警事件类型:lCommand:" + Integer.toHexString(lCommand));
                // log.debug("未知报警事件类型:lCommand:" + Integer.toHexString(lCommand));
                break;
        }
        return true;
    }
    /**
     * @描述 保存图片封装方法
     * @参数 [strVcaAlarm, eventName, eventNameEng]
     * @返回值 java.lang.String
     * @创建人 刘苏义
     * @创建时间 2023/2/17 15:05
     * @修改人和其它信息
     */
    private String savePicture(HCNetSDK.NET_VCA_RULE_ALARM strVcaAlarm, String eventName, String eventNameEng) {
        String url = "";
        if ((strVcaAlarm.dwPicDataLen > 0) && (strVcaAlarm.byPicTransType == 0)) {
            String currentTime = new SimpleDateFormat("yyyyMMdd").format(new Date());
            try {
                //存入minio
                long offset = 0;
                ByteBuffer buffers = strVcaAlarm.pImage.getByteBuffer(offset, strVcaAlarm.dwPicDataLen);
                byte[] bytes = new byte[strVcaAlarm.dwPicDataLen];
                buffers.rewind();
                buffers.get(bytes);
                InputStream inputStream = new ByteArrayInputStream(bytes);
                String ipaddr = new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4).trim();//设备ip
                String UUID = java.util.UUID.randomUUID().toString().replace("-", "");
                String filename = ipaddr + "/" + currentTime + "/" + eventNameEng + "/" + UUID + ".jpg";
                boolean uploadRes = MinioUtils.uploadObject("pic", filename, inputStream, "image/jpeg");
                if (uploadRes) {
                    url = MinioClientSingleton.domainUrl + filename;
                    log.info("写入minio图片地址:" + url);
                }
            } catch (Exception ex) {
                log.error(eventName + "处理图片异常:" + ex.getMessage());
            }
        }
        return url;
    }
    /**
     * 相机截图
@@ -405,8 +402,7 @@
    private String savePicture(CameraEventInfo info) {
        CameraCmd cmd = new CameraCmd();
        ArdCameras Cameras = GlobalVariable.cameraMap.get(info.getCameraIp());
        if(Cameras==null)
        {
        if (Cameras == null) {
            return "";
        }
        cmd.setCameraId(Cameras.getId());
@@ -442,9 +438,9 @@
     * 打印门禁事件日志
     */
    private void printLog(AccessControlHostEventInfo info) {
        log.debug("【报警ID】" + info.getSerialNo() + "【设备编号】"+
        log.debug("【报警ID】" + info.getSerialNo() + "【设备编号】" +
                "【门编号】" + info.getDoorNo() + "【事件类型】" + info.getAlarmType() +
                "【防区类型】" + info.getDefenseType()+"【时间】" + info.getAlarmTime() +
                "【防区类型】" + info.getDefenseType() + "【时间】" + info.getAlarmTime() +
                "【门禁主机ID】" + info.getAcsId());
    }
src/main/java/com/ard/utils/hiksdk/service/impl/HikClientUtil.java
@@ -121,11 +121,8 @@
    /**
     * @描述 注册登录 集成于NET_DVR_Login_V30,支持同步和异步登录
     * @参数 [dvrLogin]
     * @返回值 java.lang.Integer
     * @创建人 刘苏义
     * @创建时间 2023/1/17 16:12
     * @修改人和其它信息
     */
    public static void login(DeviceInfo deviceInfo) {
        // 初始化
@@ -173,12 +170,34 @@
    }
    /**
     * @描述 用户注销
     * @创建人 刘苏义
     * @创建时间 2023/1/17 16:12
     */
    public static void logout(DeviceInfo deviceInfo) {
        String deviceIpPort = deviceInfo.getIp() + ":" + deviceInfo.getPort();
        //撤防
        if (GlobalVariable.alarmMap.containsKey(deviceInfo.getDeviceId())) {
            Integer lAlarmHandle = GlobalVariable.alarmMap.get(deviceInfo.getDeviceId());
            boolean b = hCNetSDK.NET_DVR_CloseAlarmChan_V30(lAlarmHandle);
            if (b) {
                log.debug("设备【" + deviceIpPort + "】撤防成功");
            }
        }
        //登出
        if (GlobalVariable.loginMap.containsKey(deviceInfo.getDeviceId())) {
            Integer lUserID = GlobalVariable.loginMap.get(deviceInfo.getDeviceId());
            boolean b = hCNetSDK.NET_DVR_Logout(lUserID);
            if (b) {
                log.debug("设备【" + deviceIpPort + "】注销成功");
            }
        }
    }
    /**
     * @描述 登录所有相机
     * @参数 []
     * @返回值 void
     * @创建人 刘苏义
     * @创建时间 2023/2/3 10:10
     * @修改人和其它信息
     */
    public static void loginAllCamera(List<ArdCameras> ardCameras) {
        try {
@@ -191,8 +210,30 @@
                info.setUsername(camera.getUsername());
                info.setPassword(camera.getPassword());
                login(info);
                String ip = camera.getIp();
                GlobalVariable.cameraMap.put(ip, camera);
                GlobalVariable.cameraMap.put(camera.getIp(), camera);
            }
        } catch (Exception ex) {
            log.error("初始化登录相机异常:" + ex.getMessage());
        }
    }
    /**
     * @描述 登出所有相机
     * @创建人 刘苏义
     * @创建时间 2023/2/3 10:10
     */
    public static void logoutAllCamera(List<ArdCameras> ardCameras) {
        try {
            for (ArdCameras camera : ardCameras) {
                Thread.sleep(100);
                DeviceInfo info = new DeviceInfo();
                info.setDeviceId(camera.getId());
                info.setIp(camera.getIp());
                info.setPort(camera.getPort());
                info.setUsername(camera.getUsername());
                info.setPassword(camera.getPassword());
                logout(info);
                GlobalVariable.cameraMap.remove(camera.getIp());
            }
        } catch (Exception ex) {
            log.error("初始化登录相机异常:" + ex.getMessage());
@@ -201,11 +242,8 @@
    /**
     * @描述 登录所有报警主机
     * @参数 []
     * @返回值 void
     * @创建人 刘苏义
     * @创建时间 2023/2/3 10:10
     * @修改人和其它信息
     */
    public static void loginAllAlarmHost(List<ArdEquipExternal> ardEquipExternals) {
        try {
@@ -225,14 +263,34 @@
            log.error("初始化报警主机异常:" + ex.getMessage());
        }
    }
    /**
     * @描述 登录所有门禁主机
     * @参数 []
     * @返回值 void
     * @描述 登出所有报警主机
     * @创建人 刘苏义
     * @创建时间 2023/2/3 10:10
     * @修改人和其它信息
     */
    public static void logoutAllAlarmHost(List<ArdEquipExternal> ardEquipExternals)
    {
        try {
            for (ArdEquipExternal alarmHost : ardEquipExternals) {
                Thread.sleep(100);
                DeviceInfo info = new DeviceInfo();
                info.setDeviceId(alarmHost.getId());
                info.setIp(alarmHost.getIp());
                info.setPort(alarmHost.getPort());
                info.setUsername(alarmHost.getUsername());
                info.setPassword(alarmHost.getPassword());
                logout(info);
                String ip = alarmHost.getIp();
                GlobalVariable.alarmHostMap.remove(ip);
            }
        } catch (Exception ex) {
            log.error("初始化登录相机异常:" + ex.getMessage());
        }
    }
    /**
     * @描述 登录所有门禁主机
     * @创建人 刘苏义
     * @创建时间 2023/2/3 10:10
     */
    public static void loginAllAccessControlHost(List<ArdEquipExternal> ardEquipExternals) {
        try {
@@ -246,13 +304,35 @@
                info.setPassword(accessControlHost.getPassword());
                login(info);
                String ip = accessControlHost.getIp();
                GlobalVariable.alarmHostMap.put(ip, accessControlHost);
                GlobalVariable.accessHostMap.put(ip, accessControlHost);
            }
        } catch (Exception ex) {
            log.error("初始化报警主机异常:" + ex.getMessage());
        }
    }
    /**
     * @描述 登出所有门禁主机
     * @创建人 刘苏义
     * @创建时间 2023/2/3 10:10
     */
    public static void logoutAllAccessControlHost(List<ArdEquipExternal> ardEquipExternals) {
        try {
            for (ArdEquipExternal accessControlHost : ardEquipExternals) {
                Thread.sleep(100);
                DeviceInfo info = new DeviceInfo();
                info.setDeviceId(accessControlHost.getId());
                info.setIp(accessControlHost.getIp());
                info.setPort(accessControlHost.getPort());
                info.setUsername(accessControlHost.getUsername());
                info.setPassword(accessControlHost.getPassword());
                logout(info);
                String ip = accessControlHost.getIp();
                GlobalVariable.accessHostMap.remove(ip);
            }
        } catch (Exception ex) {
            log.error("初始化报警主机异常:" + ex.getMessage());
        }
    }
    /**
     * @描述 注销登录
     * @参数 [dvrLogin]
@@ -324,10 +404,8 @@
                log.error("设备【" + deviceIpPort + "】布防失败,错误码==========》" + hCNetSDK.NET_DVR_GetLastError());
                // 注销 释放sdk资源
                logout(lUserID);
                return lAlarmHandle;
            } else {
                log.debug("设备【" + deviceIpPort + "】布防成功");
                return lAlarmHandle;
            }
        }
        return lAlarmHandle;
@@ -374,11 +452,11 @@
        //设置图片大小
        ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024);
        // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中
        log.debug("-----------这里开始封装 NET_DVR_CaptureJPEGPicture_NEW---------");
       // log.debug("-----------这里开始封装 NET_DVR_CaptureJPEGPicture_NEW---------");
        boolean is = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, channelNum, jpeg, jpegBuffer, 1024 * 1024, a);
        log.debug("-----------这里开始图片存入内存----------" + is);
        //log.debug("-----------这里开始图片存入内存----------" + is);
        if (is) {
            log.debug("hksdk(抓图)-结果状态值(0表示成功):" + hCNetSDK.NET_DVR_GetLastError());
          //  log.debug("hksdk(抓图)-结果状态值(0表示成功):" + hCNetSDK.NET_DVR_GetLastError());
            byte[] array = jpegBuffer.array();
            //存储到minio
src/main/java/com/ard/utils/hiksdk/service/impl/LoginResultCallBack.java
@@ -29,7 +29,10 @@
            GlobalVariable.loginMap.put(deviceInfo.getDeviceId(), lUserID);
            log.debug("设备【" + deviceIpPort + "】登录成功");
            // 设置报警回调函数,建立报警上传通道(启用布防)
            HikClientUtil.setupAlarmChan(deviceIpPort, lUserID, -1);
            int lAlarmHandle = HikClientUtil.setupAlarmChan(deviceIpPort, lUserID, -1);
            if (lAlarmHandle != -1) {
                GlobalVariable.alarmMap.put(deviceInfo.getDeviceId(), lAlarmHandle);
            }
        } else {
            log.debug("设备【" + deviceIpPort + "】登录失败");
        }
src/main/java/com/ard/utils/tcp/ClientHandler.java
@@ -208,7 +208,7 @@
                if (targetNum == 0) {
                    return;
                }
                log.info("目标总点数(转整型):" + targetNum);
                log.debug("目标总点数(转整型):" + targetNum);
                //解析NET_TARGET_UNIT(64是NET_TARGET_HEAD的字节数)
                int uintSize = (payloadSizeToDecimal - 64) / targetNum;
@@ -327,7 +327,7 @@
                byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
                wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
                targetNum = ByteUtils.bytesToDecimal(wTargetNum);
                log.info("目标总点数(转整型):" + targetNum);
                log.debug("目标总点数(转整型):" + targetNum);
                if (targetNum == 0) {
                    return;
                }
src/main/resources/logback-spring.xml
@@ -76,6 +76,28 @@
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--外联设备报警日志输出-->
    <appender name="external" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/external.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/external.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--过滤的级别-->
            <level>INFO</level>
            <!--匹配时的操作:接收(记录)-->
            <onMatch>ACCEPT</onMatch>
            <!--不匹配时的操作:拒绝(不记录)-->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--Netty日志输出-->
    <appender name="netty" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/netty.log</file>
@@ -148,6 +170,10 @@
    <logger name="camera" level="INFO">
        <appender-ref ref="camera"/>
    </logger>
    <!--外联设备报警操作日志-->
    <logger name="external" level="INFO">
        <appender-ref ref="external"/>
    </logger>
    <!--Netty日志-->
    <logger name="netty"  level="INFO">
        <appender-ref ref="netty"/>
src/main/resources/mapper/ArdCamerasMapper.xml
@@ -32,6 +32,7 @@
        <result property="operatorExpired" column="operator_expired"/>
        <result property="camMaxVisibleDistance" column="cam_max_visible_distance"/>
        <result property="camAlarmGuideEnable" column="cam_alarm_guide_enable"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>
    <sql id="selectArdCamerasVo">
@@ -60,7 +61,8 @@
               c.operator_id,
               c.operator_expired,
               c.cam_max_visible_distance,
               c.cam_alarm_guide_enable
               c.cam_alarm_guide_enable,
               c.update_time
        from ard_cameras c
    </sql>
src/main/resources/mapper/ArdEquipExternalMapper.xml
@@ -18,6 +18,7 @@
        <result property="altitude" column="altitude"/>
        <result property="deptId" column="dept_id"/>
        <result property="userId" column="user_id"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>
    <sql id="selectArdEquipExternalVo">
@@ -31,7 +32,8 @@
               c.password,
               c.longitude,
               c.latitude,
               c.altitude
               c.altitude,
               c.update_time
        from ard_equip_external c
    </sql>
    <select id="selectArdEquipExternal" parameterType="ArdEquipExternal" resultMap="ArdEquipExternalResult">