Explorar o código

device redis缓存 改写

chejianzheng hai 3 meses
pai
achega
febb36e16c

+ 24 - 16
device-service-application/src/main/java/com/hfln/device/application/service/impl/DeviceEventServiceImpl.java

@@ -239,6 +239,8 @@ public class DeviceEventServiceImpl implements DeviceEventService {
                 Device device = deviceOpt.get();
                 
                 if (device.getOnline() == 1) {
+
+                    deviceManagerService.updateDeviceKeepAliveInCache(deviceId, System.currentTimeMillis());
                     // 重复上线 (对应Python: 重复上线)
                     mqttGateway.sendDeviceLoginResponseMessage(deviceId, DeviceConstants.DeviceErrorCode.SUCCEED.getCode());
                     log.info("设备重复登录: deviceId={}", deviceId);
@@ -250,12 +252,10 @@ public class DeviceEventServiceImpl implements DeviceEventService {
                     
                     // 更新设备缓存
 //                    deviceManagerService.updateDeviceInCache(device);
+                    deviceManagerService.updateDeviceAliveStatusInCache(device.getDevId());
 
-                    Map<String, Object> updateDeviceMap = new HashMap<>();
-                    updateDeviceMap.put("online", 1);
-                    updateDeviceMap.put("keepAliveTime", System.currentTimeMillis());
-                    deviceManagerService.updateDeviceMapInCache(device.getDevId(), updateDeviceMap);
-                    
+                    // 更新数据库在线状态 (对应Python版本的数据库更新)
+                    deviceGateway.updateDeviceOnlineStatus(deviceId, 1);
                     log.info("设备重新上线: deviceId={}", deviceId);
                     
                     // 发送登录响应 (对应Python: mqtt_send.resp_dev_login(dev_id, DEV_EC.succeed))
@@ -363,10 +363,10 @@ public class DeviceEventServiceImpl implements DeviceEventService {
                     
                     // 4. 更新保活时间戳(参考Python版本的device.set_keepalive())
                     long currentTime = System.currentTimeMillis();
-                    device.updateKeepAliveTime(currentTime);
+//                    device.updateKeepAliveTime(currentTime);
                     
                     // 更新设备缓存
-                    deviceManagerService.updateDeviceInCache(device);
+                    deviceManagerService.updateDeviceKeepAliveInCache(deviceId, currentTime);
                     
                     log.debug("设备保活成功: deviceId={}, keepaliveTime={}", deviceId, currentTime);
                 } else {
@@ -958,21 +958,26 @@ public class DeviceEventServiceImpl implements DeviceEventService {
                 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);
                 
                 // === 更新停留时长 (对应Python的时间更新逻辑) ===
-                long ts = System.currentTimeMillis();  // ts = get_utc_time_ms()
-                if (device.getEnterTime() < 0) {       // if device.enter_ts() < 0:
-                    device.setEnterTime(ts);            // device.set_enter_ts(ts)
-                    log.info("{} target enter, {}", deviceId, ts);  // LOGINFO(f"{dev_id} target enter, {ts}")
-                }
-                device.setLeaveTime(ts);                // device.set_leave_ts(ts)
-                
+                // todo 停留时长 不在当前项目更新
+                Map<String, Object> updateMap = new HashMap<>();
+//                long ts = System.currentTimeMillis();  // ts = get_utc_time_ms()
+//                if (device.getEnterTime() < 0) {       // if device.enter_ts() < 0:
+//                    device.setEnterTime(ts);            // device.set_enter_ts(ts)
+//                    log.info("{} target enter, {}", deviceId, ts);  // LOGINFO(f"{dev_id} target enter, {ts}")
+//                }
+//                device.setLeaveTime(ts);                // device.set_leave_ts(ts)
+//                updateMap.put("leave")
+
+                deviceManagerService.updateDeviceMapInCache(deviceId, updateMap);
                 // === 更新报警目标信息 (对应Python: device.update_alarm_targets(targets)) ===
-                device.updateAlarmTargets(trackerTargetsFloat);
+//                device.updateAlarmTargets(trackerTargetsFloat);
                 
                 log.debug("处理tracker_targets完成: deviceId={}, targetCount={}", deviceId, trackerTargetsFloat.size());
             }
@@ -1552,7 +1557,8 @@ public class DeviceEventServiceImpl implements DeviceEventService {
             if (software != null && !software.trim().isEmpty()) {
                 device.setSoftware(software);            // device.set_software(software)
             }
-            
+
+            deviceManagerService.updateDeviceInCache(device);
             // === 发送设备信息更新通知 (对应Python: mqtt_send.update_dev_info_msg(device)) ===
             mqttGateway.sendDeviceInfoUpdateNotification(device);
             
@@ -1613,6 +1619,8 @@ public class DeviceEventServiceImpl implements DeviceEventService {
                 if (device.getOnline() != 1) {
                     // 若设备离线,使其重新上线 (对应Python: 若设备离线,使其重新上线)
                     device.setOnline(1);
+                    device.setKeepaliveTime(System.currentTimeMillis());
+                    deviceManagerService.updateDeviceAliveStatusInCache(deviceId);
                     
                     // 发送登录响应 (对应Python: mqtt_send.resp_dev_login(dev_id, device.online()))
                     mqttGateway.sendDeviceLoginResponseMessage(deviceId, device.getOnline());

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

@@ -20,7 +20,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
  * 姿态分析服务实现
  * 对应Python版本的post_process.py线程功能
  */
-@Service
+//@Service
 @Slf4j
 public class PoseAnalysisServiceImpl implements PoseAnalysisService {
 

+ 25 - 16
device-service-domain/src/main/java/com/hfln/device/domain/entity/Device.java

@@ -534,14 +534,14 @@ public class Device {
      * 获取告警确认状态 (对应Python版本的get_alarm_ack方法)
      * @return 告警确认状态
      */
-    public boolean getAlarmAck() {
-        try {
-            lock.lock();
-            return Boolean.TRUE.equals(alarmAck);
-        } finally {
-            lock.unlock();
-        }
-    }
+//    public boolean getAlarmAck() {
+//        try {
+//            lock.lock();
+//            return Boolean.TRUE.equals(alarmAck);
+//        } finally {
+//            lock.unlock();
+//        }
+//    }
     
     /**
      * 设置最后告警确认时间 (对应Python版本的set_last_alarm_ack_time方法)
@@ -560,14 +560,14 @@ public class Device {
      * 获取最后告警确认时间 (对应Python版本的get_last_alarm_ack_time方法)
      * @return 最后告警确认时间
      */
-    public long getLastAlarmAckTime() {
-        try {
-            lock.lock();
-            return lastAlarmAckTime != null ? lastAlarmAckTime : 0L;
-        } finally {
-            lock.unlock();
-        }
-    }
+//    public long getLastAlarmAckTime() {
+//        try {
+//            lock.lock();
+//            return lastAlarmAckTime != null ? lastAlarmAckTime : 0L;
+//        } finally {
+//            lock.unlock();
+//        }
+//    }
     
     /**
      * 设置最后上报跌倒时间 (对应Python版本的set_last_report_fall_time方法)
@@ -1479,6 +1479,15 @@ public class Device {
             lock.unlock();
         }
     }
+
+    public void setLastFallTime(Map<String, Long> map) {
+        try {
+            lock.lock();
+            lastFallTimeByEvent.putAll(map);
+        } finally {
+            lock.unlock();
+        }
+    }
     
     /**
      * 获取当前跌倒状态 (对应Python版本的device.falling_)

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

@@ -31,12 +31,16 @@ public interface DeviceManagerService {
      */
     void updateDeviceInCache(Device device);
 
+    void updateDeviceKeepAliveInCache(String devId,  Long keepaliveTime);
+
+    void updateDeviceAliveStatusInCache(String devId);
+
     /**
      * 更新设备缓存
      * @param devId 设备ID
      * @param map   设备更新属性
      */
-    default void updateDeviceMapInCache(String devId, Map<String, Object> map) {};
+    void updateDeviceMapInCache(String devId, Map<String, Object> map);
     
     /**
      * 从缓存中删除设备

+ 181 - 181
device-service-domain/src/main/java/com/hfln/device/domain/service/impl/DeviceManagerServiceImpl.java

@@ -1,181 +1,181 @@
-package com.hfln.device.domain.service.impl;
-
-import com.hfln.device.domain.entity.Device;
-import com.hfln.device.domain.constant.DeviceConstants;
-import com.hfln.device.domain.service.DeviceManagerService;
-import com.hfln.device.domain.service.DeviceStatusService;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.Collection;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-/**
- * 设备管理服务实现类
- * 负责设备状态管理、保活检查等功能
- */
-@Slf4j
-//@Service
-public class DeviceManagerServiceImpl implements DeviceManagerService {
-
-    /**
-     * 设备缓存,用于保存所有在线设备信息
-     */
-    private final Map<String, Device> deviceCache = new ConcurrentHashMap<>();
-
-    @Autowired
-    private DeviceStatusService deviceStatusService;
-
-    @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);
-        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) {
-        deviceCache.remove(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()) {
-                Long lastAckTime = device.getLastAlarmAckTime();
-                
-                // 如果有告警且超时未确认,则自动确认
-                if (lastAckTime > 0 && 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);
-    }
-} 
+//package com.hfln.device.domain.service.impl;
+//
+//import com.hfln.device.domain.entity.Device;
+//import com.hfln.device.domain.constant.DeviceConstants;
+//import com.hfln.device.domain.service.DeviceManagerService;
+//import com.hfln.device.domain.service.DeviceStatusService;
+//import lombok.extern.slf4j.Slf4j;
+//
+//import java.util.Map;
+//import java.util.Optional;
+//import java.util.concurrent.ConcurrentHashMap;
+//import java.util.Collection;
+//
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.stereotype.Service;
+//
+///**
+// * 设备管理服务实现类
+// * 负责设备状态管理、保活检查等功能
+// */
+//@Slf4j
+////@Service
+//public class DeviceManagerServiceImpl implements DeviceManagerService {
+//
+//    /**
+//     * 设备缓存,用于保存所有在线设备信息
+//     */
+//    private final Map<String, Device> deviceCache = new ConcurrentHashMap<>();
+//
+//    @Autowired
+//    private DeviceStatusService deviceStatusService;
+//
+//    @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);
+//        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) {
+//        deviceCache.remove(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()) {
+//                Long lastAckTime = device.getLastAlarmAckTime();
+//
+//                // 如果有告警且超时未确认,则自动确认
+//                if (lastAckTime > 0 && 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);
+//    }
+//}

+ 212 - 11
device-service-domain/src/main/java/com/hfln/device/domain/service/impl/DeviceRedisManagerServiceImpl.java

@@ -4,12 +4,14 @@ import cn.hfln.framework.redis.util.RedisUtil;
 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.gateway.DeviceGateway;
 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 org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
@@ -27,12 +29,15 @@ public class DeviceRedisManagerServiceImpl implements DeviceManagerService {
      */
     private final Map<String, Device> deviceCache = new ConcurrentHashMap<>();
 
-    @Autowired
-    private DeviceStatusService deviceStatusService;
+//    @Autowired
+//    private DeviceStatusService deviceStatusService;
 
     @Autowired
     private RedisUtil redisService;
 
+    @Autowired
+    private DeviceGateway deviceGateway;
+
     @Override
     public Optional<Device> getDeviceFromCache(String devId) {
 
@@ -119,7 +124,7 @@ public class DeviceRedisManagerServiceImpl implements DeviceManagerService {
             device.setAlarmInterval((long) deviceMap.get("alarmInterval"));
         }
         if (deviceMap.get("alarmAck") != null) {
-            device.setAlarmAck((boolean) deviceMap.get("alarmAck"));
+            device.setAlarmAck(Boolean.parseBoolean((String) deviceMap.get("alarmAck")));
         }
         if (deviceMap.get("lastAlarmAckTime") != null) {
             device.setLastAlarmAckTime((long) deviceMap.get("lastAlarmAckTime"));
@@ -131,6 +136,23 @@ public class DeviceRedisManagerServiceImpl implements DeviceManagerService {
             device.setFalling((int) deviceMap.get("falling"));
         }
 
+        Map<String, Long> lastFallTimeByEvent = new HashMap<>();
+        if (deviceMap.get("no_fall") != null) {
+            lastFallTimeByEvent.put("no_fall", (Long) deviceMap.get("no_fall"));
+        }
+        if (deviceMap.get("fall_detected") != null) {
+            lastFallTimeByEvent.put("fall_detected", (Long) deviceMap.get("fall_detected"));
+        }
+        // fall_confirmed
+        if (deviceMap.get("fall_confirmed") != null) {
+            lastFallTimeByEvent.put("fall_confirmed", (Long) deviceMap.get("fall_confirmed"));
+        }
+        // fall_calling
+        if (deviceMap.get("fall_calling") != null) {
+            lastFallTimeByEvent.put("fall_calling", (Long) deviceMap.get("fall_calling"));
+        }
+        device.setLastFallTime(lastFallTimeByEvent);
+
         return Optional.ofNullable(device);
     }
 
@@ -200,6 +222,16 @@ public class DeviceRedisManagerServiceImpl implements DeviceManagerService {
         deviceMap.put("alarmAckInterval", device.getAlarmAckInterval());
         // 最后上报跌倒信息 跌倒状态
         deviceMap.put("falling", device.getFalling());
+        if (!CollectionUtils.isEmpty(device.getLastFallTimeByEvent())) {
+            // 没有检测到跌倒
+            deviceMap.put("no_fall", device.getLastFallTimeByEvent().get("no_fall"));
+            // 检测到跌倒
+            deviceMap.put("fall_detected", device.getLastFallTimeByEvent().get("fall_detected"));
+            // 跌倒确认
+            deviceMap.put("fall_confirmed", device.getLastFallTimeByEvent().get("fall_confirmed"));
+            // 跌倒呼救
+            deviceMap.put("fall_calling", device.getLastFallTimeByEvent().get("fall_calling"));
+        }
 
         // 设备调试参数
 //        deviceMap.put(RedisCacheConstant.KEY_DEVICE_DEBUG_PARAM_PRE + "", device.getDebugParam(""));
@@ -212,12 +244,174 @@ public class DeviceRedisManagerServiceImpl implements DeviceManagerService {
 
     @Override
     public void updateDeviceInCache(Device device) {
-        deviceCache.put(device.getDevId(), device);
+
+        if (!redisService.sIsMember(RedisCacheConstant.KEY_DEVICE_ID, device.getDevId())) {
+            log.info("Device not found in cache: {}", device.getDevId());
+            return;
+        }
+
+        // 设置redis 存储设备的 hash对象的属性
+        Map<String, Object> deviceMap = new HashMap<>();
+
+        // 设置设备属性
+        if (StringUtils.hasText(device.getDevId())) {
+            deviceMap.put("devId", device.getDevId());
+        }
+        if (StringUtils.hasText(device.getDevType())) {
+            deviceMap.put("devType", device.getDevType());
+        }
+        if (StringUtils.hasText(device.getSoftware())) {
+            deviceMap.put("software", device.getSoftware());
+        }
+        if (StringUtils.hasText(device.getHardware())) {
+            deviceMap.put("hardware", device.getHardware());
+        }
+        if (StringUtils.hasText(device.getBluVer())) {
+            deviceMap.put("bluVer", device.getBluVer());
+        }
+
+        // 添加网络信息
+        if (device.getNetwork() != null) {
+            if (StringUtils.hasText(device.getNetwork().getSsid())) {
+                deviceMap.put("ssid", device.getNetwork().getSsid());
+            }
+            if (StringUtils.hasText(device.getNetwork().getIp())) {
+                deviceMap.put("ip", device.getNetwork().getIp());
+            }
+            if (StringUtils.hasText(device.getNetwork().getPassword())) {
+                deviceMap.put("password", device.getNetwork().getPassword());
+            }
+        }
+
+        // 添加安装参数
+        if (device.getInstallParam() != null) {
+            if (StringUtils.hasText(device.getInstallParam().getMountPlain())) {
+                deviceMap.put("mountPlain", device.getInstallParam().getMountPlain());
+            }
+            if (device.getInstallParam().getIsCeiling() != null) {
+                deviceMap.put("isCeiling", device.getInstallParam().getIsCeiling());
+            }
+            if (device.getInstallParam().getHeight() != null) {
+                deviceMap.put("height", device.getInstallParam().getHeight());
+            }
+
+            // 添加跟踪区域
+            if (device.getInstallParam().getTrackingRegion() != null) {
+                if (device.getInstallParam().getTrackingRegion().getStartX() != null) {
+                    deviceMap.put("startX", device.getInstallParam().getTrackingRegion().getStartX());
+                }
+                if (device.getInstallParam().getTrackingRegion().getStartY() != null) {
+                    deviceMap.put("startY", device.getInstallParam().getTrackingRegion().getStartY());
+                }
+                if (device.getInstallParam().getTrackingRegion().getStartZ() != null) {
+                    deviceMap.put("startZ", device.getInstallParam().getTrackingRegion().getStartZ());
+                }
+                if (device.getInstallParam().getTrackingRegion().getStopX() != null) {
+                    deviceMap.put("stopX", device.getInstallParam().getTrackingRegion().getStopX());
+                }
+                if (device.getInstallParam().getTrackingRegion().getStopY() != null) {
+                    deviceMap.put("stopY", device.getInstallParam().getTrackingRegion().getStopY());
+                }
+                if (device.getInstallParam().getTrackingRegion().getStopZ() != null) {
+                    deviceMap.put("stopZ", device.getInstallParam().getTrackingRegion().getStopZ());
+                }
+            }
+        }
+
+        // 实时点位
+        // List<Float> targets = new ArrayList<>();
+        // String targetsStr = JsonUtil.toJson(targets);
+//        deviceMap.put("targets", targetsStr);
+
+        // 在线状态
+        if (device.getOnline() != null) {
+            deviceMap.put("online", device.getOnline());
+        }
+        // 最后心跳时间戳
+        if (device.getKeepaliveTime() != null) {
+            deviceMap.put("keepAliveTime", device.getKeepaliveTime());
+        }
+        // 超时时间 默认90秒
+        if (device.getExpireTime() != null) {
+            deviceMap.put("expireTime", device.getExpireTime());
+        }
+
+        // 跌倒信息
+        // 最后上报跌倒时间
+        if (device.getLastReportFallTime() != null) {
+            deviceMap.put("lastReportFallTime", device.getLastReportFallTime());
+        }
+        // 告警时间间隔(毫秒),默认30秒
+        if (device.getAlarmInterval() != null) {
+            deviceMap.put("alarmInterval", device.getAlarmInterval());
+        }
+        // 告警确认
+        if (device.getAlarmAck() != null) {
+            deviceMap.put("alarmAck", String.valueOf(device.getAlarmAck()));
+        }
+        // 最后告警确认时间
+        if (device.getLastAlarmAckTime() != null) {
+            deviceMap.put("lastAlarmAckTime", device.getLastAlarmAckTime());
+        }
+        // 告警确认时间间间隔(毫秒),默认5分钟
+        if (device.getAlarmAckInterval() != null) {
+            deviceMap.put("alarmAckInterval", device.getAlarmAckInterval());
+        }
+        // 最后上报跌倒信息 跌倒状态
+        if (device.getFalling() != null) {
+            deviceMap.put("falling", device.getFalling());
+        }
+        if (!CollectionUtils.isEmpty(device.getLastFallTimeByEvent())) {
+            Map<String, Long> fallTimeMap = device.getLastFallTimeByEvent();
+            if (fallTimeMap != null) {
+                // 没有检测到跌倒
+                if (fallTimeMap.containsKey("no_fall") && fallTimeMap.get("no_fall") != null) {
+                    deviceMap.put("no_fall", fallTimeMap.get("no_fall"));
+                }
+                // 检测到跌倒
+                if (fallTimeMap.containsKey("fall_detected") && fallTimeMap.get("fall_detected") != null) {
+                    deviceMap.put("fall_detected", fallTimeMap.get("fall_detected"));
+                }
+                // 跌倒确认
+                if (fallTimeMap.containsKey("fall_confirmed") && fallTimeMap.get("fall_confirmed") != null) {
+                    deviceMap.put("fall_confirmed", fallTimeMap.get("fall_confirmed"));
+                }
+                // 跌倒呼救
+                if (fallTimeMap.containsKey("fall_calling") && fallTimeMap.get("fall_calling") != null) {
+                    deviceMap.put("fall_calling", fallTimeMap.get("fall_calling"));
+                }
+            }
+        }
+
+        // 设备调试参数
+//        deviceMap.put(RedisCacheConstant.KEY_DEVICE_DEBUG_PARAM_PRE + "", device.getDebugParam(""));
+
+        redisService.hSetAll(RedisCacheConstant.KEY_DEVICE_pre + device.getDevId(), deviceMap);
         log.debug("Device updated in cache: {}", device.getDevId());
     }
 
+    @Override
+    public void updateDeviceKeepAliveInCache(String devId,  Long keepaliveTime) {
+//        deviceCache.put(device.getDevId(), device);
+        if (redisService.sIsMember(RedisCacheConstant.KEY_DEVICE_ID, devId)) {
+            redisService.hSet(RedisCacheConstant.KEY_DEVICE_pre + devId, "keepaliveTime", keepaliveTime);
+        }
+        log.debug("Device updated in cache: {}", devId);
+    }
+
+    @Override
+    public void updateDeviceAliveStatusInCache(String devId) {
+        Map<String, Object> updateDeviceMap = new HashMap<>();
+        updateDeviceMap.put("online", 1);
+        updateDeviceMap.put("keepAliveTime", System.currentTimeMillis());
+        redisService.hSetAll(RedisCacheConstant.KEY_DEVICE_pre + devId, updateDeviceMap);
+    }
+
     public void updateDeviceMapInCache(String devId, Map<String, Object> map) {
 
+        if (CollectionUtils.isEmpty( map)) {
+            return;
+        }
         redisService.hSetAll(RedisCacheConstant.KEY_DEVICE_pre + devId, map);
         log.debug("Device updated in cache: {}", devId);
     }
@@ -242,13 +436,20 @@ public class DeviceRedisManagerServiceImpl implements DeviceManagerService {
             return;
         }
 
-//        for (Object devIdObj : devIdSet) {
-//            Object onlineObj = redisService.hGet(RedisCacheConstant.KEY_DEVICE_pre + devIdObj, "online");
-//            if (onlineObj != null && Integer.parseInt(onlineObj.toString()) == 1) {
-//                Long lastKeepAliveTime = redisService.hGet(RedisCacheConstant.KEY_DEVICE_pre + devIdObj, "keepAliveTime");
-//            }
-//        }
-//
+        for (Object devIdObj : devIdSet) {
+            Object onlineObj = redisService.hGet(RedisCacheConstant.KEY_DEVICE_pre + devIdObj, "online");
+            if (onlineObj != null && Integer.parseInt(onlineObj.toString()) == 1) {
+                Long lastKeepAliveTime = (Long) redisService.hGet(RedisCacheConstant.KEY_DEVICE_pre + devIdObj, "keepAliveTime");
+                // 如果设备无保活时间或超时,则设置为离线
+                if (lastKeepAliveTime == null || (currentTimeMillis - lastKeepAliveTime) > timeoutMillis) {
+                    log.info("Device keepalive timeout: {}, last keepalive: {}", devIdObj, lastKeepAliveTime);
+                    redisService.hSet(RedisCacheConstant.KEY_DEVICE_pre + devIdObj, "online", 0);
+                    // todo 更新数据库 设备状态
+                    deviceGateway.updateDeviceOnlineStatus((String) devIdObj, 0);
+                }
+            }
+        }
+
 //        deviceCache.forEach((devId, device) -> {
 //            // 只检查在线设备
 //            if (device.getOnline() != null && device.getOnline() == 1) {