# 摄像头报警信息接收 ## 前言 触发报警信息后,摄像头会把相应的报警信息通过`camera_alarm`路由键推送到`rabbitmq`的`amq.topic`交换机,`amq.topic`交换机和`camera_alarm`队列通过`camera_alarm`路由键绑定,所以最后报警信息会被推送至`camera_alarm`队列,消费者(后台服务)只需要监听该队列即可。 报警信息的具体内容如下: ```json { 'id': 200, 'alarm_id': 100, 'status': 0, 'device_id': 1, 'device_name': '森林防⽕', 'device_type': 0, 'device_manufacturer': 1, 'image': '/record/hk_alarm/20201119/image_1_20201119131301.jpg', 'video': '/record/hk_alarm/20201119/video_1_20201119131301.mp4', 'rule_id': 0, 'event_channel': 1, 'fire_max_temperature': '0.00', 'fire_target_distance': 0, 'event_type': 18833, 'event_type_desc': '⽕点检测报警.', 'event_type_ext': 1, 'event_type_ext_desc': '烟雾检测报警.', 'created_at': '2020-11-19 14:09:07', 'updated_at': '2020-11-19 14:09:07' } ``` ![image-20220225142808501](./摄像头报警信息接收文档.assets/image-20220225142808501.png) ## 环境 ### 测试环境 - **rabbitmq host & ip** 112.74.89.58:43504(端口由于使用映射工具映射,可能随时会发生改变) - **rabbitmq username & password** guest/guest - **rabbitmq virtual-host**/ - **rabbitmq management**http://92cwif.natappfree.cc(url由于使用映射工具映射,可能随时会发生改变) ### 正式环境 - **rabbitmq host & ip** 6.200.0.4:5672 - **rabbitmq username & password** third333/third333@qwerv - **rabbitmq virtual-host**/ - **rabbitmq management**暂无 > 正式环境只能在靖安旅游集散中心内网环境下访问。 ## 开发 > 本例使用SpringBoot集成RabbitMQ进行测试。 ### pom ```xml org.springframework.boot spring-boot-starter-amqp ``` ### yml ```yaml spring: rabbitmq: host: 112.74.89.58 port: 43504 virtual-host: / # 消息发送到消息队列服务器确认 publisher-confirms: true # 消息成功发送到队列确认 publisher-returns: true # 和publisher-returns搭配使用,只要消息抵达队列,以异步发送优先回调publisher-return template: mandatory: true # 手动ack listener: simple: acknowledge-mode: manual ``` ### main ```java @EnableRabbit @SpringBootApplication public class CameraAlarmApplication { public static void main(String[] args) { SpringApplication.run(CameraAlarmApplication.class, args); } } ``` ### CameraAlarmMessage.java > 根据发生的内容格式封装CameraAlarmMessage ```java @Data public class CameraAlarmMessage { /** * 99:设备列表、1:结束事件、0:新增事件 * (只需要关注status为0的事件) */ private Integer status; /** * status为0,1时会有该字段 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime created_at; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updated_at; /** * status为99时会有该字段 */ private String data_count; /** * status为99时会有该字段 */ private Object[] data; /** * status为0,1时会有该字段 */ private Long id; /** * 设备id * status为0,1时会有该字段 */ private Long device_id; // == status为0时会有以下字段 == /** * 设备品牌 1:海康、2:大华 */ private Integer device_manufacturer; private Long alarm_id; /** * 设备名称 */ private String device_name; private Integer device_type; /** * 图片 */ private String image; /** * 视频 */ private String video; private Integer rule_id; private Integer event_channel; private String fire_max_temperature; private String fire_target_distance; /** * 事件类型 * 4354:⾏为分析报警信息(海康)、18833:⽕点检测报警(海康)、 * 4391:报告报警上传,注:报警柱(海康)、8591:视频移动侦测事件(大华)、 * 8561:设备请求对⽅发起对讲事件,报警柱(大华) */ private Integer event_type; private String event_type_desc; /** * 事件类型 */ private String event_type_ext; /** * 事件类型描述 */ private String event_type_ext_desc; } ``` ### listener ```java @Component @RabbitListener(queues = "camera_alarm") // 监听 camera_alarm 队列 public class CameraAlarmListener { // 本例使用ObjectMapper把json格式的数据转换成实体类 public static final ObjectMapper mapper = new ObjectMapper(); static { JavaTimeModule javaTimeModule = new JavaTimeModule(); // LocalDateTime 日期支持 javaTimeModule.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); mapper.registerModule(javaTimeModule); mapper.setTimeZone(TimeZone.getDefault()); } @RabbitHandler public void listener(Object data, Channel channel, Message message) throws IOException { try { // 警告信息 String body = new String(message.getBody(), Charset.forName("utf-8")); // json数据转换成实体类 CameraAlarmMessage cameraAlarmMessage = mapper.readValue(body, CameraAlarmMessage.class); // 根据图例,status为0时表示新增事件 if (0 == cameraAlarmMessage.getStatus().intValue()) { // 打印事件信息 System.out.println("=============="); System.out.println(cameraAlarmMessage.toString()); System.out.println("=============="); // TODO 具体业务操作 } // 手动 ack channel.basicAck(message.getMessageProperties().getDeliveryTag(),false); } catch (Exception e) { // 发生异常直接 reject channel.basicReject(message.getMessageProperties().getDeliveryTag(),true); } } } ```