Przeglądaj źródła

跌倒通知触发逻辑更改

chejianzheng 2 miesięcy temu
rodzic
commit
8d8fc9fd67

+ 1 - 1
device-service-application/src/main/java/com/hfln/device/application/service/DeviceSchedulerService.java

@@ -47,7 +47,7 @@ public class DeviceSchedulerService {
      * 定时检查设备告警确认状态
      * 每分钟执行一次
      */
-    @Scheduled(fixedRate = 10000)
+//    @Scheduled(fixedRate = 10000)
     public void checkDeviceAlarmAck() {
         try {
             log.debug("开始执行设备告警确认状态检查任务");

+ 168 - 77
device-service-application/src/main/java/com/hfln/device/application/service/impl/DeviceEventServiceImpl.java

@@ -3,6 +3,7 @@ package com.hfln.device.application.service.impl;
 import com.alibaba.fastjson2.JSON;
 import com.hfln.device.application.service.DeviceEventService;
 import com.hfln.device.application.service.DebugConfigService;
+import com.hfln.device.common.constant.MapConstant;
 import com.hfln.device.common.constant.redis.RedisCacheConstant;
 import com.hfln.device.domain.entity.Device;
 import com.hfln.device.domain.gateway.DeviceGateway;
@@ -962,22 +963,22 @@ public class DeviceEventServiceImpl implements DeviceEventService {
             if (messageData.containsKey("tracker_targets")) {
                 List<List<Number>> trackerTargets = (List<List<Number>>) messageData.get("tracker_targets");
                 
-                // 转换数据类型为Float
-                List<List<Float>> trackerTargetsFloat = trackerTargets.stream()
-                        .map(target -> target.stream()
-                                .map(number -> number.floatValue())
-                                .collect(Collectors.toList()))
-                        .collect(Collectors.toList());
-                
-                // === 更新实时点云和target (对应Python的核心逻辑) ===
-                List<List<Float>> rawPoints = Collections.emptyList();  // raw_points = []
-                List<List<Float>> targets = trackerTargetsFloat;         // targets = tracker_targets
-                List<List<Float>> stableTargets = device.updateTargets(targets);  // stable_targets:list = device.update_targets(targets)
-                // todo 对接算法服务 获取pose 接口
-                List<Integer> pose = device.getRealtimePose();           // pose = device.realtime_pose()
+//                // 转换数据类型为Float
+//                List<List<Float>> trackerTargetsFloat = trackerTargets.stream()
+//                        .map(target -> target.stream()
+//                                .map(number -> number.floatValue())
+//                                .collect(Collectors.toList()))
+//                        .collect(Collectors.toList());
+//
+//                // === 更新实时点云和target (对应Python的核心逻辑) ===
+//                List<List<Float>> rawPoints = Collections.emptyList();  // raw_points = []
+//                List<List<Float>> targets = trackerTargetsFloat;         // targets = tracker_targets
+//                List<List<Float>> stableTargets = device.updateTargets(targets);  // stable_targets:list = device.update_targets(targets)
+//                // todo 对接算法服务 获取pose 接口
+//                List<Integer> pose = device.getRealtimePose();           // pose = device.realtime_pose()
                 
                 // === 发送实时位置姿态消息 (对应Python: mqtt_send.realtime_pos_msg(dev_id, raw_points, pose, targets)) ===
-                mqttGateway.sendRealtimePosMessage(deviceId, rawPoints, pose, targets);
+//                mqttGateway.sendRealtimePosMessage(deviceId, rawPoints, pose, targets);
                 
                 // === 更新停留时长 (对应Python的时间更新逻辑) ===
                 // todo 停留时长 不在当前项目更新
@@ -989,8 +990,8 @@ public class DeviceEventServiceImpl implements DeviceEventService {
 //                }
 //                device.setLeaveTime(ts);                // device.set_leave_ts(ts)
 //                updateMap.put("leave")
-                if (!CollectionUtils.isEmpty(targets)) {
-                    updateMap.put("lastTargetStr", JSON.toJSONString(targets));
+                if (!CollectionUtils.isEmpty(trackerTargets)) {
+                    updateMap.put("lastTargetStr", JSON.toJSONString(trackerTargets));
                     updateMap.put("lastTargetTime", System.currentTimeMillis());
                 }
 
@@ -998,7 +999,7 @@ public class DeviceEventServiceImpl implements DeviceEventService {
                 // === 更新报警目标信息 (对应Python: device.update_alarm_targets(targets)) ===
 //                device.updateAlarmTargets(trackerTargetsFloat);
                 
-                log.debug("处理tracker_targets完成: deviceId={}, targetCount={}", deviceId, trackerTargetsFloat.size());
+                log.debug("处理tracker_targets完成: deviceId={}, targetCount={}", deviceId, trackerTargets.size());
             }
             
             // === 检查跌倒信息 (对应Python: if ("fallingMetaData" in payload): check_falling(msg)) ===
@@ -1011,96 +1012,186 @@ public class DeviceEventServiceImpl implements DeviceEventService {
             log.error("deal_dsp_data error: {}, [{}]", e.getMessage(), deviceId, e);
         }
     }
-    
+
     /**
      * 处理跌倒检查
      * 对应Python版本的check_falling方法的核心逻辑
-     * 
+     *
      * @param deviceId 设备ID
      * @param messageData 消息数据,包含fallingMetaData
      */
     private void handleFallingCheck(String deviceId, Map<String, Object> messageData) {
         try {
-            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
-            if (!deviceOpt.isPresent()) {
-                return;
-            }
-            
-            Device device = deviceOpt.get();
+
             Map<String, Object> fallingMetaData = (Map<String, Object>) messageData.get("fallingMetaData");
-            
             if (fallingMetaData == null || !fallingMetaData.containsKey("falling")) {
                 return;
             }
-            
-            // === 跌倒状态映射 (对应Python的falling_map) ===
-            Map<Integer, String> fallingMap = new HashMap<>();
-            fallingMap.put(0, "no_fall");        // 没有检测到跌倒
-            fallingMap.put(1, "fall_detected");  // 检测到跌倒
-            fallingMap.put(2, "fall_confirmed"); // 跌倒确认
-            fallingMap.put(3, "fall_calling");   // 跌倒呼救
-            
+            if (!deviceManagerService.existInCache(deviceId)) {
+                return;
+            }
+
+
             Integer falling = ((Number) fallingMetaData.get("falling")).intValue();
-            String event = fallingMap.getOrDefault(falling, "unknown");
-                 
+            String event = MapConstant.FALLING_MAP.getOrDefault(falling, "unknown");
+
             // 获取跌倒位置坐标
             Float fallLocXCm = ((Number) fallingMetaData.get("fallLocX_cm")).floatValue();
             Float fallLocYCm = ((Number) fallingMetaData.get("fallLocY_cm")).floatValue();
             Float fallLocZCm = ((Number) fallingMetaData.get("fallLocZ_cm")).floatValue();
-            
-            long now = System.currentTimeMillis(); // now = get_utc_time_ms()
-            
-            // === 上报跌倒事件 (对应Python的设备类型处理逻辑) ===
-            if ("LNB".equals(device.getDevType())) {
+
+//            long now = System.currentTimeMillis(); // now = get_utc_time_ms()
+
+            // 目前只考虑 lnb设备
+            String devType = deviceManagerService.getDevType(deviceId);
+            if ("LNB".equals(devType)) {
                 // === LNB设备处理逻辑 ===
                 // 检查报警间隔 (对应Python的告警间隔检查)
-                if (!device.shouldSendAlarmForEvent(event, now)) {
-                    return;
-                }
-                
-                List<List<Float>> targets = Arrays.asList(Arrays.asList(fallLocXCm, fallLocYCm, fallLocZCm, 0.0f));
-                int pose = "no_fall".equals(event) ? 4 : 0; // POSE_E.POSE_4.value if event == "no_fall" else POSE_E.POSE_0.value
-                
-                // 发送事件消息 (对应Python: mqtt_send.event_msg)
-                mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), pose, targets, event);
-                
-                device.setLastFallTime(event, now);      // device.set_last_fall_time(event, now)
-                Map<String, Object> updateMap = new HashMap<>();
-                updateMap.put(event, now);
-                deviceManagerService.updateDeviceMapInCache(deviceId, updateMap);
-                String text = String.format("设备上报跌倒事件:躺, dev_id:%s, event:%s", deviceId, event);
-                log.debug(text);  // LOGDBG(text)
-                
-            } else if ("LNA".equals(device.getDevType())) {
-                // === LNA设备处理逻辑 ===
-                // 跌倒状态改变时,不管报警间隔直接发送通知 (对应Python的特殊逻辑)
-                if (!device.shouldSendAlarmForLNA(falling, now)) {
-                    return;
-                }
-                
-                List<Integer> realtimePose = device.getRealtimePose(); // realtime_pose:list = device.realtime_pose()
-                if (realtimePose.isEmpty() || !Integer.valueOf(0).equals(realtimePose.get(0))) {
-                    return; // if (len(realtime_pose) <= 0 or realtime_pose[0] != POSE_E.POSE_0.value): return
+//                if (!device.shouldSendAlarmForEvent(event, now)) {
+//                    return;
+//                }
+                // 20250818 最新触发跌倒事件逻辑,根据目前设备端逻辑,跌倒事件触发条件为: 检测跌倒,确认跌倒,跌倒呼救,
+                // 每个阶段都会持续一段时间 只有在状态变化时才会进行跌倒信息发送
+                Integer lastFallEvent = deviceManagerService.getFallEvent(deviceId);
+                if (lastFallEvent != null && !lastFallEvent.equals(falling)) {
+
+                    List<List<Float>> targets = Arrays.asList(Arrays.asList(fallLocXCm, fallLocYCm, fallLocZCm, 0.0f));
+                    int pose = "no_fall".equals(event) ? 4 : 0; // POSE_E.POSE_4.value if event == "no_fall" else POSE_E.POSE_0.value
+
+                    // 发送事件消息 (对应Python: mqtt_send.event_msg)
+                    mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), pose, targets, event);
+                    log.info("发送跌倒事件消息: deviceId={}, event={}", deviceId, event);
                 }
-                
-                List<List<Float>> targets = Arrays.asList(Arrays.asList(fallLocXCm, fallLocYCm, fallLocZCm, 0.0f));
-                
-                // 发送事件消息
-                mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), realtimePose.get(0).intValue(), targets, event);
-                
-                device.setLastReportFallTime(now);      // device.set_last_report_fall_time(now)
+
+//                device.setLastFallTime(event, now);      // device.set_last_fall_time(event, now)
                 Map<String, Object> updateMap = new HashMap<>();
-                updateMap.put("lastReportFallTime", now);
+                updateMap.put("fallEvent", falling);
                 deviceManagerService.updateDeviceMapInCache(deviceId, updateMap);
                 String text = String.format("设备上报跌倒事件:躺, dev_id:%s, event:%s", deviceId, event);
                 log.debug(text);  // LOGDBG(text)
+
             }
-            
+
+//            else if ("LNA".equals(device.getDevType())) {
+//
+//                // === LNA设备处理逻辑 ===
+//                // 跌倒状态改变时,不管报警间隔直接发送通知 (对应Python的特殊逻辑)
+//                if (!device.shouldSendAlarmForLNA(falling, now)) {
+//                    return;
+//                }
+//
+//                List<Integer> realtimePose = device.getRealtimePose(); // realtime_pose:list = device.realtime_pose()
+//                if (realtimePose.isEmpty() || !Integer.valueOf(0).equals(realtimePose.get(0))) {
+//                    return; // if (len(realtime_pose) <= 0 or realtime_pose[0] != POSE_E.POSE_0.value): return
+//                }
+//
+//                List<List<Float>> targets = Arrays.asList(Arrays.asList(fallLocXCm, fallLocYCm, fallLocZCm, 0.0f));
+//
+//                // 发送事件消息
+//                mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), realtimePose.get(0).intValue(), targets, event);
+//
+//                device.setLastReportFallTime(now);      // device.set_last_report_fall_time(now)
+//                Map<String, Object> updateMap = new HashMap<>();
+//                updateMap.put("lastReportFallTime", now);
+//                deviceManagerService.updateDeviceMapInCache(deviceId, updateMap);
+//                String text = String.format("设备上报跌倒事件:躺, dev_id:%s, event:%s", deviceId, event);
+//                log.debug(text);  // LOGDBG(text)
+//            }
+
         } catch (Exception e) {
             log.error("处理跌倒检查异常: deviceId={}, error={}", deviceId, e.getMessage(), e);
         }
     }
     
+//    /**
+//     * 处理跌倒检查
+//     * 对应Python版本的check_falling方法的核心逻辑
+//     *
+//     * @param deviceId 设备ID
+//     * @param messageData 消息数据,包含fallingMetaData
+//     */
+//    private void handleFallingCheck(String deviceId, Map<String, Object> messageData) {
+//        try {
+//            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
+//            if (!deviceOpt.isPresent()) {
+//                return;
+//            }
+//
+//            Device device = deviceOpt.get();
+//            Map<String, Object> fallingMetaData = (Map<String, Object>) messageData.get("fallingMetaData");
+//
+//            if (fallingMetaData == null || !fallingMetaData.containsKey("falling")) {
+//                return;
+//            }
+//
+//            // === 跌倒状态映射 (对应Python的falling_map) ===
+//            Map<Integer, String> fallingMap = new HashMap<>();
+//            fallingMap.put(0, "no_fall");        // 没有检测到跌倒
+//            fallingMap.put(1, "fall_detected");  // 检测到跌倒
+//            fallingMap.put(2, "fall_confirmed"); // 跌倒确认
+//            fallingMap.put(3, "fall_calling");   // 跌倒呼救
+//
+//            Integer falling = ((Number) fallingMetaData.get("falling")).intValue();
+//            String event = fallingMap.getOrDefault(falling, "unknown");
+//
+//            // 获取跌倒位置坐标
+//            Float fallLocXCm = ((Number) fallingMetaData.get("fallLocX_cm")).floatValue();
+//            Float fallLocYCm = ((Number) fallingMetaData.get("fallLocY_cm")).floatValue();
+//            Float fallLocZCm = ((Number) fallingMetaData.get("fallLocZ_cm")).floatValue();
+//
+//            long now = System.currentTimeMillis(); // now = get_utc_time_ms()
+//
+//            // === 上报跌倒事件 (对应Python的设备类型处理逻辑) ===
+//            if ("LNB".equals(device.getDevType())) {
+//                // === LNB设备处理逻辑 ===
+//                // 检查报警间隔 (对应Python的告警间隔检查)
+//                if (!device.shouldSendAlarmForEvent(event, now)) {
+//                    return;
+//                }
+//
+//                List<List<Float>> targets = Arrays.asList(Arrays.asList(fallLocXCm, fallLocYCm, fallLocZCm, 0.0f));
+//                int pose = "no_fall".equals(event) ? 4 : 0; // POSE_E.POSE_4.value if event == "no_fall" else POSE_E.POSE_0.value
+//
+//                // 发送事件消息 (对应Python: mqtt_send.event_msg)
+//                mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), pose, targets, event);
+//
+//                device.setLastFallTime(event, now);      // device.set_last_fall_time(event, now)
+//                Map<String, Object> updateMap = new HashMap<>();
+//                updateMap.put(event, now);
+//                deviceManagerService.updateDeviceMapInCache(deviceId, updateMap);
+//                String text = String.format("设备上报跌倒事件:躺, dev_id:%s, event:%s", deviceId, event);
+//                log.debug(text);  // LOGDBG(text)
+//
+//            } else if ("LNA".equals(device.getDevType())) {
+//                // === LNA设备处理逻辑 ===
+//                // 跌倒状态改变时,不管报警间隔直接发送通知 (对应Python的特殊逻辑)
+//                if (!device.shouldSendAlarmForLNA(falling, now)) {
+//                    return;
+//                }
+//
+//                List<Integer> realtimePose = device.getRealtimePose(); // realtime_pose:list = device.realtime_pose()
+//                if (realtimePose.isEmpty() || !Integer.valueOf(0).equals(realtimePose.get(0))) {
+//                    return; // if (len(realtime_pose) <= 0 or realtime_pose[0] != POSE_E.POSE_0.value): return
+//                }
+//
+//                List<List<Float>> targets = Arrays.asList(Arrays.asList(fallLocXCm, fallLocYCm, fallLocZCm, 0.0f));
+//
+//                // 发送事件消息
+//                mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), realtimePose.get(0).intValue(), targets, event);
+//
+//                device.setLastReportFallTime(now);      // device.set_last_report_fall_time(now)
+//                Map<String, Object> updateMap = new HashMap<>();
+//                updateMap.put("lastReportFallTime", now);
+//                deviceManagerService.updateDeviceMapInCache(deviceId, updateMap);
+//                String text = String.format("设备上报跌倒事件:躺, dev_id:%s, event:%s", deviceId, event);
+//                log.debug(text);  // LOGDBG(text)
+//            }
+//
+//        } catch (Exception e) {
+//            log.error("处理跌倒检查异常: deviceId={}, error={}", deviceId, e.getMessage(), e);
+//        }
+//    }
+    
     /**
      * 处理点云数据
      * 对应Python版本的deal_cloudpoint方法

+ 16 - 0
device-service-common/src/main/java/com/hfln/device/common/constant/MapConstant.java

@@ -0,0 +1,16 @@
+package com.hfln.device.common.constant;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MapConstant {
+
+    public static final Map<Integer, String> FALLING_MAP =
+            Collections.unmodifiableMap(new HashMap<Integer, String>() {{
+                put(0, "no_fall");        // 没有检测到跌倒
+                put(1, "fall_detected");  // 检测到跌倒
+                put(2, "fall_confirmed"); // 跌倒确认
+                put(3, "fall_calling");   // 跌倒呼救
+            }});
+}

+ 5 - 1
device-service-domain/src/main/java/com/hfln/device/domain/service/DeviceManagerService.java

@@ -91,4 +91,8 @@ public interface DeviceManagerService {
      * 可以根据设备的各种状态触发不同类型的告警
      */
     void checkAllDeviceAlarmPlan();
-} 
+
+    String getDevType(String deviceId);
+
+    Integer getFallEvent(String deviceId);
+}

+ 10 - 17
device-service-domain/src/main/java/com/hfln/device/domain/service/impl/DeviceRedisManagerServiceImpl.java

@@ -484,23 +484,6 @@ public class DeviceRedisManagerServiceImpl implements DeviceManagerService {
             }
 
         }
-//
-//        deviceCache.forEach((devId, device) -> {
-//            // 只检查未确认的告警
-//            if (device.getAlarmAck() != null && !device.getAlarmAck()) {
-//                Long lastAckTime = device.getLastAlarmAckTime();
-//
-//                // 如果有告警且超时未确认,则自动确认
-//                if (lastAckTime != null && (currentTimeMillis - lastAckTime) > timeoutMillis) {
-//                    log.info("Device alarm auto acknowledge: {}, last alarm: {}", devId, lastAckTime);
-//                    device.setAlarmAcknowledgement(true, currentTimeMillis);
-//                    updateDeviceInCache(device);
-//
-//                    // 更新数据库中的告警确认状态
-//                    // 这里应该调用相应的网关方法
-//                }
-//            }
-//        });
     }
 
     /**
@@ -544,6 +527,16 @@ public class DeviceRedisManagerServiceImpl implements DeviceManagerService {
         });
     }
 
+    @Override
+    public String getDevType(String deviceId) {
+        return (String) redisService.hGet(RedisCacheConstant.KEY_DEVICE_pre + deviceId, "devType");
+    }
+
+    @Override
+    public Integer getFallEvent(String deviceId) {
+        return (Integer) redisService.hGet(RedisCacheConstant.KEY_DEVICE_pre + deviceId, "fallEvent");
+    }
+
     /**
      * 检查设备的滞留状态
      *