修改报警信息解析规则

This commit is contained in:
lin 2026-04-02 18:03:34 +08:00
parent 472000200d
commit 99d19d0623
17 changed files with 145 additions and 118 deletions

2
.gitignore vendored
View File

@ -31,3 +31,5 @@ certificates
/.vs
/docker/volumes
/docker/wvp/config/jwk.json
/打包/
/snap/

View File

@ -32,7 +32,5 @@ public class SipConfig {
Integer registerTimeInterval = 120;
private boolean alarm = false;
private long timeout = 1000;
}

View File

@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.gb28181.bean;
import com.genersoft.iot.vmp.service.bean.AlarmType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -13,9 +14,6 @@ import java.util.Set;
@Data
public class DeviceAlarm {
@Schema(description = "数据库id")
private String id;
@Schema(description = "设备的国标编号")
private String deviceId;
@ -220,46 +218,78 @@ public class DeviceAlarm {
if (alarmMethodSet.contains("6")) {
switch (alarmType) {
case "1":
result = "人工视频报警";
result = "存储设备磁盘故障报警";
break;
case "2":
result = "运动目标检测报警";
break;
case "3":
result = "遗留物检测报警";
break;
case "4":
result = "物体移除检测报警";
break;
case "5":
result = "绊线检测报警";
break;
case "6":
result = "入侵检测报警";
break;
case "7":
result = "逆行检测报警";
break;
case "8":
result = "徘徊检测报警";
break;
case "9":
result = "流量统计报警";
break;
case "10":
result = "密度检测报警";
break;
case "11":
result = "视频异常检测报警";
break;
case "12":
result = "快速移动报警";
result = "存储设备风扇故障报警";
break;
}
}
return result;
}
public AlarmType getAlarmTypeEnum() {
if (alarmType == null) {
return null;
}
char[] charArray = alarmMethod.toCharArray();
Set<String> alarmMethodSet = new HashSet<>();
for (char c : charArray) {
alarmMethodSet.add(Character.toString(c));
}
if (alarmMethodSet.contains("2")) {
switch (alarmType) {
case "1":
return AlarmType.VideoLoss;
case "2":
return AlarmType.DeviceTamper;
case "3":
return AlarmType.StorageFull;
case "4":
return AlarmType.DeviceHighTemperature;
case "5":
return AlarmType.DeviceLowTemperature;
}
}
if (alarmMethodSet.contains("5")) {
switch (alarmType) {
case "1":
return AlarmType.ManualVideo;
case "2":
return AlarmType.MotionDetection;
case "3":
return AlarmType.LeftObjectDetection;
case "4":
return AlarmType.ObjectRemovalDetection;
case "5":
return AlarmType.TripwireDetection;
case "6":
return AlarmType.IntrusionDetection;
case "7":
return AlarmType.ReverseDetection;
case "8":
return AlarmType.LoiteringDetection;
case "9":
return AlarmType.FlowStatistics;
case "10":
return AlarmType.DensityDetection;
case "11":
return AlarmType.VideoAbnormal;
case "12":
return AlarmType.RapidMovement;
}
}
if (alarmMethodSet.contains("6")) {
switch (alarmType) {
case "1":
return AlarmType.StorageFault;
case "2":
return AlarmType.StorageFanFault;
}
}
return null;
}
@Schema(description = "报警类型描述")
private String alarmTypeDescription;

View File

@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.gb28181.event;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEvent;
import com.genersoft.iot.vmp.gb28181.event.alarm.DeviceAlarmEvent;
import com.genersoft.iot.vmp.gb28181.event.channel.ChannelEvent;
import com.genersoft.iot.vmp.gb28181.event.device.DeviceOfflineEvent;
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
@ -41,7 +41,7 @@ public class EventPublisher {
* @param deviceAlarm
*/
public void deviceAlarmEventPublish(DeviceAlarm deviceAlarm) {
AlarmEvent alarmEvent = new AlarmEvent(this);
DeviceAlarmEvent alarmEvent = new DeviceAlarmEvent(this);
alarmEvent.setAlarmInfo(deviceAlarm);
applicationEventPublisher.publishEvent(alarmEvent);
}

View File

@ -1,32 +0,0 @@
package com.genersoft.iot.vmp.gb28181.event.alarm;
import com.genersoft.iot.vmp.gb28181.session.SseSessionManager;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;
/**
* 报警事件监听器.
*
* @author lawrencehj
* @author <a href="mailto:xiaoQQya@126.com">xiaoQQya</a>
* @since 2021/01/20
*/
@Slf4j
@Component
public class AlarmEventListener implements ApplicationListener<AlarmEvent> {
@Resource
private SseSessionManager sseSessionManager;
@Override
public void onApplicationEvent(@NotNull AlarmEvent event) {
if (log.isDebugEnabled()) {
log.debug("设备报警事件触发, deviceId: {}, {}", event.getAlarmInfo().getDeviceId(), event.getAlarmInfo().getAlarmDescription());
}
sseSessionManager.sendForAll("message", event.getAlarmInfo());
}
}

View File

@ -11,12 +11,12 @@ import java.io.Serial;
* @data: 2021-01-20
*/
public class AlarmEvent extends ApplicationEvent {
public class DeviceAlarmEvent extends ApplicationEvent {
@Serial
private static final long serialVersionUID = 1L;
public AlarmEvent(Object source) {
public DeviceAlarmEvent(Object source) {
super(source);
}

View File

@ -1,8 +1,10 @@
package com.genersoft.iot.vmp.gb28181.session;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.gb28181.event.alarm.DeviceAlarmEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@ -52,6 +54,11 @@ public class SseSessionManager {
}
sendForAll("keepalive", "alive");
}
@Async
@org.springframework.context.event.EventListener
public void onApplicationEvent(DeviceAlarmEvent event) {
sendForAll("message", event.getAlarmInfo());
}
public void sendForAll(String event, Object data) {

View File

@ -94,9 +94,6 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
* 处理alarm设备报警Notify
*/
private void processNotifyAlarm(RequestEvent evt) {
if (!sipConfig.isAlarm()) {
return;
}
log.info("[收到Notify-Alarm]{}", evt.getRequest());
try {
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);

View File

@ -190,12 +190,6 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
continue;
}
log.debug("存储报警信息、报警分类");
// 存储报警信息报警分类
if (sipConfig.isAlarm()) {
// deviceAlarmService.add(deviceAlarm);
}
if (redisCatchStorage.deviceIsOnline(sipMsgInfo.getDevice().getDeviceId())) {
publisher.deviceAlarmEventPublish(deviceAlarm);
}

View File

@ -18,6 +18,12 @@ public class Alarm {
@Schema(description = "关联通道的数据库id")
private int channelId;
@Schema(description = "关联通道国标编号")
private String channelDeviceId;
@Schema(description = "关联通道国标名称")
private String channelName;
@Schema(description = "报警描述")
private String description;

View File

@ -1,6 +1,7 @@
package com.genersoft.iot.vmp.service.impl;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.gb28181.event.alarm.DeviceAlarmEvent;
import com.genersoft.iot.vmp.service.IAlarmService;
import com.genersoft.iot.vmp.service.bean.Alarm;
import com.genersoft.iot.vmp.service.bean.AlarmType;
@ -9,6 +10,8 @@ import com.genersoft.iot.vmp.utils.DateUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.List;
@ -19,6 +22,20 @@ public class AlarmServiceImpl implements IAlarmService {
private final AlarmMapper alarmMapper;
@Async
@EventListener
public void onApplicationEvent(DeviceAlarmEvent event) {
// 处理国标的报警事件转换为通用的Alarm对象后缓存在定时任务中批量保存到数据库
Alarm alarm = new Alarm();
alarm.setChannelId(event.getAlarmInfo().getChannelId());
alarm.setChannelId(deviceAlarmEvent.getAlarmInfo().getChannelId());
alarm.setAlarmType(AlarmType.valueOf(deviceAlarmEvent.getAlarmInfo().getAlarmType()));
alarm.setAlarmTime(deviceAlarmEvent.getAlarmInfo().getAlarmTime());
alarm.setAlarmInfo(deviceAlarmEvent.getAlarmInfo().getAlarmInfo());
}
@Override
public void saveAlarmInfo(Alarm alarm) {

View File

@ -13,16 +13,23 @@ import java.util.List;
public interface AlarmMapper {
@Select("<script>" +
"SELECT * FROM wvp_alarm WHERE 1=1" +
"SELECT " +
" wa.*," +
" coalesce(wdc.gb_device_id, wdc.device_id) as channelDeviceId, " +
" coalesce(wdc.gb_name, wdc.name) as channelName " +
" FROM wvp_alarm wa " +
" LEFT join wvp_device_channel wdc " +
" on wdc.id = wa.channel_id " +
" WHERE 1=1" +
"<if test='alarmType != null and alarmType.size() > 0'>" +
" AND alarmType IN " +
" AND wa.alarm_type IN " +
"<foreach collection='alarmType' item='item' open='(' separator=',' close=')'>" +
"#{item}" +
"</foreach>" +
"</if>" +
"<if test='beginTimeLong != null'> AND alarmTime &gt;= #{beginTimeLong}</if>" +
"<if test='endTimeLong != null'> AND alarmTime &lt;= #{endTimeLong}</if>" +
" ORDER BY alarmTime DESC" +
"<if test='beginTimeLong != null'> AND wa.alarm_time &gt;= #{beginTimeLong}</if>" +
"<if test='endTimeLong != null'> AND wa.alarm_time &lt;= #{endTimeLong}</if>" +
" ORDER BY wa.alarm_time DESC" +
"</script>")
List<Alarm> getAlarms(@Param("alarmType") List<AlarmType> alarmType,
@Param("beginTimeLong") Long beginTimeLong,

View File

@ -78,7 +78,8 @@
</template>
</el-table-column>
<el-table-column prop="description" label="报警描述" show-overflow-tooltip />
<el-table-column prop="channelId" label="通道ID" width="90" />
<el-table-column prop="channelName" label="通道名称" width="150" />
<el-table-column prop="channelDeviceId" label="通道编号" width="180" />
<el-table-column prop="longitude" label="经度" width="110" />
<el-table-column prop="latitude" label="纬度" width="110" />
<el-table-column label="报警时间" width="170">

View File

@ -529,12 +529,12 @@ create table IF NOT EXISTS wvp_jt_channel (
drop table IF EXISTS wvp_alarm;
create table IF NOT EXISTS wvp_alarm (
id serial primary key COMMENT '主键ID',
channelId integer COMMENT '关联通道的数据库id',
channel_id integer COMMENT '关联通道的数据库id',
description character varying(255) COMMENT '报警描述',
snapPath character varying(255) COMMENT '报警快照路径',
recordPath character varying(255) COMMENT '报警录像路径',
snap_path character varying(255) COMMENT '报警快照路径',
record_path character varying(255) COMMENT '报警录像路径',
longitude double precision COMMENT '报警附带的经度',
latitude double precision COMMENT '报警附带的纬度',
alarmType integer COMMENT '报警类别',
alarmTime bigint COMMENT '报警时间'
alarm_type integer COMMENT '报警类别',
alarm_time bigint COMMENT '报警时间'
);

View File

@ -923,23 +923,23 @@ COMMENT ON COLUMN wvp_jt_channel.create_time IS '创建时间';
drop table IF EXISTS wvp_alarm;
create table IF NOT EXISTS wvp_alarm (
id serial primary key,
channelId integer,
channel_id integer,
description character varying(255),
snapPath character varying(255),
recordPath character varying(255),
snap_path character varying(255),
record_path character varying(255),
longitude double precision,
latitude double precision,
alarmType integer,
alarmTime bigint
alarm_type integer,
alarm_time bigint
)
COMMENT ON COLUMN wvp_alarm.id IS '主键ID';
COMMENT ON COLUMN wvp_alarm.channelId IS '关联通道的数据库id';
COMMENT ON COLUMN wvp_alarm.channel_id IS '关联通道的数据库id';
COMMENT ON COLUMN wvp_alarm.description IS '报警描述';
COMMENT ON COLUMN wvp_alarm.snapPath IS '报警快照路径';
COMMENT ON COLUMN wvp_alarm.recordPath IS '报警录像路径';
COMMENT ON COLUMN wvp_alarm.snap_path IS '报警快照路径';
COMMENT ON COLUMN wvp_alarm.record_path IS '报警录像路径';
COMMENT ON COLUMN wvp_alarm.longitude IS '报警附带的经度';
COMMENT ON COLUMN wvp_alarm.latitude IS '报警附带的纬度';
COMMENT ON COLUMN wvp_alarm.alarmType IS '报警类别';
COMMENT ON COLUMN wvp_alarm.alarmTime IS '报警时间';
COMMENT ON COLUMN wvp_alarm.alarm_type IS '报警类别';
COMMENT ON COLUMN wvp_alarm.alarm_time IS '报警时间';

View File

@ -145,14 +145,14 @@ DELIMITER ;
drop table IF EXISTS wvp_alarm;
create table IF NOT EXISTS wvp_alarm (
id serial primary key COMMENT '主键ID',
channelId integer COMMENT '关联通道的数据库id',
channel_id integer COMMENT '关联通道的数据库id',
description character varying(255) COMMENT '报警描述',
snapPath character varying(255) COMMENT '报警快照路径',
recordPath character varying(255) COMMENT '报警录像路径',
snap_path character varying(255) COMMENT '报警快照路径',
record_path character varying(255) COMMENT '报警录像路径',
longitude double precision COMMENT '报警附带的经度',
latitude double precision COMMENT '报警附带的纬度',
alarmType integer COMMENT '报警类别',
alarmTime bigint COMMENT '报警时间'
alarm_type integer COMMENT '报警类别',
alarm_time bigint COMMENT '报警时间'
);

View File

@ -51,21 +51,21 @@ ALTER table wvp_device DROP COLUMN IF EXISTS keepalive_time;
drop table IF EXISTS wvp_alarm;
create table IF NOT EXISTS wvp_alarm (
id serial primary key,
channelId integer,
channel_id integer,
description character varying(255),
snapPath character varying(255),
recordPath character varying(255),
snap_path character varying(255),
record_path character varying(255),
longitude double precision,
latitude double precision,
alarmType integer,
alarmTime bigint
alarm_type integer,
alarm_time bigint
)
COMMENT ON COLUMN wvp_alarm.id IS '主键ID';
COMMENT ON COLUMN wvp_alarm.channelId IS '关联通道的数据库id';
COMMENT ON COLUMN wvp_alarm.channel_id IS '关联通道的数据库id';
COMMENT ON COLUMN wvp_alarm.description IS '报警描述';
COMMENT ON COLUMN wvp_alarm.snapPath IS '报警快照路径';
COMMENT ON COLUMN wvp_alarm.recordPath IS '报警录像路径';
COMMENT ON COLUMN wvp_alarm.snap_path IS '报警快照路径';
COMMENT ON COLUMN wvp_alarm.record_path IS '报警录像路径';
COMMENT ON COLUMN wvp_alarm.longitude IS '报警附带的经度';
COMMENT ON COLUMN wvp_alarm.latitude IS '报警附带的纬度';
COMMENT ON COLUMN wvp_alarm.alarmType IS '报警类别';
COMMENT ON COLUMN wvp_alarm.alarmTime IS '报警时间';
COMMENT ON COLUMN wvp_alarm.alarm_type IS '报警类别';
COMMENT ON COLUMN wvp_alarm.alarm_time IS '报警时间';