| Dockerfile | ●●●●● patch | view | raw | blame | history | |
| pom.xml | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/ard/alarm/external/service/IArdEquipExternalService.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/ard/alarm/external/service/impl/ArdEquipExternalServiceImpl.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/ard/alarm/radar/domain/RadarAlarmData.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/ard/utils/hiksdk/domain/FaceMatchEventInfo.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/ard/utils/hiksdk/domain/FaceSnapEventInfo.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/ard/utils/hiksdk/service/impl/FMSGCallBack.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/ard/utils/hiksdk/service/impl/HikClientUtil.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/ard/utils/tcp/ClientHandler.java | ●●●●● patch | view | raw | blame | history |
Dockerfile
File was deleted 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
New file @@ -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
New file @@ -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;