chejianzheng 3 месяцев назад
Родитель
Сommit
6875bbf96d

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

@@ -34,7 +34,7 @@ public class DeviceManagementTask {
      * 定时检查设备保活状态
      * 每30秒执行一次
      */
-    @Scheduled(fixedRate = 30000)
+//    @Scheduled(fixedRate = 30000)
     public void checkDeviceKeepalive() {
         try {
             log.debug("开始执行设备保活状态检查任务");

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

@@ -31,7 +31,7 @@ public class DeviceSchedulerService {
      * 定时检查设备保活状态
      * 每30秒执行一次
      */
-//    @Scheduled(fixedRate = 30000)
+    @Scheduled(fixedRate = 30000)
     public void checkDeviceKeepAlive() {
         try {
             log.debug("开始执行设备保活状态检查任务");

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

@@ -31,7 +31,7 @@ public class AlarmPlanCheckTask {
      * 定期检查告警计划
      * 每30秒执行一次
      */
-    @Scheduled(fixedRate = 30000)
+//    @Scheduled(fixedRate = 30000)
     public void checkAlarmPlans() {
         log.debug("开始检查告警计划...");
         

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

@@ -100,7 +100,7 @@ public class DeviceStatusCheckTask {
      * 检查所有设备停留时间 (参考Python版本的check_all_dev_stay_time函数)
      * 每30秒执行一次
      */
-    @Scheduled(fixedRate = 30000) // 30秒检查一次
+//    @Scheduled(fixedRate = 30000) // 30秒检查一次
     public void checkAllDeviceStayTime() {
         try {
             log.debug("开始检查所有设备停留时间...");

+ 6 - 5
device-service-common/src/main/java/com/hfln/device/common/constant/redis/RedisCacheConstant.java

@@ -5,13 +5,14 @@ package com.hfln.device.common.constant.redis;
  */
 public interface RedisCacheConstant {
 
+
     /**
-     * 登录验证码
+     * redis缓存设备 key
      */
-    String SMS_LOGIN_CODE = "sms:login:";
-    String SMS_SIGNUP_CODE = "sms:signup:";
-    String SMS_SEND_LOGIN_TIME = "sms:login:frequency:";
-    String SMS_SEND_SIGNUP_TIME = "sms:signup:frequency:";
+    String KEY_DEVICE = "hfln:device:";
+    String KEY_DEVICE_ID = "hfln:devid:";
+    String KEY_DEVICE_DEBUG_PARAM_PRE = "hfln:device:debugParam-";
+
 
 
 

+ 1611 - 0
device-service-domain/src/main/java/com/hfln/device/domain/entity/DeviceCache.java

@@ -0,0 +1,1611 @@
+package com.hfln.device.domain.entity;
+
+import com.hfln.device.domain.vo.BehaviorPattern;
+import lombok.*;
+import org.springframework.util.CollectionUtils;
+
+import java.util.*;
+
+/**
+ * 设备实体类 - 聚合根(Aggregate Root)
+ *
+ * 作为聚合根,Device 封装了设备相关的业务属性、行为和不变性,
+ * 其生命周期内可包含多个子实体(如 Region)和值对象(如 InstallParam、TrackingRegion、NetworkInfo)。
+ */
+@Getter
+@Setter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DeviceCache {
+
+    /**
+     * 设备ID
+     */
+    private String devId;                // 设备ID
+    private String devType;              // 设备类型
+    private String software;             // 软件版本
+    private String hardware;             // 硬件版本
+    private String bluVer;               // 蓝牙版本
+
+//    private NetworkInfo network;         // 网络信息
+    private String ssid;             // WIFI SSID
+    private String password;         // WIFI 密码
+    private String ip;               // IP地址
+//    private InstallParam installParam;   // 安装参数
+private String mountPlain;       // 安装面
+    private Integer isCeiling;       // 是否天花板安装
+    private Float height;            // 安装高度
+//    private TrackingRegion trackingRegion; // 跟踪区域
+    private Integer startX;          // 起始X
+    private Integer startY;          // 起始Y
+    private Integer startZ;          // 起始Z
+    private Integer stopX;           // 终止X
+    private Integer stopY;           // 终止Y
+    private Integer stopZ;           // 终止Z
+
+    private List<Float> targets;         // 实时目标位置
+    //    private List<Integer> realtimePose;  // 实时姿态
+    //
+//    private Long enterTs;                // 进入时间戳
+//    private Long leaveTs;                // 离开时间戳
+//    private Long stayTime;               // 停留时间
+
+//    private Long retentionTime;          // 滞留时间
+//    private Long retentionKeepTime;      // 滞留保持时间
+//    private Long retentionAlarmTime;     // 滞留告警时间
+private Integer online;              // 在线状态:0-离线,1-在线
+
+    private Long keepaliveTime;          // 最后一次心跳时间
+    private Long expireTime;             // 超时时间(毫秒),默认90秒
+        private Boolean alarmAck;            // 告警确认
+        private Long lastAlarmAckTime;       // 最后告警确认时间
+    //
+    private Long lastReportFallTime;     // 最后上报跌倒时间
+//
+//    private String lastAlarmType;        // 最后一次告警类型
+//    private Long lastAlarmTime;          // 最后一次告警时间
+
+    // 跌倒状态记录 (对应Python版本的device.falling_)
+    private Integer falling_;            // 当前跌倒状态:0-无跌倒,1-检测到跌倒,2-跌倒确认,3-跌倒呼救
+
+    // 告警间隔相关属性 (参考Python版本)
+    private Long alarmInterval;          // 告警间隔时间(毫秒),默认30秒
+    private Long alarmAckInterval;       // 告警确认间隔时间(毫秒),默认5分钟
+
+    // 调试参数 (参考Python版本的g_dev_dbg_map)
+    private Map<String, Object> debugParams = new HashMap<>();
+
+//    // 姿态分析相关属性
+//    private PoseAnalysisResult lastPoseResult;  // 最近一次姿态分析结果
+//    private Long lastPoseChangeTime;            // 最近一次姿态变化时间
+//    private Map<Integer, Long> poseDurations;   // 各姿态持续时间(姿态ID -> 持续时间毫秒)
+//    private Map<Integer, Float> poseDistribution; // 姿态分布(姿态ID -> 占比百分比)
+
+//    // 行为分析相关属性
+//    private Long lastActivityDetectTime;        // 最近一次活动检测时间
+//    private Long lastRestTime;                  // 最近一次休息时间
+//    private Long lastFallTime;                  // 最近一次跌倒时间
+//    private Integer currentActivityLevel;       // 当前活动级别
+//    private Map<String, Long> areaRetentionTimes; // 各区域滞留时间(区域名称 -> 开始滞留时间毫秒)
+
+//    // 历史行为模式记录
+//    private final List<BehaviorPattern> behaviorHistory = new ArrayList<>();
+//
+//    // 告警历史记录
+//    private final List<Alarm> alarmHistory = new ArrayList<>();
+//
+//    // 设备最近的活动记录
+//    private final Map<String, Long> lastActivityTime = new HashMap<>();
+
+    // 每个事件类型的最后跌倒时间 (对应Python版本的last_fall_time_)
+    private final Map<String, Long> lastFallTimeByEvent = new HashMap<>();
+
+//    // 告警计划管理
+//    private Map<String, AlarmPlan> alarmPlanMap = new HashMap<>();
+//
+//    // 区域管理
+//    private List<Region> regions = new ArrayList<>();
+
+    // 完整的设备参数信息 (对应Python版本的param_)
+    private Map<String, Object> param = new HashMap<>();
+
+//    // 点云数据队列 (对应Python版本的put_cloud_points_que方法)
+//    private final Queue<List<List<Float>>> cloudPointsQueue = new LinkedList<>();
+//    private static final int MAX_CLOUD_POINTS_QUEUE_SIZE = 10; // 最大队列大小
+//
+//    private final ReentrantLock lock = new ReentrantLock();
+
+//    /**
+//     * 告警计划
+//     */
+//    private Map<String, Object> alarmSchedule;
+
+    /**
+     * 目标稳定器 - 对应Python版本的TargetStabilizer类
+     * 动态阈值调整的目标稳定算法
+     */
+//    private static class TargetStabilizer {
+//        private final java.util.Deque<List<Float>> targetList;
+//        private final float baseThreshold;
+//
+//        public TargetStabilizer(int queueLength, float baseThreshold) {
+//            this.targetList = new java.util.ArrayDeque<>(queueLength);
+//            this.baseThreshold = baseThreshold;
+//        }
+//
+//        /**
+//         * 优化目标点 (对应Python版本的optimize_target方法)
+//         * @param newTarget 新接收到的目标点 [x, y, z, snr]
+//         * @return 优化后的目标点
+//         */
+//        public List<Float> optimizeTarget(List<Float> newTarget) {
+//            if (targetList.isEmpty()) {
+//                return new ArrayList<>(newTarget);
+//            }
+//
+//            // 计算队列中点的平均值 (对应Python版本的avg_x, avg_y, avg_z计算)
+//            float avgX = 0.0f, avgY = 0.0f, avgZ = 0.0f;
+//            for (List<Float> target : targetList) {
+//                avgX += target.get(0);
+//                avgY += target.get(1);
+//                avgZ += target.get(2);
+//            }
+//            avgX /= targetList.size();
+//            avgY /= targetList.size();
+//            avgZ /= targetList.size();
+//
+//            // 动态阈值调整 (对应Python版本的dynamic_threshold计算)
+//            float dx = newTarget.get(0) - avgX;
+//            float dy = newTarget.get(1) - avgY;
+//            float distanceToAvg = (float) Math.sqrt(dx * dx + dy * dy);
+//            float dynamicThreshold = baseThreshold + (distanceToAvg * 0.3f);
+//
+//            // 如果与均值的偏差超过动态阈值,则平滑处理 (对应Python版本的平滑逻辑)
+//            if (distanceToAvg > dynamicThreshold) {
+//                float smoothedX = (newTarget.get(0) + avgX) / 2.0f;
+//                float smoothedY = (newTarget.get(1) + avgY) / 2.0f;
+//                float smoothedZ = (newTarget.get(1) + avgZ) / 2.0f;  // 保持与Python版本完全一致,包括这个bug:使用newTarget.get(1)而不是get(2)
+//
+//                List<Float> optimizedTarget = new ArrayList<>();
+//                optimizedTarget.add(smoothedX);
+//                optimizedTarget.add(smoothedY);
+//                optimizedTarget.add(smoothedZ);
+//                return optimizedTarget;
+//            } else {
+//                return new ArrayList<>(newTarget);
+//            }
+//        }
+//
+//        /**
+//         * 更新目标列表 (对应Python版本的update_target_list方法)
+//         * @param newTarget 原始目标点 [x, y, z, snr]
+//         * @return 优化后的目标点
+//         */
+//        public List<Float> updateTargetList(List<Float> newTarget) {
+//            if (newTarget.size() < 3) {
+//                // 对应Python: LOGDBG(f"update_target_list error: invlid target:{new_target}")
+//                return new ArrayList<>(newTarget);
+//            }
+//
+//            List<Float> optimizedTarget = optimizeTarget(newTarget);
+//
+//            // 如果队列已满,移除最老的目标 (对应Python的deque maxlen行为)
+//            if (targetList.size() >= 10) {  // queueLength
+//                targetList.removeFirst();
+//            }
+//            targetList.addLast(optimizedTarget);
+//
+//            return optimizedTarget;
+//        }
+//    }
+//
+//    // 目标稳定器实例 (对应Python版本device中的stabilizer)
+//    private TargetStabilizer stabilizer = new TargetStabilizer(10, 1.0f);
+
+    /**
+     * 构造函数,设置默认值
+     * @param devId 设备ID
+     */
+    public DeviceCache(String devId) {
+        this.devId = devId;
+        this.online = 0;
+        this.expireTime = 90000L; // 默认90秒
+        this.alarmAck = false;
+        this.alarmInterval = 30000L; // 默认30秒告警间隔
+        this.alarmAckInterval = 300000L; // 默认5分钟告警确认间隔
+//        this.realtimePose = new ArrayList<>();
+//        this.poseDurations = new HashMap<>();
+//        this.poseDistribution = new HashMap<>();
+//        this.areaRetentionTimes = new HashMap<>();
+//        this.alarmPlanMap = new HashMap<>();
+//        this.regions = new ArrayList<>();
+        this.debugParams = new HashMap<>();
+        
+//        // 初始化时间戳
+//        this.enterTs = -1L;
+//        this.leaveTs = -1L;
+//        this.stayTime = -1L;
+//
+//        // 初始化滞留相关参数 (参考Python版本)
+//        this.retentionTime = 60000L;     // 默认60秒
+//        this.retentionKeepTime = 30000L; // 默认30秒
+//        this.retentionAlarmTime = 180000L; // 默认180秒(3分钟)
+        
+        // 初始化跌倒状态 (对应Python版本)
+        this.falling_ = 0; // 默认无跌倒状态
+    }
+    
+    /**
+     * 安装参数 - 值对象(Value Object)
+     * 不可变对象,描述设备的安装参数。
+     */
+    @Getter
+    @Setter
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @Builder
+    public static class InstallParam {
+        private String mountPlain;       // 安装面
+        private Integer isCeiling;       // 是否天花板安装
+        private Float height;            // 安装高度
+        private TrackingRegion trackingRegion; // 跟踪区域
+        
+        /**
+         * TODO: 完善安装参数类,参考dev_mng.py中的InstallParam类
+         * 1. 添加安装面属性 (参考dev_mng.py中的mount_plain和isCeiling属性)
+         * 2. 完善跟踪区域属性 (参考dev_mng.py中的tracking_region属性)
+         */
+    }
+    
+    /**
+     * 跟踪区域 - 值对象(Value Object)
+     * 不可变对象,描述设备的跟踪区域。
+     */
+    @Getter
+    @Setter
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class TrackingRegion {
+        private Integer startX;          // 起始X
+        private Integer startY;          // 起始Y
+        private Integer startZ;          // 起始Z
+        private Integer stopX;           // 终止X
+        private Integer stopY;           // 终止Y
+        private Integer stopZ;           // 终止Z
+        
+        /**
+         * TODO: 完善跟踪区域类,参考dev_mng.py中的TrackingRegion类
+         * 1. 添加线程安全访问机制 (参考dev_mng.py中的lock_机制)
+         * 2. 完善区域属性 (参考dev_mng.py中的TrackingRegion类属性)
+         */
+    }
+    
+    /**
+     * 网络信息 - 值对象(Value Object)
+     * 不可变对象,描述设备的网络配置。
+     */
+    @Getter
+    @Setter
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @Builder
+    public static class NetworkInfo {
+        private String ssid;             // WIFI SSID
+        private String password;         // WIFI 密码
+        private String ip;               // IP地址
+        
+        /**
+         * TODO: 完善网络信息类,参考dev_mng.py中的Network类
+         * 1. 添加线程安全访问机制 (参考dev_mng.py中的lock_机制)
+         * 2. 增加更多网络属性 (参考dev_mng.py中的Network类属性)
+         */
+    }
+    
+    /**
+     * 告警实体
+     */
+    @Getter
+    @Setter
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @Builder
+    public static class Alarm {
+        private Long id;                 // 告警ID
+        private String type;             // 告警类型
+        private String description;      // 告警描述
+        private Integer severity;        // 严重程度
+        private Long timestamp;          // 时间戳
+        private Boolean acknowledged;    // 是否已确认
+        private Long acknowledgedTime;   // 确认时间
+        private Long userId;             // 确认用户ID
+        
+        /**
+         * 确认告警
+         * @param userId 用户ID
+         * @param timestamp 确认时间
+         */
+        public void acknowledge(Long userId, Long timestamp) {
+            this.acknowledged = true;
+            this.acknowledgedTime = timestamp;
+            this.userId = userId;
+        }
+    }
+    
+    /**
+     * 更新设备保活时间
+     * @param keepaliveTime 保活时间戳
+     */
+    public void updateKeepAliveTime(Long keepaliveTime) {
+        try {
+            lock.lock();
+            this.keepaliveTime = keepaliveTime;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 更新设备在线状态
+     * @param online 在线状态
+     * @return 返回旧的在线状态
+     */
+    public Integer updateOnlineStatus(Integer online) {
+        try {
+            lock.lock();
+            Integer oldStatus = this.online;
+            this.online = online;
+            return oldStatus;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 更新停留时间
+     */
+    public void updateStayTime() {
+        try {
+            lock.lock();
+            if (enterTs != null && leaveTs != null) {
+                stayTime = leaveTs - enterTs;
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 重置进入时间
+     */
+    public void resetEnterTs() {
+        try {
+            lock.lock();
+            this.enterTs = null;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 重置离开时间
+     */
+    public void resetLeaveTs() {
+        try {
+            lock.lock();
+            this.leaveTs = null;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 重置停留时间
+     */
+    public void resetStayTime() {
+        try {
+            lock.lock();
+            this.stayTime = 0L;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 检查设备是否超时
+     * @param currentTime 当前时间
+     * @return 是否超时
+     */
+    public boolean isExpired(long currentTime) {
+        if (online != null && online == 1 && keepaliveTime != null && expireTime != null) {
+            return (currentTime - keepaliveTime) > expireTime;
+        }
+        return false;
+    }
+    
+    /**
+     * 设置告警确认状态
+     * @param ack 确认状态
+     * @param timestamp 确认时间
+     */
+    public void setAlarmAcknowledgement(boolean ack, long timestamp) {
+        try {
+            lock.lock();
+            this.alarmAck = ack;
+            this.lastAlarmAckTime = timestamp;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 设置最后上报跌倒时间 (对应Python版本的set_last_report_fall_time方法)
+     * @param timestamp 时间戳
+     */
+    public void setLastReportFallTime(Long timestamp) {
+        try {
+            lock.lock();
+            this.lastReportFallTime = timestamp;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取最后上报跌倒时间 (对应Python版本的last_report_fall_time方法)
+     * @return 最后上报跌倒时间
+     */
+    public Long getLastReportFallTime() {
+        try {
+            lock.lock();
+            return lastReportFallTime != null ? lastReportFallTime : 0L;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 添加告警记录
+     * @param alarm 告警对象
+     */
+    public void addAlarm(Alarm alarm) {
+        try {
+            lock.lock();
+            alarmHistory.add(alarm);
+            lastAlarmType = alarm.getType();
+            lastAlarmTime = alarm.getTimestamp();
+            
+            // 更新最近活动时间
+            updateLastActivityTime(alarm.getType(), alarm.getTimestamp());
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 添加行为模式
+     * @param pattern 行为模式
+     */
+    public void addBehaviorPattern(BehaviorPattern pattern) {
+        try {
+            lock.lock();
+            behaviorHistory.add(pattern);
+            
+            // 如果是异常行为,更新相关状态
+            if (pattern.getBehaviorType() != null && 
+                    pattern.getBehaviorType() == 3) { // 3表示异常行为
+                
+                // 更新最近活动时间
+                updateLastActivityTime(pattern.getDescription(), pattern.getTimestamp());
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 更新最近活动时间
+     * @param activityType 活动类型
+     * @param timestamp 时间戳
+     */
+    private void updateLastActivityTime(String activityType, Long timestamp) {
+        if (activityType != null && timestamp != null) {
+            lastActivityTime.put(activityType, timestamp);
+        }
+    }
+    
+    /**
+     * 确认告警
+     * @param alarmId 告警ID
+     * @param userId 用户ID
+     * @param timestamp 确认时间
+     * @return 是否成功确认
+     */
+    public boolean acknowledgeAlarm(Long alarmId, Long userId, Long timestamp) {
+        try {
+            lock.lock();
+            for (Alarm alarm : alarmHistory) {
+                if (alarm.getId() != null && alarm.getId().equals(alarmId)) {
+                    alarm.acknowledge(userId, timestamp);
+                    return true;
+                }
+            }
+            return false;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取未确认的告警
+     * @return 未确认的告警列表
+     */
+    public List<Alarm> getUnacknowledgedAlarms() {
+        try {
+            lock.lock();
+            List<Alarm> unacknowledgedAlarms = new ArrayList<>();
+            for (Alarm alarm : alarmHistory) {
+                if (alarm.getAcknowledged() == null || !alarm.getAcknowledged()) {
+                    unacknowledgedAlarms.add(alarm);
+                }
+            }
+            return unacknowledgedAlarms;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 检查是否应该发送告警
+     * @param alarmType 告警类型
+     * @param timestamp 当前时间戳
+     * @param intervalThreshold 告警间隔阈值(毫秒)
+     * @return 是否应该发送告警
+     */
+    public boolean shouldSendAlarm(String alarmType, Long timestamp, Long intervalThreshold) {
+        try {
+            lock.lock();
+            
+            // 如果没有最近活动记录,应该发送告警
+            if (!lastActivityTime.containsKey(alarmType)) {
+                return true;
+            }
+            
+            // 获取上次该类型告警的时间
+            Long lastTime = lastActivityTime.get(alarmType);
+            if (lastTime == null) {
+                return true;
+            }
+            
+            // 检查告警间隔是否超过阈值
+            return (timestamp - lastTime) > intervalThreshold;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 检查设备是否存在持续滞留
+     * @param currentTime 当前时间
+     * @param areaName 区域名称
+     * @param retentionThreshold 滞留阈值(毫秒)
+     * @return 是否滞留
+     */
+    public boolean checkRetention(Long currentTime, String areaName, Long retentionThreshold) {
+        if (enterTs == null || currentTime == null) {
+            return false;
+        }
+        
+        long stayDuration = currentTime - enterTs;
+        
+        // 如果滞留时间超过阈值且未发送过滞留告警,则需要发送告警
+        if (stayDuration > retentionThreshold) {
+            // 如果没有发送过滞留告警或者距离上次告警时间已经超过阈值
+            if (retentionAlarmTime == null || (currentTime - retentionAlarmTime) > retentionThreshold) {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+    
+    /**
+     * 更新设备姿态
+     * 
+     * @param pose 姿态
+     * @param timestamp 时间戳
+     */
+    public void updatePose(Integer pose, Long timestamp) {
+        try {
+            lock.lock();
+            
+            // 检查姿态是否变化
+            boolean poseChanged = false;
+            if (realtimePose == null) {
+                realtimePose = new ArrayList<>();
+            }
+            
+            if (realtimePose.isEmpty() || !pose.equals(realtimePose.get(0))) {
+                poseChanged = true;
+            }
+            
+            // 添加新姿态到列表开头
+            realtimePose.add(0, pose);
+            
+            // 保持列表长度不超过10
+            if (realtimePose.size() > 10) {
+                realtimePose.remove(realtimePose.size() - 1);
+            }
+            
+            // 如果姿态发生变化,更新姿态变化时间
+            if (poseChanged) {
+                lastPoseChangeTime = timestamp;
+                
+                // 更新姿态持续时间
+                updatePoseDuration(pose, timestamp);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 更新姿态持续时间
+     * 
+     * @param pose 姿态
+     * @param timestamp 当前时间戳
+     */
+    private void updatePoseDuration(Integer pose, Long timestamp) {
+        if (poseDurations == null) {
+            poseDurations = new HashMap<>();
+        }
+        
+        // 初始化姿态持续时间
+        if (!poseDurations.containsKey(pose)) {
+            poseDurations.put(pose, 0L);
+        }
+    }
+    
+    /**
+     * 更新区域滞留时间
+     * 
+     * @param areaName 区域名称
+     * @param timestamp 时间戳
+     */
+    public void updateAreaRetentionTime(String areaName, Long timestamp) {
+        try {
+            lock.lock();
+            
+            if (areaRetentionTimes == null) {
+                areaRetentionTimes = new HashMap<>();
+            }
+            
+            // 记录区域滞留开始时间
+            if (!areaRetentionTimes.containsKey(areaName)) {
+                areaRetentionTimes.put(areaName, timestamp);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 重置区域滞留时间
+     * 
+     * @param areaName 区域名称
+     */
+    public void resetAreaRetentionTime(String areaName) {
+        try {
+            lock.lock();
+            
+            if (areaRetentionTimes != null && areaRetentionTimes.containsKey(areaName)) {
+                areaRetentionTimes.remove(areaName);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取区域滞留时间
+     * 
+     * @param areaName 区域名称
+     * @param currentTime 当前时间
+     * @return 滞留时间(毫秒)
+     */
+    public Long getAreaRetentionDuration(String areaName, Long currentTime) {
+        try {
+            lock.lock();
+            
+            if (areaRetentionTimes == null || !areaRetentionTimes.containsKey(areaName)) {
+                return 0L;
+            }
+            
+            Long startTime = areaRetentionTimes.get(areaName);
+            if (startTime == null) {
+                return 0L;
+            }
+            
+            return currentTime - startTime;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 添加告警计划
+     * 
+     * @param alarmPlan 告警计划
+     */
+    public void addAlarmPlan(AlarmPlan alarmPlan) {
+        try {
+            lock.lock();
+            
+            if (alarmPlan != null && alarmPlan.getName() != null) {
+                alarmPlanMap.put(alarmPlan.getName(), alarmPlan);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 移除告警计划
+     * 
+     * @param planName 计划名称
+     * @return 被移除的告警计划
+     */
+    public AlarmPlan removeAlarmPlan(String planName) {
+        try {
+            lock.lock();
+            
+            return alarmPlanMap.remove(planName);
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取告警计划
+     * 
+     * @param planName 计划名称
+     * @return 告警计划
+     */
+    public AlarmPlan getAlarmPlan(String planName) {
+        try {
+            lock.lock();
+            
+            return alarmPlanMap.get(planName);
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取所有告警计划
+     * 
+     * @return 告警计划列表
+     */
+    public List<AlarmPlan> getAllAlarmPlans() {
+        try {
+            lock.lock();
+            
+            return new ArrayList<>(alarmPlanMap.values());
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 更新告警计划目标
+     * 
+     * @param targets 目标点列表
+     */
+    public void updateAlarmTargets(List<List<Float>> targets) {
+        if (targets == null || targets.isEmpty()) {
+            return;
+        }
+        
+        try {
+            lock.lock();
+            
+            long currentTime = System.currentTimeMillis();
+            
+            // 更新所有告警计划的目标
+            if (CollectionUtils.isEmpty(alarmPlanMap)) {
+                return;
+            }
+            for (AlarmPlan plan : alarmPlanMap.values()) {
+                plan.updateTarget(targets, currentTime);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 检查所有告警计划
+     * 
+     * @return 需要触发告警的计划列表
+     */
+    public List<AlarmPlan> checkAlarmPlans() {
+        try {
+            lock.lock();
+            
+            List<AlarmPlan> alarmedPlans = new ArrayList<>();
+            long currentTime = System.currentTimeMillis();
+            
+            // 检查所有告警计划
+            for (AlarmPlan plan : alarmPlanMap.values()) {
+                if (plan.checkRetention(currentTime)) {
+                    alarmedPlans.add(plan);
+                }
+            }
+            
+            return alarmedPlans;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 添加区域
+     * 
+     * @param region 区域
+     */
+    public void addRegion(Region region) {
+        try {
+            lock.lock();
+            
+            if (region != null) {
+                // 检查是否已存在相同ID的区域
+                for (int i = 0; i < regions.size(); i++) {
+                    if (regions.get(i).getId().equals(region.getId())) {
+                        // 更新现有区域
+                        regions.set(i, region);
+                        return;
+                    }
+                }
+                
+                // 添加新区域
+                regions.add(region);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 移除区域
+     * 
+     * @param regionId 区域ID
+     * @return 是否成功移除
+     */
+    public boolean removeRegion(String regionId) {
+        try {
+            lock.lock();
+            
+            for (int i = 0; i < regions.size(); i++) {
+                if (regions.get(i).getId().equals(regionId)) {
+                    regions.remove(i);
+                    return true;
+                }
+            }
+            
+            return false;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取区域
+     * 
+     * @param regionId 区域ID
+     * @return 区域
+     */
+    public Region getRegion(String regionId) {
+        try {
+            lock.lock();
+            
+            for (Region region : regions) {
+                if (region.getId().equals(regionId)) {
+                    return region;
+                }
+            }
+            
+            return null;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取所有区域
+     * 
+     * @return 区域列表
+     */
+    public List<Region> getAllRegions() {
+        try {
+            lock.lock();
+            
+            return new ArrayList<>(regions);
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 查找包含指定点的区域
+     * 
+     * @param x 点的x坐标
+     * @param y 点的y坐标
+     * @return 包含该点的区域列表
+     */
+    public List<Region> findRegionsContainingPoint(float x, float y) {
+        try {
+            lock.lock();
+            
+            List<Region> result = new ArrayList<>();
+            
+            for (Region region : regions) {
+                if (region.containsPoint(x, y)) {
+                    result.add(region);
+                }
+            }
+            
+            return result;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 更新告警配置
+     *
+     * @param retentionTime 停留时间阈值(毫秒)
+     * @param retentionKeepTime 停留保持时间(毫秒)
+     * @param retentionAlarmTime 停留告警时间(毫秒)
+     */
+    public void updateAlarmConfig(long retentionTime, long retentionKeepTime, long retentionAlarmTime) {
+        try {
+            lock.lock();
+            this.retentionTime = retentionTime;
+            this.retentionKeepTime = retentionKeepTime;
+            this.retentionAlarmTime = retentionAlarmTime;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 检查是否应该发送跌倒告警 (参考Python版本的deal_report_falling_event逻辑)
+     * @param currentTime 当前时间
+     * @return true如果应该发送告警
+     */
+    public boolean shouldSendFallAlarm(long currentTime) {
+        try {
+            lock.lock();
+            // 检查告警确认状态
+            if (Boolean.TRUE.equals(alarmAck)) {
+                return false;
+            }
+            
+            // 检查告警间隔
+            if (lastReportFallTime != null) {
+                long timeSinceLastAlarm = currentTime - lastReportFallTime;
+                if (timeSinceLastAlarm < alarmInterval) {
+                    return false;
+                }
+            }
+            
+            return true;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 检查心跳是否被调试参数拒绝 (参考Python版本的deal_dev_keepalive逻辑)
+     * @return true如果应该拒绝心跳
+     */
+    public boolean shouldRejectKeepAlive() {
+        try {
+            lock.lock();
+            Object keepaliveDebug = debugParams.get("keepalive");
+            return keepaliveDebug != null && Integer.valueOf(0).equals(keepaliveDebug);
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 设置设备参数信息
+     * 对应Python版本的set_param(self, param)方法
+     * @param param 完整的设备参数信息
+     */
+    public void setParam(Map<String, Object> param) {
+        try {
+            lock.lock();
+            this.param = param;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取设备参数信息
+     * 对应Python版本的param(self)方法
+     * @return 完整的设备参数信息
+     */
+    public Map<String, Object> getParam() {
+        try {
+            lock.lock();
+            return param;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 设置调试参数
+     * @param key 参数键
+     * @param value 参数值
+     */
+    public void setDebugParam(String key, Object value) {
+        try {
+            lock.lock();
+            debugParams.put(key, value);
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取调试参数
+     * @param key 参数键
+     * @return 参数值
+     */
+    public Object getDebugParam(String key) {
+        try {
+            lock.lock();
+            return debugParams.get(key);
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 检查停留时间并处理滞留告警 (参考Python版本的check_stay_time逻辑)
+     * @param currentTime 当前时间
+     * @return 如果检测到滞留事件返回滞留记录,否则返回null
+     */
+    public StayTimeRecord checkStayTime(long currentTime) {
+        try {
+            lock.lock();
+            
+            if (enterTs == null || enterTs == -1 || leaveTs == null || leaveTs == -1) {
+                return null;
+            }
+            
+            // 保留时间内,不认为停留事件结束
+            long timeSinceLeave = currentTime - leaveTs;
+            if (timeSinceLeave <= retentionKeepTime) {
+                return null;
+            }
+            
+            // 时间少于最小时间尺,忽略本次事件,并重置计时
+            long stayTimeMs = leaveTs - enterTs;
+            if (stayTimeMs < retentionTime) {
+                // 重置计时
+                this.enterTs = -1L;
+                this.leaveTs = -1L;
+                this.stayTime = -1L;
+                return null;
+            }
+            
+            // 创建停留时间记录
+            StayTimeRecord record = new StayTimeRecord();
+            record.setDevId(devId);
+            record.setEnterTime(enterTs);
+            record.setLeaveTime(leaveTs);
+            record.setStayTime(stayTimeMs);
+            
+            // 检查是否需要创建滞留告警 (超过3分钟视为异常滞留)
+            long stayTimeSeconds = stayTimeMs / 1000;
+            if (stayTimeSeconds >= (retentionAlarmTime / 1000)) {
+                record.setNeedAlarm(true);
+                record.setAlarmType("alarm_retention");
+                record.setAlarmDescription("设备滞留时间过长");
+            }
+            
+            // 重置计时
+            this.enterTs = -1L;
+            this.leaveTs = -1L;
+            this.stayTime = -1L;
+            
+            return record;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 检查告警确认是否超时 (参考Python版本的check_dev_alarm_ack逻辑)
+     * @param currentTime 当前时间
+     * @return true如果告警确认超时需要清除
+     */
+    public boolean shouldClearAlarmAck(long currentTime) {
+        try {
+            lock.lock();
+            if (Boolean.TRUE.equals(alarmAck) && lastAlarmAckTime != null) {
+                long timeSinceAck = currentTime - lastAlarmAckTime;
+                return timeSinceAck > alarmAckInterval;
+            }
+            return false;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 清除告警确认状态
+     */
+    public void clearAlarmAck() {
+        try {
+            lock.lock();
+            this.alarmAck = false;
+            this.lastAlarmAckTime = null;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+         /**
+      * 更新实时位置(平滑算法) - 重写以对应Python版本的update_targets方法
+      * @param newTargets 新的目标位置列表
+      * @return 稳定的目标位置列表
+      */
+     public List<List<Float>> updateTargets(List<List<Float>> newTargets) {
+        try {
+            lock.lock();
+            
+            // 对应Python版本的输入验证
+            if (newTargets == null || newTargets.isEmpty() || 
+                newTargets.get(0).size() < 3) {
+                // 对应Python: LOGERR(f"update_targets error: invalid new_targets")
+                return new ArrayList<>();
+            }
+            
+            // 对应Python: new_target = new_targets[0]
+            List<Float> newTarget = newTargets.get(0);
+            
+            // 对应Python: stable_target = self.stabilizer.update_target_list(new_target)
+            List<Float> stableTarget = stabilizer.updateTargetList(newTarget);
+            
+            // 更新targets字段
+            this.targets = stableTarget;
+            
+            // 对应Python: return [stable_target]
+            List<List<Float>> result = new ArrayList<>();
+            result.add(stableTarget);
+            return result;
+            
+        } catch (Exception e) {
+            // 对应Python: except Exception as e: LOGERR(f"update_targets error: {e}")
+            return new ArrayList<>();
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取实时姿态 (对应Python版本的realtime_pose方法)
+     * @return 实时姿态列表
+     */
+    public List<Integer> getRealtimePose() {
+        try {
+            lock.lock();
+            return realtimePose != null ? new ArrayList<>(realtimePose) : new ArrayList<>();
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 设置实时姿态 (对应Python版本的set_realtime_pose方法)
+     * @param pose 姿态列表
+     */
+    public void setRealtimePose(List<Integer> pose) {
+        try {
+            lock.lock();
+            this.realtimePose = pose != null ? new ArrayList<>(pose) : new ArrayList<>();
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取进入时间 (对应Python版本的enter_ts方法)
+     * @return 进入时间戳,如果未设置返回-1
+     */
+    public Long getEnterTime() {
+        try {
+            lock.lock();
+            return enterTs != null ? enterTs : -1L;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 设置进入时间 (对应Python版本的set_enter_ts方法)
+     * @param timestamp 时间戳
+     */
+    public void setEnterTime(Long timestamp) {
+        try {
+            lock.lock();
+            this.enterTs = timestamp;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取离开时间 (对应Python版本的leave_ts方法)
+     * @return 离开时间戳,如果未设置返回-1
+     */
+    public Long getLeaveTime() {
+        try {
+            lock.lock();
+            return leaveTs != null ? leaveTs : -1L;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 设置离开时间 (对应Python版本的set_leave_ts方法)
+     * @param timestamp 时间戳
+     */
+    public void setLeaveTime(Long timestamp) {
+        try {
+            lock.lock();
+            this.leaveTs = timestamp;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 检查告警间隔 (对应Python版本的告警间隔检查逻辑)
+     * @param eventType 事件类型
+     * @param currentTime 当前时间
+     * @return 是否应该发送告警
+     */
+    public boolean shouldSendAlarmForEvent(String eventType, Long currentTime) {
+        try {
+            lock.lock();
+            // 如果已经确认告警,则不发送
+            if (Boolean.TRUE.equals(alarmAck)) {
+                return false;
+            }
+            
+            // 检查告警间隔 (对应Python: now - device.last_fall_time(event) < device.alarm_interval())
+            Long lastEventTime = lastFallTimeByEvent.get(eventType);
+            if (lastEventTime != null && currentTime != null) {
+                long timeSinceLastAlarm = currentTime - lastEventTime;
+                return timeSinceLastAlarm >= (alarmInterval != null ? alarmInterval : 30000L); // 默认30秒间隔
+            }
+            
+            return true;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 设置最后跌倒时间 (对应Python版本的set_last_fall_time方法)
+     * @param eventType 事件类型
+     * @param timestamp 时间戳
+     */
+    public void setLastFallTime(String eventType, Long timestamp) {
+        try {
+            lock.lock();
+            this.lastReportFallTime = timestamp;
+            // 为每个事件类型单独记录时间 (对应Python版本的last_fall_time_[event] = time)
+            lastFallTimeByEvent.put(eventType, timestamp);
+            lastActivityTime.put("fall_" + eventType, timestamp);
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取指定事件类型的最后跌倒时间 (对应Python版本的last_fall_time(event))
+     * @param eventType 事件类型
+     * @return 最后跌倒时间,如果没有记录返回0
+     */
+    public Long getLastFallTime(String eventType) {
+        try {
+            lock.lock();
+            return lastFallTimeByEvent.getOrDefault(eventType, 0L);
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取当前跌倒状态 (对应Python版本的device.falling_)
+     * @return 跌倒状态:0-无跌倒,1-检测到跌倒,2-跌倒确认,3-跌倒呼救
+     */
+    public Integer getFalling() {
+        try {
+            lock.lock();
+            return falling_ != null ? falling_ : 0;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 设置当前跌倒状态 (对应Python版本的device.falling_)
+     * @param falling 跌倒状态:0-无跌倒,1-检测到跌倒,2-跌倒确认,3-跌倒呼救
+     */
+    public void setFalling(Integer falling) {
+        try {
+            lock.lock();
+            this.falling_ = falling;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 检查LNA设备的告警间隔 (对应Python版本的LNA特殊逻辑)
+     * 
+     * Python真实逻辑:
+     * - device.falling_字段永远为0(从不更新)
+     * - 当falling==0(无跌倒)时:falling_ == falling为true,检查报警间隔
+     * - 当falling!=0(有跌倒)时:falling_ == falling为false,跳过报警间隔检查,立即发送
+     * - 简化理解:只有无跌倒状态才检查报警间隔,任何跌倒状态都立即发送
+     * 
+     * @param newFalling 新的跌倒状态
+     * @param currentTime 当前时间
+     * @return 是否应该发送告警
+     */
+    public boolean shouldSendAlarmForLNA(Integer newFalling, Long currentTime) {
+        try {
+            lock.lock();
+            // 如果已经确认告警,则不发送
+            if (Boolean.TRUE.equals(alarmAck)) {
+                return false;
+            }
+            
+            // 对应Python逻辑:if device.falling_ == falling
+            // 由于falling_永远为0,所以只有当newFalling==0时才检查报警间隔
+            if (Objects.equals(falling_, newFalling)) {
+                // 检查报警间隔(使用lastReportFallTime,对应Python: device.last_report_fall_time())
+                if (lastReportFallTime != null && currentTime != null) {
+                    long timeSinceLastAlarm = currentTime - lastReportFallTime;
+                    return timeSinceLastAlarm >= (alarmInterval != null ? alarmInterval : 30000L);
+                }
+            }
+            
+            // 当falling_不等于newFalling时(即newFalling!=0时),或者没有历史时间时,直接发送
+            return true;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 根据设备类型处理跌倒事件 (参考Python版本的设备类型区分逻辑)
+     * @param event 事件类型
+     * @param pose 姿态
+     * @param location 位置坐标
+     * @return 处理结果
+     */
+    public FallEventResult processFallEvent(String event, int pose, List<Float> location) {
+        try {
+            lock.lock();
+            FallEventResult result = new FallEventResult();
+            result.setDevId(devId);
+            result.setEvent(event);
+            
+            if ("LNB".equals(devType)) {
+                // LNB设备的处理逻辑 (参考Python版本)
+                result.setPose("no_fall".equals(event) ? 4 : 0); // POSE_4 或 POSE_0
+                // 转换位置坐标格式 (参考Python版本的targets格式)
+                if (location != null && location.size() >= 3) {
+                    float[] targetPoint = {location.get(0)/100f, location.get(1)/100f, location.get(2)/100f};
+                    result.setLocation(targetPoint);
+                }
+                result.setShouldProcess(true);
+            } else if ("LNA".equals(devType)) {
+                // LNA设备的处理逻辑 (参考Python版本)
+                if (realtimePose == null || realtimePose.isEmpty() || !Integer.valueOf(0).equals(realtimePose.get(0))) {
+                    result.setShouldProcess(false);
+                    return result;
+                }
+                result.setPose(realtimePose.get(0));
+                // 转换位置坐标格式
+                if (location != null && location.size() >= 3) {
+                    float[] targetPoint = {location.get(0)/100f, location.get(1)/100f, location.get(2)/100f};
+                    result.setLocation(targetPoint);
+                }
+                result.setShouldProcess(true);
+            } else {
+                result.setShouldProcess(false);
+            }
+            
+            return result;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 放入点云数据到队列 (对应Python版本的put_cloud_points_que方法)
+     * @param cloudPoints 点云数据
+     */
+    public void putCloudPointsQueue(List<List<Float>> cloudPoints) {
+        try {
+            lock.lock();
+            if (cloudPoints != null && !cloudPoints.isEmpty()) {
+                // 如果队列已满,移除最老的数据
+                while (cloudPointsQueue.size() >= MAX_CLOUD_POINTS_QUEUE_SIZE) {
+                    cloudPointsQueue.poll();
+                }
+                cloudPointsQueue.offer(new ArrayList<>(cloudPoints));
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取点云数据队列 (用于调试和分析)
+     * @return 点云数据队列的副本
+     */
+    public List<List<List<Float>>> getCloudPointsQueue() {
+        try {
+            lock.lock();
+            return new ArrayList<>(cloudPointsQueue);
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 清空点云数据队列
+     */
+    public void clearCloudPointsQueue() {
+        try {
+            lock.lock();
+            cloudPointsQueue.clear();
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 检查跌倒告警间隔 (对应Python版本的告警间隔检查逻辑)
+     * @param currentTime 当前时间
+     * @return true如果可以发送跌倒告警
+     */
+    public boolean checkFallAlarmInterval(Long currentTime) {
+        try {
+            lock.lock();
+            // 检查告警确认状态 (对应Python: device.get_alarm_ack())
+            if (Boolean.TRUE.equals(alarmAck)) {
+                return false;
+            }
+            
+            // 检查告警间隔 (对应Python: now - device.last_report_fall_time() < device.alarm_interval())
+            if (lastReportFallTime != null && currentTime != null) {
+                long timeSinceLastFall = currentTime - lastReportFallTime;
+                return timeSinceLastFall >= (alarmInterval != null ? alarmInterval : 30000L); // 默认30秒间隔
+            }
+            
+            return true; // 第一次跌倒或时间信息不完整时允许发送
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 设置调试参数集合 (对应应用层的setDebugParams需求)
+     * @param debugParams 调试参数集合
+     */
+    public void setDebugParams(Map<String, Object> debugParams) {
+        try {
+            lock.lock();
+            if (debugParams != null) {
+                this.debugParams.clear();
+                this.debugParams.putAll(debugParams);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
+     * 获取调试参数集合 (对应应用层的getDebugParams需求)
+     * @return 调试参数集合
+     */
+    public Map<String, Object> getDebugParams() {
+        try {
+            lock.lock();
+            return new HashMap<>(debugParams); // 返回副本确保线程安全
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * 停留时间记录
+     */
+    @Getter
+    @Setter
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class StayTimeRecord {
+        private String devId;
+        private Long enterTime;
+        private Long leaveTime;
+        private Long stayTime;
+        private boolean needAlarm;
+        private String alarmType;
+        private String alarmDescription;
+    }
+    
+    /**
+     * 跌倒事件处理结果
+     */
+    @Getter
+    @Setter
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class FallEventResult {
+        private String devId;
+        private String event;
+        private Integer pose;
+        private Object location;  // 修改为Object类型,匹配MqttGateway接口
+        private boolean shouldProcess;
+    }
+
+    /**
+     * 获取数据量最多的一组点云数据,然后清空cloud_points_que_ 
+     * (对应Python版本的get_max_len_cloud_points方法)
+     * @return 数据量最多的点云list,失败返回null
+     */
+    public List<List<Float>> getMaxLenCloudPoints() {
+        try {
+            lock.lock();
+            
+            // 对应Python: if self.dev_type_ == "LNB": return None
+            if ("LNB".equals(devType)) {
+                return null;
+            }
+            
+            // 对应Python: 取出数据量最多的的点云,成功返回点云list,失败返回None
+            int maxLen = 0;
+            List<List<Float>> maxLenList = null;
+            
+            // 对应Python: while not self.cloud_points_que_.empty():
+            while (!cloudPointsQueue.isEmpty()) {
+                List<List<Float>> currentList = cloudPointsQueue.poll();
+                // 对应Python: if len(current_list) >= max_len:
+                if (currentList != null && currentList.size() >= maxLen) {
+                    maxLen = currentList.size();
+                    maxLenList = currentList;
+                }
+            }
+            
+            return maxLenList;
+        } finally {
+            lock.unlock();
+        }
+    }
+} 

+ 265 - 0
device-service-domain/src/main/java/com/hfln/device/domain/service/impl/DeviceRedisManagerServiceImpl.java

@@ -0,0 +1,265 @@
+package com.hfln.device.domain.service.impl;
+
+import cn.hfln.framework.common.redis.service.RedisService;
+import com.hfln.device.common.constant.redis.RedisCacheConstant;
+import com.hfln.device.domain.constant.DeviceConstants;
+import com.hfln.device.domain.entity.Device;
+import com.hfln.device.domain.entity.DeviceCache;
+import com.hfln.device.domain.service.DeviceManagerService;
+import com.hfln.device.domain.service.DeviceStatusService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 设备管理服务实现类
+ * 负责设备状态管理、保活检查等功能
+ */
+@Slf4j
+@Service
+public class DeviceRedisManagerServiceImpl implements DeviceManagerService {
+
+    /**
+     * 设备缓存,用于保存所有在线设备信息
+     */
+    private final Map<String, Device> deviceCache = new ConcurrentHashMap<>();
+
+    @Autowired
+    private DeviceStatusService deviceStatusService;
+
+    @Autowired
+    private RedisService redisService;
+
+
+    public Optional<Device> xx(String devId) {
+
+
+
+        return Optional.ofNullable(deviceCache.get(devId));
+    }
+
+
+    @Override
+    public Optional<Device> getDeviceFromCache(String devId) {
+        return Optional.ofNullable(deviceCache.get(devId));
+    }
+
+    /**
+     * 将设备添加到缓存
+     * 
+     * @param device 设备信息
+     */
+    public void addDeviceToCache(Device device) {
+//        deviceCache.put(device.getDevId(), device);
+
+        // 设置redis 存储设备的 hash对象的属性
+        Map<String, Object> deviceMap = new HashMap<>();
+
+        // 设置设备属性
+        deviceMap.put("devId", device.getDevId());
+        deviceMap.put("devType", device.getDevType());
+        deviceMap.put("software", device.getSoftware());
+        deviceMap.put("hardware", device.getHardware());
+        deviceMap.put("bluVer", device.getBluVer());
+        deviceMap.put("online", device.getOnline());
+
+        // 添加网络信息
+        if (device.getNetwork() != null) {
+            deviceMap.put("ssid", device.getNetwork().getSsid());
+            deviceMap.put("ip", device.getNetwork().getIp());
+            deviceMap.put("password", device.getNetwork().getPassword());
+        }
+
+        // 添加安装参数
+        if (device.getInstallParam() != null) {
+            deviceMap.put("mountPlain", device.getInstallParam().getMountPlain());
+            deviceMap.put("isCeiling", device.getInstallParam().getIsCeiling());
+            deviceMap.put("height", device.getInstallParam().getHeight());
+
+            // 添加跟踪区域
+            if (device.getInstallParam().getTrackingRegion() != null) {
+                deviceMap.put("startX", device.getInstallParam().getTrackingRegion().getStartX());
+                deviceMap.put("startY", device.getInstallParam().getTrackingRegion().getStartY());
+                deviceMap.put("startZ", device.getInstallParam().getTrackingRegion().getStartZ());
+                deviceMap.put("stopX", device.getInstallParam().getTrackingRegion().getStopX());
+                deviceMap.put("stopY", device.getInstallParam().getTrackingRegion().getStopY());
+                deviceMap.put("stopZ", device.getInstallParam().getTrackingRegion().getStopZ());
+            }
+        }
+
+        // 实时点位
+        // List<Float> targets = new ArrayList<>();
+        // String targetsStr = JsonUtil.toJson(targets);
+//        deviceMap.put("targets", targetsStr);
+
+        // 在线状态
+        deviceMap.put("online", device.getOnline());
+        // 最后心跳时间戳
+        deviceMap.put("keepAliveTime", device.getKeepaliveTime());
+        // 超时时间 默认90秒
+        deviceMap.put("expireTime", device.getExpireTime());
+
+        // 跌倒信息
+        // 最后上报跌倒时间
+        deviceMap.put("lastReportFallTime", device.getLastReportFallTime());
+        // 告警时间间隔(毫秒),默认30秒
+        deviceMap.put("alarmInterval", device.getAlarmInterval());
+        // 告警确认
+        deviceMap.put("alarmAck", device.getAlarmAck());
+        // 最后告警确认时间
+        deviceMap.put("lastAlarmAckTime", device.getLastAlarmAckTime());
+        // 告警确认时间间间隔(毫秒),默认5分钟
+        deviceMap.put("alarmAckInterval", device.getAlarmAckInterval());
+        // 最后上报跌倒信息 跌倒状态
+        deviceMap.put("falling", device.getFalling());
+
+        // 设备调试参数
+//        deviceMap.put(RedisCacheConstant.KEY_DEVICE_DEBUG_PARAM_PRE + "", device.getDebugParam(""));
+
+
+        redisService.setNx(RedisCacheConstant.KEY_DEVICE + device.getDevId(), device);
+        redisService.setCacheMap(RedisCacheConstant.KEY_DEVICE + device.getDevId(), deviceMap);
+        log.info("Device added to cache: {}", device.getDevId());
+    }
+
+    @Override
+    public void updateDeviceInCache(Device device) {
+        deviceCache.put(device.getDevId(), device);
+        log.debug("Device updated in cache: {}", device.getDevId());
+    }
+
+    @Override
+    public void removeDeviceFromCache(String devId) {
+
+        redisService.deleteObject(RedisCacheConstant.KEY_DEVICE + devId);
+        log.info("Device removed from cache: {}", devId);
+    }
+
+    @Override
+    public void checkDeviceKeepAlive(long currentTimeMillis, long timeoutMillis) {
+        deviceCache.forEach((devId, device) -> {
+            // 只检查在线设备
+            if (device.getOnline() != null && device.getOnline() == 1) {
+                Long lastKeepAliveTime = device.getKeepaliveTime();
+                
+                // 如果设备无保活时间或超时,则设置为离线
+                if (lastKeepAliveTime == null || (currentTimeMillis - lastKeepAliveTime) > timeoutMillis) {
+                    log.info("Device keepalive timeout: {}, last keepalive: {}", devId, lastKeepAliveTime);
+                    deviceStatusService.handleDeviceOffline(device);
+                }
+            }
+        });
+    }
+
+    /**
+     * 检查设备告警确认状态
+     * 如果设备告警状态长时间未确认,可以执行特定的业务逻辑
+     * 
+     * @param currentTimeMillis 当前时间戳
+     * @param timeoutMillis 超时时间(毫秒)
+     */
+    @Override
+    public void checkDeviceAlarmAck(long currentTimeMillis, long timeoutMillis) {
+        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);
+                    
+                    // 更新数据库中的告警确认状态
+                    // 这里应该调用相应的网关方法
+                }
+            }
+        });
+    }
+
+    /**
+     * 检查所有设备的停留时间
+     * 根据设备报告的进入和离开时间计算停留时间
+     */
+    @Override
+    public void checkAllDeviceStayTime() {
+        deviceCache.forEach((devId, device) -> {
+            checkDeviceStayTime(device);
+        });
+    }
+
+    /**
+     * 检查单个设备的停留时间
+     * 
+     * @param device 设备信息
+     */
+    private void checkDeviceStayTime(Device device) {
+        try {
+            // 如果有进入时间和离开时间,计算停留时间
+            if (device.getEnterTs() != null && device.getLeaveTs() != null) {
+                device.updateStayTime();
+                // 这里可以增加业务逻辑,例如记录停留时间到数据库
+                log.debug("Device stay time updated: {}, stay time: {}", 
+                        device.getDevId(), device.getStayTime());
+            }
+        } catch (Exception e) {
+            log.error("Error checking device stay time: {}", device.getDevId(), e);
+        }
+    }
+
+    /**
+     * 检查所有设备的告警计划
+     * 可以根据设备的各种状态触发不同类型的告警
+     */
+    @Override
+    public void checkAllDeviceAlarmPlan() {
+        deviceCache.forEach((devId, device) -> {
+            checkDeviceRetention(device);
+        });
+    }
+
+    /**
+     * 检查设备的滞留状态
+     * 
+     * @param device 设备信息
+     */
+    private void checkDeviceRetention(Device device) {
+        try {
+            // 滞留检测逻辑
+            Long retentionTime = device.getRetentionTime();
+            if (retentionTime != null) {
+                long currentTime = System.currentTimeMillis();
+                long retentionKeepTime = device.getRetentionKeepTime() != null ? 
+                        device.getRetentionKeepTime() : 
+                        DeviceConstants.AlarmConfig.DEFAULT_RETENTION_KEEP_TIME * 1000L;
+                
+                if (currentTime - retentionTime > retentionKeepTime) {
+                    // 滞留时间超过阈值,触发告警
+                    log.warn("Device retention time exceeded threshold: {}", device.getDevId());
+                    // 这里可以增加告警逻辑
+                }
+            }
+        } catch (Exception e) {
+            log.error("Error checking device retention: {}", device.getDevId(), e);
+        }
+    }
+
+    @Override
+    public Collection<Device> getAllDevicesFromCache() {
+        return deviceCache.values();
+    }
+
+    @Override
+    public void checkDevicesTimeout() {
+        long currentTimeMillis = System.currentTimeMillis();
+        long timeoutMillis = 90000L; // 默认90秒超时
+        checkDeviceKeepAlive(currentTimeMillis, timeoutMillis);
+    }
+}