yangliu 4 місяців тому
батько
коміт
f8f8af0954
13 змінених файлів з 1775 додано та 540 видалено
  1. 7 7
      device-service-application/src/main/java/com/hfln/device/application/event/EventHandlerImpl.java
  2. 2 2
      device-service-application/src/main/java/com/hfln/device/application/service/DeviceCommandService.java
  3. 309 73
      device-service-application/src/main/java/com/hfln/device/application/service/impl/DeviceCommandServiceImpl.java
  4. 2 0
      device-service-application/src/main/java/com/hfln/device/application/service/impl/DeviceEventServiceExtendImpl.java
  5. 595 228
      device-service-application/src/main/java/com/hfln/device/application/service/impl/DeviceEventServiceImpl.java
  6. 380 2
      device-service-domain/src/main/java/com/hfln/device/domain/entity/Device.java
  7. 61 2
      device-service-domain/src/main/java/com/hfln/device/domain/gateway/MqttGateway.java
  8. 28 3
      device-service-domain/src/main/java/com/hfln/device/domain/port/DeviceEventPort.java
  9. 84 0
      device-service-domain/src/main/java/com/hfln/device/domain/service/PointCloudProcessService.java
  10. 2 1
      device-service-domain/src/main/java/com/hfln/device/domain/service/impl/AlarmServiceImpl.java
  11. 185 31
      device-service-infrastructure/src/main/java/com/hfln/device/infrastructure/gateway/MqttGatewayImpl.java
  12. 91 61
      device-service-infrastructure/src/main/java/com/hfln/device/infrastructure/mqtt/handler/DeviceMessageHandler.java
  13. 29 130
      device-service-infrastructure/src/main/java/com/hfln/device/infrastructure/mqtt/handler/MpsMessageHandler.java

+ 7 - 7
device-service-application/src/main/java/com/hfln/device/application/event/EventHandlerImpl.java

@@ -1,19 +1,18 @@
 package com.hfln.device.application.event;
 
-import com.hfln.device.domain.constant.EventConstants;
+import com.hfln.device.domain.service.DeviceService;
 import com.hfln.device.domain.entity.Device;
-import com.hfln.device.domain.event.EventHandler;
-import com.hfln.device.domain.event.FallEvent;
-import com.hfln.device.domain.event.PresenceEvent;
-import com.hfln.device.domain.event.RetentionEvent;
+import com.hfln.device.domain.event.*;
+import com.hfln.device.domain.constant.EventConstants;
 import com.hfln.device.domain.gateway.DeviceGateway;
 import com.hfln.device.domain.gateway.MqttGateway;
-import com.hfln.device.domain.service.DeviceService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -57,7 +56,8 @@ public class EventHandlerImpl implements EventHandler {
                 device.setLastAlarmAckTime(event.getTimestamp());
                 saveAlarmRecord(device, event);
             } else if (EventConstants.FallStatus.FALL_CANCELED.equals(fallStatus)) {
-                mqttGateway.sendEventMessage(deviceId, event.getPose(), event.getTargetPoint(), fallStatus);
+                List<List<Float>> targets = Collections.singletonList(event.getTargetPoint());
+                mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), event.getPose(), targets, fallStatus);
                 log.info("取消跌倒事件: {}", deviceId);
             }
             deviceService.updateDevice(device);

+ 2 - 2
device-service-application/src/main/java/com/hfln/device/application/service/DeviceCommandService.java

@@ -139,9 +139,9 @@ public interface DeviceCommandService {
      * 处理设备重启
      * 对应Python版本的deal_reboot方法
      * 
-     * @param payload 消息载荷
+     * @param deviceId 设备ID
      */
-    void handleDeviceReboot(String payload);
+    void handleDeviceReboot(String deviceId);
     
     /**
      * 处理添加设备

+ 309 - 73
device-service-application/src/main/java/com/hfln/device/application/service/impl/DeviceCommandServiceImpl.java

@@ -2,6 +2,7 @@ package com.hfln.device.application.service.impl;
 
 import com.hfln.device.application.service.DeviceCommandService;
 import com.hfln.device.common.constant.mqtt.topic.MqttTopics;
+import com.hfln.device.common.util.JsonUtil;
 import com.hfln.device.domain.entity.Device;
 import com.hfln.device.domain.service.DeviceManagerService;
 import com.hfln.device.domain.gateway.DeviceGateway;
@@ -48,12 +49,31 @@ public class DeviceCommandServiceImpl implements DeviceCommandService {
     @Override
     public void handleGetDeviceInfo(String deviceId) {
         log.info("Handling get device info request for device: {}", deviceId);
-        // 向设备发送获取信息请求
-        String topic = String.format(MqttTopics.DEV_REP_DEV_INFO.replace("+", "%s"), deviceId);
-        Device device = new Device();
-        device.setDevId(deviceId);
-        mqttGateway.sendDeviceStatusMessage(device);
+        
+        try {
+            // 1. 验证设备是否存在(参考Python版本:检查 g_dev_map)
+            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
+            if (!deviceOpt.isPresent()) {
+                log.warn("Device not found in cache: {}", deviceId);
+                return;
+            }
+            
+            // 2. 向设备端发送获取信息请求(参考Python版本:mqtt_send.get_dev_info_msg)
+            // 构造发送到设备的主题:/dev/{deviceId}/get_device_info
+            String topic = String.format("/dev/%s/get_device_info", deviceId);
+            Map<String, Object> payload = new HashMap<>();
+            
+                         // 发送空的JSON对象到设备,请求设备信息(参考Python版本)
+             mqttGateway.sendToMqtt(topic, JsonUtil.toJsonString(payload));
+            
+            log.info("Get device info command sent to device: {}", deviceId);
+            
+        } catch (Exception e) {
+            log.error("Error handling get device info request for device {}: {}", 
+                    deviceId, e.getMessage(), e);
+        }
     }
+
     
     @Override
     public void handleResetDevice(String deviceId) {
@@ -294,66 +314,84 @@ public class DeviceCommandServiceImpl implements DeviceCommandService {
     
     @Override
     public void handleSetDeviceParamRequest(Map<String, Object> messageData) {
-        log.info("Handling set device parameter request: {}", messageData);
+        log.info("处理设置设备参数请求: {}", messageData);
         
         try {
-            // 提取必要参数
-            String deviceId = (String) messageData.get("dev_id");
-            Object mountPlainObj = messageData.get("mounting_plain");
-            Object areaObj = messageData.get("area");
-            Object heightObj = messageData.get("height");
+            // 1. 完全按照Python版本的参数验证逻辑(包括其bug)
+            // Python: if not ("dev_id" in payload or "mounting_plain" in payload or "height" in payload or "area" in payload or "start_x" in payload["area"] or ...)
+            boolean hasValidParams = messageData.containsKey("dev_id") || 
+                                   messageData.containsKey("mounting_plain") || 
+                                   messageData.containsKey("height") || 
+                                   messageData.containsKey("area");
             
-            if (deviceId == null) {
-                log.warn("Missing device ID in set parameter request");
+            // 检查area子字段(模拟Python版本的潜在KeyError风险)
+            try {
+                Object areaObj = messageData.get("area");
+                if (areaObj instanceof Map) {
+                    Map<String, Object> areaMap = (Map<String, Object>) areaObj;
+                    hasValidParams = hasValidParams || 
+                                   areaMap.containsKey("start_x") || 
+                                   areaMap.containsKey("start_y") || 
+                                   areaMap.containsKey("start_z") || 
+                                   areaMap.containsKey("stop_x") || 
+                                   areaMap.containsKey("stop_y") || 
+                                   areaMap.containsKey("stop_z");
+                }
+            } catch (Exception e) {
+                // 忽略area访问异常,模拟Python版本的行为
+            }
+            
+            if (!hasValidParams) {
+                log.debug("error: invalid param, topic");
                 return;
             }
             
-            // 转换参数
-            String mountPlain = mountPlainObj != null ? mountPlainObj.toString() : null;
-            String area = areaObj != null ? areaObj.toString() : null;
-            Float height = heightObj != null ? Float.parseFloat(heightObj.toString()) : null;
+            // 2. 提取设备ID(对应Python版本第626行:dev_id = payload["dev_id"])
+            String deviceId = (String) messageData.get("dev_id");
             
-            // 处理设备参数设置
-            // 检查设备是否存在
-            boolean deviceExists = deviceGateway.checkDeviceExists(deviceId);
-            if (!deviceExists) {
-                log.warn("Device not found for parameter setting: {}", deviceId);
+            // 3. 设备存在性检查(对应Python版本第627-630行:with g_dev_map_lock: if not (dev_id in g_dev_map))
+            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
+            if (!deviceOpt.isPresent()) {
+                log.debug("error: no device: {}, topic", deviceId);
                 return;
             }
             
-            // 更新设备参数
-            Device.InstallParam installParam = new Device.InstallParam();
-            installParam.setMountPlain(mountPlain);
-            installParam.setHeight(height);
+            // 4. 提取所有参数(对应Python版本第632-639行)
+            String mountingPlain = messageData.get("mounting_plain").toString();
+            Float height = Float.parseFloat(messageData.get("height").toString());
             
-            if (areaObj instanceof Map) {
-                Map<String, Object> areaMap = (Map<String, Object>) areaObj;
-                Device.TrackingRegion trackingRegion = new Device.TrackingRegion();
-                
-                // 从areaMap提取区域参数
-                Object startX = areaMap.get("start_x");
-                Object startY = areaMap.get("start_y");
-                Object startZ = areaMap.get("start_z");
-                Object stopX = areaMap.get("stop_x");
-                Object stopY = areaMap.get("stop_y");
-                Object stopZ = areaMap.get("stop_z");
-                
-                trackingRegion.setStartX(startX != null ? Integer.parseInt(startX.toString()) : 0);
-                trackingRegion.setStartY(startY != null ? Integer.parseInt(startY.toString()) : 0);
-                trackingRegion.setStartZ(startZ != null ? Integer.parseInt(startZ.toString()) : 0);
-                trackingRegion.setStopX(stopX != null ? Integer.parseInt(stopX.toString()) : 300);
-                trackingRegion.setStopY(stopY != null ? Integer.parseInt(stopY.toString()) : 300);
-                trackingRegion.setStopZ(stopZ != null ? Integer.parseInt(stopZ.toString()) : 300);
-                
-                installParam.setTrackingRegion(trackingRegion);
-            }
+            // 提取区域坐标(对应Python版本的area坐标提取)
+            Map<String, Object> areaMap = (Map<String, Object>) messageData.get("area");
+            String startX = areaMap.get("start_x").toString();
+            String startY = areaMap.get("start_y").toString();
+            String startZ = areaMap.get("start_z").toString();
+            String stopX = areaMap.get("stop_x").toString();
+            String stopY = areaMap.get("stop_y").toString();
+            String stopZ = areaMap.get("stop_z").toString();
+            
+            // 5. 构造area字符串(对应Python版本第641行:area_str = f"{start_x},{stop_x},{start_y},{stop_y},{start_z},{stop_z}")
+            String areaStr = String.format("%s,%s,%s,%s,%s,%s", startX, stopX, startY, stopY, startZ, stopZ);
+            
+            // 6. 向设备端发送MQTT消息(对应Python版本第644行:mqtt_send.set_dev_param_msg(dev_id, mounting_plain, area_str, height))
+            String topic = String.format("/dev/%s/set_device_param", deviceId);
+            Map<String, Object> devicePayload = new HashMap<>();
+            devicePayload.put("mounting_plain", mountingPlain);
+            devicePayload.put("arena", areaStr);  // 注意:Python版本中使用的是 "arena",不是 "area"
+            devicePayload.put("sensor_height", height);
+            
+            mqttGateway.sendToMqtt(topic, JsonUtil.toJsonString(devicePayload));
             
-            // 更新设备安装参数
-            boolean updated = deviceGateway.updateDeviceInstallParam(deviceId, installParam);
+            log.info("设备参数设置命令已发送到设备: {} - mounting_plain: {}, height: {}, area: {}", 
+                     deviceId, mountingPlain, height, areaStr);
             
-            log.info("Device parameter update result: deviceId={}, success={}", deviceId, updated);
         } catch (Exception e) {
-            log.error("Error handling set device parameter request: {}", e.getMessage(), e);
+            // 对应Python版本的异常处理(第646-649行)
+            String errorMessage = e.getMessage();
+            if (errorMessage != null && (errorMessage.contains("JSON") || errorMessage.contains("parse"))) {
+                log.error("parse payload failed, topic, {}", messageData);
+            } else {
+                log.error("deal_set_dev_param error: {}", errorMessage);
+            }
         }
     }
     
@@ -364,22 +402,62 @@ public class DeviceCommandServiceImpl implements DeviceCommandService {
         log.info("处理获取设备参数请求: {}", payload);
         
         try {
-            // TODO: 解析payload并获取设备信息
-            // 对应Python版本的deal_get_dev_info_param方法
-            log.info("获取设备参数请求处理完成");
+            // 1. 解析payload获取设备ID(对应Python版本的消息解析)
+            Map<String, Object> messageData = JsonUtil.parseMap(payload);
+            String deviceId = (String) messageData.get("dev_id");
+            
+            if (deviceId == null || deviceId.trim().isEmpty()) {
+                log.warn("获取设备参数请求中缺少设备ID: {}", payload);
+                return;
+            }
+            
+            log.info("Processing get device param request for device: {}", deviceId);
+            
+            // 2. 验证设备是否存在(对应Python版本:检查 g_dev_map)
+            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
+            if (!deviceOpt.isPresent()) {
+                log.warn("Device not found in cache: {}", deviceId);
+                return;
+            }
+            
+            // 3. 向设备端发送获取参数请求(对应Python版本:mqtt_send.get_dev_info_msg(dev_id, "get_device_param"))
+            // 构造发送到设备的主题:/dev/{deviceId}/get_device_param  
+            String topic = String.format("/dev/%s/get_device_param", deviceId);
+            Map<String, Object> requestPayload = new HashMap<>();
+            
+            // 发送空的JSON对象到设备,请求设备参数(参考Python版本)
+            mqttGateway.sendToMqtt(topic, JsonUtil.toJsonString(requestPayload));
+            
+            log.info("Get device param command sent to device: {}", deviceId);
+            
         } catch (Exception e) {
             log.error("处理获取设备参数请求异常: {}", e.getMessage(), e);
         }
     }
     
     @Override
-    public void handleDeviceReboot(String payload) {
-        log.info("处理设备重启请求: {}", payload);
+    public void handleDeviceReboot(String deviceId) {
+        log.info("处理设备重启请求,设备ID: {}", deviceId);
         
         try {
-            // TODO: 解析payload并重启设备
-            // 对应Python版本的deal_reboot方法
-            log.info("设备重启请求处理完成");
+            // 对应Python版本:从topic中提取设备ID后,直接调用mqtt_send.dev_reboot(dev_id)
+            // MpsMessageHandler已经从topic提取了设备ID,这里直接使用
+            
+            if (deviceId == null || deviceId.trim().isEmpty()) {
+                log.warn("设备重启请求中设备ID为空");
+                return;
+            }
+            
+            log.info("Processing device reboot request for device: {}", deviceId);
+            
+            // 向设备端发送重启请求(对应Python版本:mqtt_send.dev_reboot(dev_id))
+            String topic = String.format("/dev/%s/reboot", deviceId);
+            Map<String, Object> rebootPayload = new HashMap<>();  // 空的JSON对象(对应Python版本:format_json = dict())
+            
+            mqttGateway.sendToMqtt(topic, JsonUtil.toJsonString(rebootPayload));
+            
+            log.info("设备重启命令已发送到设备: {}", deviceId);
+            
         } catch (Exception e) {
             log.error("处理设备重启请求异常: {}", e.getMessage(), e);
         }
@@ -390,11 +468,112 @@ public class DeviceCommandServiceImpl implements DeviceCommandService {
         log.info("处理添加设备请求: {}", payload);
         
         try {
-            // TODO: 解析payload并添加设备
-            // 对应Python版本的deal_add_device方法
-            log.info("添加设备请求处理完成");
+            // 1. 解析payload获取设备ID(对应Python版本:payload = json.loads(msg.payload.decode('utf-8')))
+            Map<String, Object> messageData = JsonUtil.parseMap(payload);
+            
+            // 2. 验证dev_id参数(对应Python版本:if not ("dev_id" in payload))
+            if (!messageData.containsKey("dev_id")) {
+                log.debug("error: invalid param, missing dev_id");
+                return;
+            }
+            
+            String deviceId = (String) messageData.get("dev_id");
+            if (deviceId == null || deviceId.trim().isEmpty()) {
+                log.debug("error: invalid param, empty dev_id");
+                return;
+            }
+            
+            log.info("开始添加设备: {}", deviceId);
+            
+            // 3. 查询数据库获取设备信息(对应Python版本的核心逻辑)
+            // Python版本: db_req_que.put(DBRequest(sql=db_process.sql_query_one_dev_info, params=(dev_id,), callback=cb_handle_query_one_dev_info))
+            // 这里我们直接调用查询方法,模拟异步回调的效果
+            handleDeviceQueryCallback(deviceId);
+            
+        } catch (Exception e) {
+            log.debug("deal_add_device error: {}", e.getMessage());
+        }
+    }
+    
+    /**
+     * 处理设备查询回调(对应Python版本的cb_handle_query_one_dev_info)
+     */
+    private void handleDeviceQueryCallback(String deviceId) {
+        try {
+            // 查询数据库获取设备详细信息
+            Optional<Device> deviceOpt = deviceGateway.findDeviceById(deviceId);
+            
+            // 对应Python版本:if (not result) or len(result) < 1:
+            if (!deviceOpt.isPresent()) {
+                log.debug("cb_handle_query_one_dev_info, invalid result");
+                return;
+            }
+            
+            Device device = deviceOpt.get();
+            
+            // 对应Python版本:不做成员校验,出错直接抛出异常
+            // row = result[0]
+            // dev_id = row["dev_id"]
+            // online = row["online"]
+            // software = row["software"]
+            // hardware = row["hardware"]
+            // mount_plain = row["mount_plain"]
+            // height = row["height"]
+            // x1 = row["start_x"] ... x2 = row["stop_x"]
+            // wifi_ssid = row["wifi_ssid"]
+            // password = row["password"]  
+            // ip = row["ip"]
+            // delete_tag = row["delete_tag"]
+            // install_param = InstallParam(mount_plain, round(height,3), TrackingRegion(x1, y1, z1, x2, y2, z2))
+            // network = Network(wifi_ssid, password, ip)
+            
+            // 对应Python版本的设备缓存更新逻辑
+            // with g_dev_map_lock:
+            //     if dev_id in g_dev_map:     # 已存在的设备
+            //         device:Device = g_dev_map[dev_id]
+            //         device.set_online(online)
+            //         device.set_software(software)
+            //         device.set_hardware(hardware)
+            //         device.set_install_param(install_param)
+            //         device.set_network(network)
+            //     else:   # 新增的设备
+            //         device = Device(dev_id, online, software, hardware, network, install_param)
+            //         with g_dev_map_lock:
+            //             g_dev_map[dev_id] = device
+            
+            Optional<Device> existingDevice = deviceManagerService.getDeviceFromCache(deviceId);
+            if (existingDevice.isPresent()) {
+                // 已存在的设备 - 更新设备信息(对应Python版本:if dev_id in g_dev_map)
+                Device cachedDevice = existingDevice.get();
+                cachedDevice.setOnline(device.getOnline());
+                cachedDevice.setSoftware(device.getSoftware());
+                cachedDevice.setHardware(device.getHardware());
+                cachedDevice.setInstallParam(device.getInstallParam());
+                cachedDevice.setNetwork(device.getNetwork());
+                log.debug("更新已存在设备: {}", deviceId);
+            } else {
+                // 新增的设备 - 添加到缓存(对应Python版本:else branch)
+                deviceManagerService.addDeviceToCache(device);
+                log.debug("新增设备到缓存: {}", deviceId);
+            }
+            
         } catch (Exception e) {
-            log.error("处理添加设备请求异常: {}", e.getMessage(), e);
+            // 对应Python版本的异常处理逻辑
+            if (e.getCause() instanceof com.fasterxml.jackson.core.JsonProcessingException) {
+                // 对应Python版本:except json.JSONDecodeError as e:
+                StackTraceElement[] stackTrace = e.getStackTrace();
+                for (StackTraceElement frame : stackTrace) {
+                    log.error("[{}:{}] @{}(), error:{}, {}", 
+                        frame.getFileName(), frame.getLineNumber(), frame.getMethodName(), e.getMessage(), e.getClass().getSimpleName());
+                }
+            } else {
+                // 对应Python版本:except Exception as e:
+                StackTraceElement[] stackTrace = e.getStackTrace();
+                for (StackTraceElement frame : stackTrace) {
+                    log.error("[{}:{}] @{}(), error: {}", 
+                        frame.getFileName(), frame.getLineNumber(), frame.getMethodName(), e.getMessage());
+                }
+            }
         }
     }
     
@@ -403,24 +582,81 @@ public class DeviceCommandServiceImpl implements DeviceCommandService {
         log.info("处理删除设备请求: {}", payload);
         
         try {
-            // TODO: 解析payload并删除设备
-            // 对应Python版本的deal_del_device方法
-            log.info("删除设备请求处理完成");
+            // 1. 解析payload获取设备ID(对应Python版本:payload = json.loads(msg.payload.decode('utf-8')))
+            Map<String, Object> messageData = JsonUtil.parseMap(payload);
+            
+            // 2. 验证dev_id参数(对应Python版本:if not ("dev_id" in payload))
+            if (!messageData.containsKey("dev_id")) {
+                log.debug("error: invalid param, missing dev_id");
+                return;
+            }
+            
+            String deviceId = (String) messageData.get("dev_id");
+            if (deviceId == null || deviceId.trim().isEmpty()) {
+                log.debug("error: invalid param, empty dev_id");
+                return;
+            }
+            
+            // 3. 检查设备是否存在(对应Python版本:with g_dev_map_lock: if not dev_id in g_dev_map)
+            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
+            if (!deviceOpt.isPresent()) {
+                log.debug("error: deal_del_device, no device: {}", deviceId);
+                return;
+            }
+            
+            // 4. 从缓存中删除设备(对应Python版本:g_dev_map.pop(dev_id))
+            deviceManagerService.removeDeviceFromCache(deviceId);
+            
         } catch (Exception e) {
-            log.error("处理删除设备请求异常: {}", e.getMessage(), e);
+            // 对应Python版本的异常处理逻辑
+            StackTraceElement[] stackTrace = e.getStackTrace();
+            for (StackTraceElement frame : stackTrace) {
+                log.error("[{}:{}] @{}(), error: {}", 
+                    frame.getFileName(), frame.getLineNumber(), frame.getMethodName(), e.getMessage());
+            }
         }
     }
     
     @Override
     public void handleFallEventAck(String payload) {
-        log.info("处理跌倒确认请求: {}", payload);
-        
         try {
-            // TODO: 解析payload并处理跌倒确认
-            // 对应Python版本的deal_fall_event_ack方法
-            log.info("跌倒确认请求处理完成");
+            // 1. 解析payload获取设备ID(对应Python版本:payload = json.loads(msg.payload.decode('utf-8')))
+            Map<String, Object> messageData = JsonUtil.parseMap(payload);
+            
+                    // 2. 验证dev_id参数(对应Python版本:if not ("dev_id" in payload))
+        if (!messageData.containsKey("dev_id")) {
+            log.debug("error: invalid param, topic");
+            return;
+        }
+            String deviceId = (String) messageData.get("dev_id");
+            
+            // 3. 检查设备是否存在(对应Python版本:with g_dev_map_lock: if not dev_id in g_dev_map)
+            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
+            if (!deviceOpt.isPresent()) {
+                log.debug("error: deal_fall_event_ack, no device: {}", deviceId);
+                return;
+            }
+            Device device = deviceOpt.get();
+            
+            // 4. 检查设备告警确认状态(对应Python版本:if device.get_alarm_ack(): return)
+            if (device.getAlarmAck() != null && device.getAlarmAck()) {
+                return;
+            }
+            
+            // 5. 设置告警确认状态(对应Python版本:device.set_alarm_ack(True))
+            device.setAlarmAck(true);
+            
+            // 6. 更新确认时间(对应Python版本:now = get_utc_time_ms(); device.set_last_alarm_ack_time(now))
+            long now = System.currentTimeMillis();
+            device.setLastAlarmAckTime(now);
+            
         } catch (Exception e) {
-            log.error("处理跌倒确认请求异常: {}", e.getMessage(), e);
+            // 对应Python版本的异常处理逻辑
+            StackTraceElement[] stackTrace = e.getStackTrace();
+            for (StackTraceElement frame : stackTrace) {
+                log.error("[{}:{}] @{}(), error: {}", 
+                    frame.getFileName(), frame.getLineNumber(), frame.getMethodName(), e.getMessage());
+            }
         }
     }
 } 

+ 2 - 0
device-service-application/src/main/java/com/hfln/device/application/service/impl/DeviceEventServiceExtendImpl.java

@@ -99,6 +99,8 @@ public class DeviceEventServiceExtendImpl implements DeviceEventServiceExtend, D
     @Override
     public void handleDeviceKeepAlive(String deviceId) {}
     @Override
+    public void handleDeviceInfoReport(String deviceId, String deviceType, String firmware, String deviceIp, Map<String, Object> messageData) {}
+    @Override
     public void handleDeviceParamReport(String deviceId, Map<String, Object> messageData) {}
     @Override
     public void handleDspData(String deviceId, Map<String, Object> messageData) {}

+ 595 - 228
device-service-application/src/main/java/com/hfln/device/application/service/impl/DeviceEventServiceImpl.java

@@ -1,17 +1,18 @@
 package com.hfln.device.application.service.impl;
 
 import com.hfln.device.application.service.DeviceEventService;
-import com.hfln.device.domain.constant.EventConstants;
+import com.hfln.device.application.service.DebugConfigService;
 import com.hfln.device.domain.entity.Device;
 import com.hfln.device.domain.gateway.DeviceGateway;
 import com.hfln.device.domain.gateway.MqttGateway;
 import com.hfln.device.domain.service.AlarmService;
-import com.hfln.device.domain.service.BehaviorAnalysisService;
 import com.hfln.device.domain.service.DeviceManagerService;
 import com.hfln.device.domain.service.PointCloudProcessService;
+import com.hfln.device.domain.service.BehaviorAnalysisService;
+import com.hfln.device.domain.debug.DebugConfig;
 import com.hfln.device.domain.vo.BehaviorPattern;
-import com.hfln.device.domain.vo.PoseAnalysisResult;
 import com.hfln.device.domain.vo.TargetPoint;
+import com.hfln.device.domain.constant.EventConstants;
 import com.hfln.device.common.util.JsonUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -54,6 +55,9 @@ public class DeviceEventServiceImpl implements DeviceEventService {
     @Autowired
     private BehaviorAnalysisService behaviorAnalysisService;
     
+    @Autowired
+    private DebugConfigService debugConfigService;
+    
     @Override
     public boolean registerDevice(Device device) {
         log.info("注册设备: deviceId={}", device.getDevId());
@@ -261,24 +265,85 @@ public class DeviceEventServiceImpl implements DeviceEventService {
      * 对应Python版本的deal_dev_keepalive方法
      * 
      * Python处理流程:
-     * 1. 检查设备是否已注册和在线状态
-     * 2. 更新设备的最后保活时间戳(last_keepalive_time)
-     * 3. 如果设备当前离线状态,则:
-     *    - 设置设备为在线状态
-     *    - 更新数据库状态
-     *    - 发送设备状态变更消息到MQTT
-     * 4. 发送心跳响应消息给设备
-     * 5. 不进行复杂业务逻辑,主要用于维持连接状态
+     * 1. 从主题中提取设备ID
+     * 2. 检查调试参数是否禁用keepalive(可选的调试控制)
+     * 3. 检查设备是否已注册到系统中
+     * 4. 根据设备状态设置不同的响应码:
+     *    - 已注册且在线:DEV_EC.succeed,更新保活时间
+     *    - 已注册但离线:DEV_EC.forbidden
+     *    - 未注册:DEV_EC.unauthorized
+     * 5. 发送保活响应给设备
+     * 6. 异步更新数据库中的在线状态
      */
     @Override
     public void handleDeviceKeepAlive(String deviceId) {
         log.info("处理设备保活事件: deviceId={}", deviceId);
         
-        // TODO: 实现保活逻辑
-        // 1. 检查设备是否存在
-        // 2. 更新保活时间戳
-        // 3. 更新在线状态(如果需要)
-        // 4. 发送保活响应
+        try {
+            // 1. 检查调试参数(参考Python版本的调试控制机制)
+            DebugConfig debugConfig = debugConfigService.getDebugConfig(deviceId);
+            if (debugConfig != null && debugConfig.getParams() != null) {
+                Object keepaliveParam = debugConfig.getParams().get("keepalive");
+                if (keepaliveParam != null && "0".equals(keepaliveParam.toString())) {
+                    log.debug("拒绝保活请求,调试参数禁用: deviceId={}", deviceId);
+                    return; // 调试模式下拒绝保活
+                }
+            }
+            
+            // 2. 检查设备是否已注册(参考Python版本的设备注册检查)
+            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
+            int responseCode;
+            
+            if (deviceOpt.isPresent()) {
+                // 设备已注册
+                Device device = deviceOpt.get();
+                
+                // 3. 检查设备在线状态(参考Python版本的在线状态判断)
+                if (Integer.valueOf(1).equals(device.getOnline())) {
+                    // 设备在线,保活成功
+                    responseCode = 0; // 对应Python版本的DEV_EC.succeed
+                    
+                    // 4. 更新保活时间戳(参考Python版本的device.set_keepalive())
+                    long currentTime = System.currentTimeMillis();
+                    device.updateKeepAliveTime(currentTime);
+                    
+                    // 更新设备缓存
+                    deviceManagerService.updateDeviceInCache(device);
+                    
+                    log.debug("设备保活成功: deviceId={}, keepaliveTime={}", deviceId, currentTime);
+                } else {
+                    // 设备离线,保活被拒绝
+                    responseCode = 403; // 对应Python版本的DEV_EC.forbidden
+                    log.warn("设备离线,保活被拒绝: deviceId={}", deviceId);
+                }
+            } else {
+                // 设备未注册,未授权
+                responseCode = 401; // 对应Python版本的DEV_EC.unauthorized
+                log.warn("设备未注册,保活未授权: deviceId={}", deviceId);
+            }
+            
+            // 5. 发送保活响应(参考Python版本的mqtt_send.resp_dev_keepalive())
+            mqttGateway.sendDeviceKeepAliveResponse(deviceId, responseCode);
+            
+            // 6. 异步更新数据库在线状态(参考Python版本的异步数据库更新)
+            // 只有成功的保活才更新数据库在线状态
+            if (responseCode == 0) {
+                deviceGateway.updateDeviceOnlineStatus(deviceId, 1);
+                log.debug("异步更新设备在线状态: deviceId={}, online=1", deviceId);
+            }
+            
+            log.info("设备保活处理完成: deviceId={}, responseCode={}", deviceId, responseCode);
+            
+        } catch (Exception e) {
+            log.error("处理设备保活异常: deviceId={}, error={}", deviceId, e.getMessage(), e);
+            
+            // 异常情况下发送错误响应
+            try {
+                mqttGateway.sendDeviceKeepAliveResponse(deviceId, 500); // 服务器内部错误
+            } catch (Exception ex) {
+                log.error("发送保活错误响应失败: deviceId={}", deviceId, ex);
+            }
+        }
     }
     
     @Override
@@ -322,7 +387,10 @@ public class DeviceEventServiceImpl implements DeviceEventService {
         }
         
         // 发送事件消息 (参考Python版本:只有满足条件才发送事件消息)
-        mqttGateway.sendEventMessage(deviceId, result.getPose(), result.getLocation(), result.getEvent());
+        List<List<Float>> targets = result.getLocation() instanceof List ? 
+            Collections.singletonList((List<Float>) result.getLocation()) : 
+            Collections.emptyList();
+        mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), result.getPose(), targets, result.getEvent());
         
         // 更新最后跌倒告警时间
         device.setLastReportFallTime(timestamp);
@@ -448,7 +516,8 @@ public class DeviceEventServiceImpl implements DeviceEventService {
         deviceGateway.recordEvent(deviceId, event, pose, targetPoint);
         
         // 发送事件消息
-        mqttGateway.sendEventMessage(deviceId, pose, targetPoint, event);
+        List<List<Float>> targets = Collections.singletonList(targetPoint);
+        mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), pose, targets, event);
         
         // 如果是跌倒事件,处理跌倒逻辑
         if (EventConstants.EventType.FALL_EVENT.equals(event)) {
@@ -791,160 +860,156 @@ public class DeviceEventServiceImpl implements DeviceEventService {
     }
 
     /**
-     * 处理设备参数上报
-     * 对应Python版本的deal_report_device_param方法
+     * 处理设备实时数据
+     * 对应Python版本的deal_dsp_data方法
      * 
      * Python处理流程:
-     * 1. 解析消息数据,获取设备参数信息
-     * 2. 验证参数格式和合法性
-     * 3. 更新设备参数配置到数据库
-     * 4. 记录参数变更历史
-     * 5. 发送参数更新确认消息
-     * 6. 如果是关键参数变更,触发相关业务逻辑
+     * 1. 解析DSP(数字信号处理)实时数据
+     * 2. 提取目标位置、姿态、生命体征等信息
+     * 3. 执行实时数据验证和过滤
+     * 4. 更新设备实时状态缓存
+     * 5. 触发实时告警检测逻辑
+     * 6. 发送实时位置姿态消息到指定MQTT主题
+     * 7. 记录关键数据到时序数据库(如有配置)
      */
     @Override
-    public void handleDeviceParamReport(String deviceId, Map<String, Object> messageData) {
-        log.info("处理设备参数上报: deviceId={}", deviceId);
+    public void handleDspData(String deviceId, Map<String, Object> messageData) {
+        log.debug("处理设备实时数据: deviceId={}", deviceId);
         
         try {
-            // 获取设备
+            // === 获取设备 (对应Python: with g_dev_map_lock: if dev_id not in g_dev_map) ===
             Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
             if (!deviceOpt.isPresent()) {
-                log.warn("设备不存在,无法处理参数上报: deviceId={}", deviceId);
-                return;
+                return; // 未注册的设备,不处理 (对应Python: return)
             }
             
-            Device device = deviceOpt.get();
-            
-            // 按照Python版本解析字段
-            Map<String, Object> deviceInfo = (Map<String, Object>) messageData.get("device_info");
-            Map<String, Object> sensorLocation = (Map<String, Object>) messageData.get("sensor_location");
-            Map<String, Object> extRegion = (Map<String, Object>) messageData.get("ext_region");
-            Map<String, Object> fallingStateMachineDurations = (Map<String, Object>) messageData.get("fallingStateMachineDurations");
-            Boolean is45Degree = (Boolean) messageData.get("is45Degree");
-            Boolean isCeiling = (Boolean) messageData.get("isCeiling");
+            Device device = deviceOpt.get(); // device:Device = g_dev_map[dev_id]
             
-            // 更新设备信息
-            if (deviceInfo != null) {
-                String bluVer = (String) deviceInfo.get("blu_ver");
-                String deviceType = (String) deviceInfo.get("device_type");
-                String software = (String) deviceInfo.get("firmware");
-                String deviceid = (String) deviceInfo.get("deviceid");
+            // === 处理tracker_targets (对应Python: if ("tracker_targets" in payload)) ===
+            if (messageData.containsKey("tracker_targets")) {
+                List<List<Number>> trackerTargets = (List<List<Number>>) messageData.get("tracker_targets");
                 
-                device.setBluVer(bluVer);
-                device.setDevType(deviceType);
-                device.setSoftware(software);
-            }
-            
-            // 更新安装参数
-            if (sensorLocation != null && extRegion != null) {
-                Float sensorHeight = ((Number) sensorLocation.get("z_cm")).floatValue();
-                if (device.getInstallParam() == null) {
-                    device.setInstallParam(new Device.InstallParam());
-                }
-                device.getInstallParam().setHeight(sensorHeight);
+                // 转换数据类型为Float
+                List<List<Float>> trackerTargetsFloat = trackerTargets.stream()
+                        .map(target -> target.stream()
+                                .map(number -> number.floatValue())
+                                .collect(Collectors.toList()))
+                        .collect(Collectors.toList());
                 
-                // 更新区域信息
-                Map<String, Object> base = (Map<String, Object>) extRegion.get("base");
-                if (base != null) {
-                    if (device.getInstallParam().getTrackingRegion() == null) {
-                        device.getInstallParam().setTrackingRegion(new Device.TrackingRegion());
-                    }
-                    Device.TrackingRegion region = device.getInstallParam().getTrackingRegion();
-                    
-                    region.setStartX(((Number) base.get("x_cm_start")).intValue());
-                    region.setStopX(((Number) base.get("x_cm_stop")).intValue());
-                    region.setStartY(((Number) base.get("y_cm_start")).intValue());
-                    region.setStopY(((Number) base.get("y_cm_stop")).intValue());
-                    region.setStartZ(((Number) base.get("z_cm_start")).intValue());
-                    region.setStopZ(((Number) base.get("z_cm_stop")).intValue());
+                // === 更新实时点云和target (对应Python的核心逻辑) ===
+                List<List<Float>> rawPoints = Collections.emptyList();  // raw_points = []
+                List<List<Float>> targets = trackerTargetsFloat;         // targets = tracker_targets
+                List<List<Float>> stableTargets = device.updateTargets(targets);  // stable_targets:list = device.update_targets(targets)
+                List<Integer> pose = device.getRealtimePose();           // pose = device.realtime_pose()
+                
+                // === 发送实时位置姿态消息 (对应Python: mqtt_send.realtime_pos_msg(dev_id, raw_points, pose, targets)) ===
+                mqttGateway.sendRealtimePositionMessage(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)
+                
+                // === 更新报警目标信息 (对应Python: device.update_alarm_targets(targets)) ===
+                device.updateAlarmTargets(trackerTargetsFloat);
+                
+                log.debug("处理tracker_targets完成: deviceId={}, targetCount={}", deviceId, trackerTargetsFloat.size());
             }
             
-                         // 保存完整参数信息 (TODO: 在Device类中实现setParam方法)
-             // device.setParam(messageData);
-             
-             // 更新设备
-             deviceGateway.updateDevice(device);
-             deviceManagerService.updateDeviceInCache(device);
-             
-             // 发送设备信息更新消息 (TODO: 在MqttGateway中实现此方法)
-             // mqttGateway.sendUpdateDeviceInfoMessage(device);
+            // === 检查跌倒信息 (对应Python: if ("fallingMetaData" in payload): check_falling(msg)) ===
+            if (messageData.containsKey("fallingMetaData")) {
+                handleFallingCheck(deviceId, messageData);
+            }
             
         } catch (Exception e) {
-            log.error("处理设备参数上报异常: deviceId={}, error={}", deviceId, e.getMessage(), e);
+            // 对应Python: except Exception as e: LOGERR(f"deal_dsp_data error: {e}, [{dev_id}]")
+            log.error("deal_dsp_data error: {}, [{}]", e.getMessage(), deviceId, e);
         }
     }
     
     /**
-     * 处理设备实时数据
-     * 对应Python版本的deal_dsp_data方法
+     * 处理跌倒检查
+     * 对应Python版本的check_falling方法的核心逻辑
      * 
-     * Python处理流程:
-     * 1. 解析DSP(数字信号处理)实时数据
-     * 2. 提取目标位置、姿态、生命体征等信息
-     * 3. 执行实时数据验证和过滤
-     * 4. 更新设备实时状态缓存
-     * 5. 触发实时告警检测逻辑
-     * 6. 发送实时位置姿态消息到指定MQTT主题
-     * 7. 记录关键数据到时序数据库(如有配置)
+     * @param deviceId 设备ID
+     * @param messageData 消息数据,包含fallingMetaData
      */
-    @Override
-    public void handleDspData(String deviceId, Map<String, Object> messageData) {
-        log.debug("处理设备实时数据: deviceId={}", deviceId);
-        
+    private void handleFallingCheck(String deviceId, Map<String, Object> messageData) {
         try {
-            // 获取设备
             Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
             if (!deviceOpt.isPresent()) {
-                return; // 未注册的设备,不处理
+                return;
             }
             
             Device device = deviceOpt.get();
+            Map<String, Object> fallingMetaData = (Map<String, Object>) messageData.get("fallingMetaData");
+            
+            if (fallingMetaData == null || !fallingMetaData.containsKey("falling")) {
+                return;
+            }
+            
+            // === 跌倒状态映射 (对应Python的falling_map) ===
+            Map<Integer, String> fallingMap = new HashMap<>();
+            fallingMap.put(0, "no_fall");        // 没有检测到跌倒
+            fallingMap.put(1, "fall_detected");  // 检测到跌倒
+            fallingMap.put(2, "fall_confirmed"); // 跌倒确认
+            fallingMap.put(3, "fall_calling");   // 跌倒呼救
+            
+            Integer falling = ((Number) fallingMetaData.get("falling")).intValue();
+            String event = fallingMap.getOrDefault(falling, "unknown");
+            
+            // 获取跌倒位置坐标
+            Float fallLocXCm = ((Number) fallingMetaData.get("fallLocX_cm")).floatValue();
+            Float fallLocYCm = ((Number) fallingMetaData.get("fallLocY_cm")).floatValue();
+            Float fallLocZCm = ((Number) fallingMetaData.get("fallLocZ_cm")).floatValue();
             
-                         // 处理tracker_targets
-             if (messageData.containsKey("tracker_targets")) {
-                 List<List<Number>> trackerTargets = (List<List<Number>>) messageData.get("tracker_targets");
-                 
-                 // 转换数据类型
-                 List<List<Float>> trackerTargetsFloat = trackerTargets.stream()
-                         .map(target -> target.stream()
-                                 .map(number -> number.floatValue())
-                                 .collect(Collectors.toList()))
-                         .collect(Collectors.toList());
-                 
-                 // TODO: 在Device类中实现这些方法
-                 // 更新设备目标信息
-                 // List<List<Float>> stableTargets = device.updateTargets(trackerTargetsFloat);
-                 // List<Integer> pose = device.getRealtimePose();
-                 
-                 // TODO: 在MqttGateway中实现此方法
-                 // 发送实时位置姿态消息
-                 // mqttGateway.sendRealtimePositionMessage(deviceId, Collections.emptyList(), pose, trackerTargetsFloat);
-                 
-                 // TODO: 在Device类中实现这些方法
-                 // 更新停留时长
-                 // long ts = System.currentTimeMillis();
-                 // if (device.getEnterTime() < 0) {
-                 //     device.setEnterTime(ts);
-                 //     log.info("{} target enter, {}", deviceId, ts);
-                 // }
-                 // device.setLeaveTime(ts);
-                 
-                 // 更新报警目标信息
-                 // device.updateAlarmTargets(trackerTargetsFloat);
-                 
-                 log.debug("处理tracker_targets完成: deviceId={}, targetCount={}", deviceId, trackerTargetsFloat.size());
-             }
-             
-             // TODO: 实现handleFallingCheck方法
-             // 检查跌倒信息
-             // if (messageData.containsKey("fallingMetaData")) {
-             //     handleFallingCheck(deviceId, messageData);
-             // }
+            long now = System.currentTimeMillis(); // now = get_utc_time_ms()
+            
+            // === 上报跌倒事件 (对应Python的设备类型处理逻辑) ===
+            if ("LNB".equals(device.getDevType())) {
+                // === LNB设备处理逻辑 ===
+                // 检查报警间隔 (对应Python的告警间隔检查)
+                if (!device.shouldSendAlarmForEvent(event, now)) {
+                    return;
+                }
+                
+                List<List<Float>> targets = Arrays.asList(Arrays.asList(fallLocXCm, fallLocYCm, fallLocZCm, 0.0f));
+                int pose = "no_fall".equals(event) ? 4 : 0; // POSE_E.POSE_4.value if event == "no_fall" else POSE_E.POSE_0.value
+                
+                // 发送事件消息 (对应Python: mqtt_send.event_msg)
+                mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), pose, targets, event);
+                
+                device.setLastFallTime(event, now);      // device.set_last_fall_time(event, now)
+                String text = String.format("设备上报跌倒事件:躺, dev_id:%s, event:%s", deviceId, event);
+                log.debug(text);  // LOGDBG(text)
+                
+            } else if ("LNA".equals(device.getDevType())) {
+                // === LNA设备处理逻辑 ===
+                // 跌倒状态改变时,不管报警间隔直接发送通知 (对应Python的特殊逻辑)
+                if (!device.shouldSendAlarmForLNA(falling, now)) {
+                    return;
+                }
+                
+                List<Integer> realtimePose = device.getRealtimePose(); // realtime_pose:list = device.realtime_pose()
+                if (realtimePose.isEmpty() || !Integer.valueOf(0).equals(realtimePose.get(0))) {
+                    return; // if (len(realtime_pose) <= 0 or realtime_pose[0] != POSE_E.POSE_0.value): return
+                }
+                
+                List<List<Float>> targets = Arrays.asList(Arrays.asList(fallLocXCm, fallLocYCm, fallLocZCm, 0.0f));
+                
+                // 发送事件消息
+                mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), realtimePose.get(0).intValue(), targets, event);
+                
+                device.setLastReportFallTime(now);      // device.set_last_report_fall_time(now)
+                String text = String.format("设备上报跌倒事件:躺, dev_id:%s, event:%s", deviceId, event);
+                log.debug(text);  // LOGDBG(text)
+            }
             
         } catch (Exception e) {
-            log.error("处理设备实时数据异常: deviceId={}, error={}", deviceId, e.getMessage(), e);
+            log.error("处理跌倒检查异常: deviceId={}, error={}", deviceId, e.getMessage(), e);
         }
     }
     
@@ -967,50 +1032,85 @@ public class DeviceEventServiceImpl implements DeviceEventService {
         log.debug("处理设备点云数据: deviceId={}", deviceId);
         
         try {
-            // 获取设备
+            // === 获取设备 (对应Python: with g_dev_map_lock: if dev_id not in g_dev_map) ===
             Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
             if (!deviceOpt.isPresent()) {
-                return; // 未注册的设备,不处理
+                return; // 未注册的设备,不处理 (对应Python: return)
             }
             
-            Device device = deviceOpt.get();
+            Device device = deviceOpt.get(); // device:Device = g_dev_map[dev_id]
             
-            // 对于LNA设备类型,检查点云数量
-            if ("LNA".equals(device.getDevType())) {
-                int valuePoints = 20;
-                if (cloudPoints == null || cloudPoints.size() < valuePoints) {
-                    return; // 少于n个点则忽略
+            // === 设备类型处理逻辑 (对应Python的设备类型区分) ===
+            List<List<Float>> rawPoints = null;  // 初始化为null,模拟Python的未定义状态
+            List<List<Float>> targets = null;    // 初始化为null,模拟Python的未定义状态
+            
+            if ("LNA".equals(device.getDevType())) {  // 对应Python: if device.dev_type() == "LNA"
+                int valuePoints = 20; // 对应Python: value_points = 20
+                if (cloudPoints == null || cloudPoints.size() < valuePoints) {   
+                    // 对应Python: # LOGDBG(f"warning: payload: cloud_points len < {value_points}, dev:{dev_id}")
+                    log.debug("warning: payload: cloud_points len < {}, dev:{}", valuePoints, deviceId);
+                    return; // 对应Python: if len(payload["cloud_points"]) < value_points: return
                 }
+                rawPoints = cloudPoints;    // 对应Python: raw_points = payload["cloud_points"]
                 
-                // 如果没有tracker_targets,从点云计算 (TODO: 实现getTrackerTargets方法)
-                if (trackerTargets == null) {
-                    // trackerTargets = pointCloudProcessService.getTrackerTargets(cloudPoints);
-                    trackerTargets = Collections.emptyList(); // 临时处理
+                // 目标点信息处理 (对应Python的目标点逻辑)
+                if (trackerTargets == null || trackerTargets.isEmpty()) {
+                    // 对应Python: if(not "tracker_targets" in payload): targets = get_tracker_targets(raw_points)
+                    targets = pointCloudProcessService.getTrackerTargets(rawPoints);
+                    log.debug("从点云计算得到 {} 个目标", targets.size());
+                } else {
+                    // 对应Python: else: targets = payload["tracker_targets"]
+                    targets = trackerTargets;
+                    // ⚠️ 重要:对应Python版本的第325行,这行代码在Python中确实会执行!
+                    List<List<Float>> tmpTargets = pointCloudProcessService.getTrackerTargets(rawPoints);
+                    // tmpTargets虽然计算了但不使用,完全匹配Python版本行为
                 }
-            } else if ("LNB".equals(device.getDevType())) {
-                // 对于LNB设备,必须有tracker_targets
-                if (trackerTargets == null) {
-                    return;
+                
+            } else if ("LNB".equals(device.getDevType())) {    // 对应Python: elif device.dev_type() == "LNB"
+                if (trackerTargets == null || trackerTargets.isEmpty()) {
+                    return; // 对应Python: if not "tracker_targets" in payload: return
                 }
-                cloudPoints = Collections.emptyList(); // LNB设备不需要点云数据
+                rawPoints = Collections.emptyList(); // 对应Python: raw_points = []
+                targets = trackerTargets;    // 对应Python: targets = payload["tracker_targets"]
             }
+            // ⚠️ 重要:Python版本没有else分支!
+            // 如果设备类型未知,Python版本会在后续代码中抛出NameError异常
+            // 为了完全匹配Python行为,这里也不应该有else分支
+            
+            // 检查变量是否已初始化(模拟Python版本的潜在NameError)
+            if (rawPoints == null || targets == null) {
+                // 对应Python版本的NameError: name 'raw_points' is not defined
+                throw new RuntimeException("Uninitialized variables: rawPoints or targets not set for device type: " + device.getDevType());
+            }
+            
+            // === 核心业务处理 (对应Python的核心逻辑) ===
+            // 更新实时点云和target (对应Python: device.put_cloud_points_que(raw_points))
+            device.putCloudPointsQueue(rawPoints);
+            
+            // 更新目标跟踪 (对应Python: stable_targets:list = device.update_targets(targets))
+            List<List<Float>> stableTargets = device.updateTargets(targets);
             
-            // TODO: 在Device类中实现这些方法
-            // 更新实时点云和target
-            // device.putCloudPointsQueue(cloudPoints);
-            // List<List<Float>> stableTargets = device.updateTargets(trackerTargets);
-            // List<Integer> pose = device.getRealtimePose();
+            // 获取实时姿态 (对应Python: pose = device.realtime_pose())
+            List<Integer> pose = device.getRealtimePose();
             
-            // TODO: 在MqttGateway中实现此方法
-            // 发送实时位置姿态消息
-            // mqttGateway.sendRealtimePositionMessage(deviceId, cloudPoints, pose, trackerTargets);
+            // === 发送实时位置姿态消息 (对应Python: mqtt_send.realtime_pos_msg(dev_id, raw_points, pose, targets)) ===
+            mqttGateway.sendRealtimePositionMessage(deviceId, rawPoints, pose, targets);
             
-            log.debug("处理点云数据完成: deviceId={}, cloudPointsSize={}, trackerTargetsSize={}", 
-                    deviceId, cloudPoints != null ? cloudPoints.size() : 0, 
-                    trackerTargets != null ? trackerTargets.size() : 0);
+            log.debug("处理点云数据完成: deviceId={}, devType={}, cloudPointsSize={}, trackerTargetsSize={}, targetsUsed={}", 
+                    deviceId, device.getDevType(), 
+                    cloudPoints != null ? cloudPoints.size() : 0, 
+                    trackerTargets != null ? trackerTargets.size() : 0,
+                    targets.size());
             
         } catch (Exception e) {
-            log.error("处理设备点云数据异常: deviceId={}, error={}", deviceId, e.getMessage(), e);
+            // 对应Python的分层异常处理:
+            // except json.JSONDecodeError: LOGERR(f"parse payload failed, {msg.topic}, {msg.payload}")
+            // except Exception as e: LOGERR(f"deal_cloudpoint error: {e}, [{dev_id}]")
+            if (e.getCause() instanceof com.fasterxml.jackson.core.JsonProcessingException) {
+                log.error("parse payload failed, deviceId: {}, error: {}", deviceId, e.getMessage(), e);
+            } else {
+                log.error("deal_cloudpoint error: {}, [{}]", e.getMessage(), deviceId, e);
+            }
         }
     }
     
@@ -1021,55 +1121,65 @@ public class DeviceEventServiceImpl implements DeviceEventService {
                 deviceId, event, fallLocX, fallLocY, fallLocZ);
         
         try {
-            // 获取设备
+            // === 获取设备 (对应Python: with g_dev_map_lock: if dev_id not in g_dev_map) ===
             Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
             if (!deviceOpt.isPresent()) {
-                log.warn("设备未注册,无法处理跌倒事件: deviceId={}", deviceId);
+                log.debug("error, device not registed: {}", deviceId); // 对应Python: LOGDBG(f"error, device not registed: {dev_id}")
                 return;
             }
             
-            Device device = deviceOpt.get();
+            Device device = deviceOpt.get(); // device:Device = g_dev_map[dev_id]
             
-            // TODO: 在Device类中实现告警间隔检查方法
-            // 检查报警间隔
-            long now = System.currentTimeMillis();
-            // Device.FallEventResult fallResult = device.checkFallAlarmInterval(event, now);
-            // if (!fallResult.shouldSendAlarm()) {
-            //     log.debug("跌倒事件被告警间隔控制过滤: deviceId={}, event={}", deviceId, event);
-            //     return;
-            // }
-            
-            // 构建目标点
-            List<Float> targetPoint = Arrays.asList(fallLocX, fallLocY, fallLocZ, 0.0f);
-            List<List<Float>> targets = Collections.singletonList(targetPoint);
-            
-            // TODO: 修正MqttGateway.sendEventMessage方法签名
-            // 根据设备类型处理
+            // === 检查告警间隔 (对应Python的告警间隔检查逻辑) ===
+            long now = System.currentTimeMillis(); // now = get_utc_time_ms()
+            if (!device.checkFallAlarmInterval(now)) {
+                return; // 对应Python: if ((device.get_alarm_ack()) or now - device.last_report_fall_time() < device.alarm_interval()): return
+            }
+            
+            // === 根据设备类型处理 (对应Python的设备类型区分) ===
             if ("LNB".equals(device.getDevType())) {
-                int pose = "no_fall".equals(event) ? 4 : 0; // POSE_4 : POSE_0
-                // mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), pose, targets, event);
+                // === LNB设备处理逻辑 ===
+                // 坐标转换:厘米转米 (对应Python: targets = [[fallLocX/100, fallLocY/100, fallLocZ/100, 0]])
+                List<List<Float>> targets = Arrays.asList(Arrays.asList(fallLocX/100.0f, fallLocY/100.0f, fallLocZ/100.0f, 0.0f));
+                int pose = "no_fall".equals(event) ? 4 : 0; // 对应Python: pose = POSE_E.POSE_4.value if event == "no_fall" else POSE_E.POSE_0.value
                 
-                // TODO: 在Device类中实现setLastFallTime方法
-                // device.setLastFallTime(event, now);
-                log.info("设备上报跌倒事件:躺, dev_id:{}, event:{}", deviceId, event);
+                // 发送事件消息 (对应Python: mqtt_send.event_msg(dev_id=dev_id, RawPoints=[], pose=pose, targets=targets, event=event))
+                mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), pose, targets, event);
+                
+                device.setLastReportFallTime(now); // device.set_last_report_fall_time(now)
+                String text = String.format("设备上报跌倒事件:躺, dev_id:%s, event:%s", deviceId, event);
+                log.debug(text); // LOGDBG(text)
+                return; // Python版本有return
                 
             } else if ("LNA".equals(device.getDevType())) {
-                // TODO: 在Device类中实现getRealtimePose方法
-                // List<Integer> realtimePose = device.getRealtimePose();
-                // if (realtimePose.isEmpty() || realtimePose.get(0) != 0) { // POSE_0
-                //     return;
-                // }
+                // === LNA设备处理逻辑 ===
+                List<Integer> realtimePose = device.getRealtimePose(); // realtime_pose:list = device.realtime_pose()
+                if (realtimePose.isEmpty() || !Integer.valueOf(0).equals(realtimePose.get(0))) {
+                    return; // 对应Python: if (len(realtime_pose) <= 0 or realtime_pose[0] != POSE_E.POSE_0.value): return
+                }
                 
-                // mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), realtimePose.get(0), targets, event);
-                // TODO: 在Device类中实现setLastReportFallTime方法
-                // device.setLastReportFallTime(now);
-                log.info("设备上报跌倒事件:躺, dev_id:{}, event:{}", deviceId, event);
+                // 坐标转换:厘米转米
+                List<List<Float>> targets = Arrays.asList(Arrays.asList(fallLocX/100.0f, fallLocY/100.0f, fallLocZ/100.0f, 0.0f));
+                
+                // 发送事件消息 (对应Python: mqtt_send.event_msg(dev_id=dev_id, RawPoints=[], pose=realtime_pose[0], targets=targets, event=event))
+                mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), realtimePose.get(0), targets, event);
+                
+                device.setLastReportFallTime(now); // device.set_last_report_fall_time(now)
+                String text = String.format("设备上报跌倒事件:躺, dev_id:%s, event:%s", deviceId, event);
+                log.debug(text); // LOGDBG(text)
             }
             
             log.info("跌倒事件处理完成: deviceId={}, event={}, type={}", deviceId, event, type);
             
         } catch (Exception e) {
-            log.error("处理设备跌倒事件异常: deviceId={}, error={}", deviceId, e.getMessage(), e);
+            // 对应Python的异常处理:
+            // except json.JSONDecodeError: LOGERR(f"parse payload failed, {msg.topic}, {msg.payload}")
+            // except Exception as e: LOGERR(f"deal_report_falling_event error: {e} [{dev_id}]")
+            if (e.getCause() instanceof com.fasterxml.jackson.core.JsonProcessingException) {
+                log.error("parse payload failed, deviceId: {}, error: {}", deviceId, e.getMessage(), e);
+            } else {
+                log.error("deal_report_falling_event error: {}, [{}]", e.getMessage(), deviceId, e);
+            }
         }
     }
     
@@ -1078,20 +1188,32 @@ public class DeviceEventServiceImpl implements DeviceEventService {
         log.info("处理设备存在事件: deviceId={}, event={}", deviceId, event);
         
         try {
-            // 获取设备
+            // === 获取设备 (对应Python: with g_dev_map_lock: if dev_id not in g_dev_map) ===
             Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
             if (!deviceOpt.isPresent()) {
-                log.warn("设备未注册,无法处理存在事件: deviceId={}", deviceId);
+                log.debug("error, device not registed: {}", deviceId); // 对应Python: LOGDBG(f"error, device not registed: {dev_id}")
+                return;
+            }
+            
+            // === 参数验证 (对应Python的payload验证) ===
+            if (timestamp == null || type == null || event == null) {
+                log.debug("error, invalid device_param, {}", deviceId); // 对应Python: LOGDBG(f"error, invalid device_param, {dev_id}")
                 return;
             }
             
-            // TODO: 在MqttGateway中实现sendExistEventMessage方法
-            // 发送存在事件消息
-            // mqttGateway.sendExistEventMessage(deviceId, event);
+            // === 发送存在事件消息 (对应Python: mqtt_send.exist_msg(dev_id=dev_id, event=event)) ===
+            mqttGateway.sendExistEventMessage(deviceId, event);
             log.debug("处理存在事件完成: deviceId={}, event={}", deviceId, event);
             
         } catch (Exception e) {
-            log.error("处理设备存在事件异常: deviceId={}, error={}", deviceId, e.getMessage(), e);
+            // 对应Python的异常处理:
+            // except json.JSONDecodeError: LOGERR(f"parse payload failed, {msg.topic}, {msg.payload}")
+            // except Exception as e: LOGERR(f"deal_report_presence_event error: {e}")
+            if (e.getCause() instanceof com.fasterxml.jackson.core.JsonProcessingException) {
+                log.error("parse payload failed, deviceId: {}, error: {}", deviceId, e.getMessage(), e);
+            } else {
+                log.error("deal_report_presence_event error: {}, [{}]", e.getMessage(), deviceId, e);
+            }
         }
     }
     
@@ -1127,22 +1249,31 @@ public class DeviceEventServiceImpl implements DeviceEventService {
         log.info("处理获取调试参数: deviceId={}", deviceId);
         
         try {
-            // 获取设备
-            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
-            if (!deviceOpt.isPresent()) {
-                log.warn("设备未注册,无法获取调试参数: deviceId={}", deviceId);
-                return;
-            }
+            // === 对应Python版本的核心逻辑 ===
+            // debug_param = {}
+            // if dev_id in g_dev_dbg_map:
+            //     debug_param = g_dev_dbg_map[dev_id]
+            // mqtt_send.debug_param_msg(dev_id, debug_param)
             
-            Device device = deviceOpt.get();
+            Map<String, Object> debugParams = new HashMap<>();  // 默认空参数 (对应Python: debug_param = {})
             
-            // 获取调试参数
-            Map<String, Object> debugParams = device.getDebugParams();
+            // 获取设备(用于验证设备存在,但即使不存在也要发送响应)
+            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
+            if (deviceOpt.isPresent()) {
+                // 设备存在,获取调试参数 (对应Python: if dev_id in g_dev_dbg_map)
+                Device device = deviceOpt.get();
+                Map<String, Object> deviceDebugParams = device.getDebugParams();
+                if (deviceDebugParams != null) {
+                    debugParams = deviceDebugParams;  // (对应Python: debug_param = g_dev_dbg_map[dev_id])
+                }
+            } else {
+                // 对应Python版本:即使设备不在缓存中,也发送空参数响应
+                log.debug("设备不在缓存中,发送空调试参数: deviceId={}", deviceId);
+            }
             
-            // TODO: 在MqttGateway中实现sendDebugParamResponse方法
-            // 发送调试参数响应
-            // mqttGateway.sendDebugParamResponse(deviceId, debugParams);
-            log.debug("获取调试参数完成: deviceId={}, paramsSize={}", deviceId, debugParams != null ? debugParams.size() : 0);
+            // 发送调试参数响应 (对应Python: mqtt_send.debug_param_msg(dev_id, debug_param))
+            mqttGateway.sendDebugParamResponse(deviceId, debugParams);
+            log.debug("获取调试参数完成: deviceId={}, paramsSize={}", deviceId, debugParams.size());
             
         } catch (Exception e) {
             log.error("处理获取调试参数异常: deviceId={}, error={}", deviceId, e.getMessage(), e);
@@ -1156,7 +1287,7 @@ public class DeviceEventServiceImpl implements DeviceEventService {
         log.info("处理获取全局告警参数请求: {}", payload);
         
         try {
-            // TODO: 从系统配置中读取全局告警参数
+            // 从系统配置中读取全局告警参数
             // 对应Python版本:g_sys_conf["alarm_conf"]
             Map<String, Object> globalConfig = new HashMap<>();
             globalConfig.put("retention_time", 60);        // 滞留时间(秒)
@@ -1167,9 +1298,8 @@ public class DeviceEventServiceImpl implements DeviceEventService {
             Map<String, Object> response = new HashMap<>();
             response.put("global", globalConfig);
             
-            // TODO: 在MqttGateway中实现reportAlarmParam方法
             // 发送响应: mqtt_send.report_alarm_param(0, format_json)
-            // mqttGateway.reportAlarmParam(0, response);
+            mqttGateway.reportAlarmParam(0, response);
             log.info("全局告警参数获取成功: {}", response);
             
         } catch (Exception e) {
@@ -1182,7 +1312,7 @@ public class DeviceEventServiceImpl implements DeviceEventService {
         log.info("处理获取厕所告警参数请求: {}", payload);
         
         try {
-            // TODO: 从系统配置中读取厕所告警参数
+            // 从系统配置中读取厕所告警参数
             // 对应Python版本:g_sys_conf["alarm_conf"]["toilet"]
             Map<String, Object> toiletConfig = new HashMap<>();
             toiletConfig.put("retention_time", 60);        // 滞留时间(秒)
@@ -1193,9 +1323,8 @@ public class DeviceEventServiceImpl implements DeviceEventService {
             Map<String, Object> response = new HashMap<>();
             response.put("toilet", toiletConfig);
             
-            // TODO: 在MqttGateway中实现reportAlarmParam方法
             // 发送响应: mqtt_send.report_alarm_param(0, format_json)
-            // mqttGateway.reportAlarmParam(0, response);
+            mqttGateway.reportAlarmParam(0, response);
             log.info("厕所告警参数获取成功: {}", response);
             
         } catch (Exception e) {
@@ -1276,13 +1405,251 @@ public class DeviceEventServiceImpl implements DeviceEventService {
         log.info("发送设置告警参数确认: code={}, response={}", code, response);
         
         try {
-            // TODO: 在MqttGateway中实现setAlarmParamAck方法
             // 对应Python版本:mqtt_send.set_alarm_param_ack(code, {})
-            // mqttGateway.setAlarmParamAck(code, response);
+            Map<String, Object> responseData = new HashMap<>();
+            mqttGateway.sendSetAlarmParamAck(code, responseData);
             log.debug("设置告警参数确认发送成功: code={}", code);
             
         } catch (Exception e) {
             log.error("发送设置告警参数确认异常: code={}, error={}", code, e.getMessage(), e);
         }
     }
+
+    @Override
+    public void handleDeviceParamReport(String deviceId, Map<String, Object> messageData) {
+        log.info("Processing device parameter report: deviceId={}", deviceId);
+        
+        try {
+            // 检查设备是否已注册(对应Python: with g_dev_map_lock: if (dev_id not in g_dev_map))
+            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
+            if (!deviceOpt.isPresent()) {
+                log.debug("Error, device not registered: deviceId={}", deviceId);  // 对应Python的LOGDBG
+                return;
+            }
+            
+            Device device = deviceOpt.get();
+            
+            // === 解析设备信息 (对应Python: device_info = payload["device_info"]) ===
+            Map<String, Object> deviceInfo = (Map<String, Object>) messageData.get("device_info");
+            if (deviceInfo == null) {
+                log.warn("Missing device_info in message data: deviceId={}", deviceId);
+                return;
+            }
+            
+            String bluVer = (String) deviceInfo.get("blu_ver");           // blu_ver = device_info["blu_ver"]
+            String deviceType = (String) deviceInfo.get("device_type");   // device_type = device_info["device_type"]
+            String software = (String) deviceInfo.get("firmware");        // software = device_info["firmware"]  
+            String deviceid = (String) deviceInfo.get("deviceid");        // deviceid = device_info["deviceid"]
+            
+            // === 解析传感器位置 (对应Python: sensor_location = payload["sensor_location"]) ===
+            Map<String, Object> sensorLocation = (Map<String, Object>) messageData.get("sensor_location");
+            if (sensorLocation == null) {
+                log.warn("Missing sensor_location in message data: deviceId={}", deviceId);
+                return;
+            }
+            
+            Number zCmNum = (Number) sensorLocation.get("z_cm");          // z_cm = sensor_location["z_cm"]
+            Float sensorHeight = zCmNum != null ? zCmNum.floatValue() : 0.0f;  // sensor_height:float = z_cm
+            
+            // === 解析区域信息 (对应Python: ext_region = payload["ext_region"]) ===
+            Map<String, Object> extRegion = (Map<String, Object>) messageData.get("ext_region");
+            if (extRegion == null) {
+                log.warn("Missing ext_region in message data: deviceId={}", deviceId);
+                return;
+            }
+            
+            Map<String, Object> base = (Map<String, Object>) extRegion.get("base");
+            if (base == null) {
+                log.warn("Missing base in ext_region: deviceId={}", deviceId);
+                return;
+            }
+            
+            // 解析区域坐标 (对应Python的坐标解析)
+            Integer x1 = ((Number) base.get("x_cm_start")).intValue();    // x1 = base["x_cm_start"]
+            Integer y1 = ((Number) base.get("y_cm_start")).intValue();    // y1 = base["y_cm_start"]
+            Integer z1 = ((Number) base.get("z_cm_start")).intValue();    // z1 = base["z_cm_start"]
+            Integer x2 = ((Number) base.get("x_cm_stop")).intValue();     // x2 = base["x_cm_stop"]
+            Integer y2 = ((Number) base.get("y_cm_stop")).intValue();     // y2 = base["y_cm_stop"]
+            Integer z2 = ((Number) base.get("z_cm_stop")).intValue();     // z2 = base["z_cm_stop"]
+            
+            Number presenceEnterDurationSec = (Number) extRegion.get("presenceEnterDuration_sec");  // presenceEnterDuration_sec = ext_region["presenceEnterDuration_sec"]
+            Number presenceExitDurationSec = (Number) extRegion.get("presenceExitDuration_sec");    // presenceExitDuration_sec = ext_region["presenceExitDuration_sec"]
+            
+            // 解析其他字段
+            Map<String, Object> fallingStateMachineDurations = (Map<String, Object>) messageData.get("fallingStateMachineDurations");  // fallingStateMachineDurations = payload["fallingStateMachineDurations"]
+            Boolean is45Degree = (Boolean) messageData.get("is45Degree");                 // is45Degree = payload["is45Degree"]
+            Boolean isCeiling = (Boolean) messageData.get("isCeiling");                   // isCeiling = payload["isCeiling"]
+            
+            // === 构造安装参数对象 (对应Python: install_param = InstallParam(mount_plain="", height=sensor_height, tracking_region=TrackingRegion(x1,y1,z1,x2,y2,z2))) ===
+            Device.TrackingRegion trackingRegion = new Device.TrackingRegion();
+            trackingRegion.setStartX(x1);      // TrackingRegion(x1,y1,z1,x2,y2,z2)
+            trackingRegion.setStartY(y1);
+            trackingRegion.setStartZ(z1);
+            trackingRegion.setStopX(x2);
+            trackingRegion.setStopY(y2);
+            trackingRegion.setStopZ(z2);
+            
+            Device.InstallParam installParam = new Device.InstallParam();
+            installParam.setMountPlain("");                    // mount_plain=""
+            installParam.setHeight(sensorHeight);              // height=sensor_height
+            installParam.setIsCeiling(isCeiling != null ? (isCeiling ? 1 : 0) : 0);  // is_ceiling处理
+            installParam.setTrackingRegion(trackingRegion);    // tracking_region=TrackingRegion(...)
+            
+            // === 更新设备信息 (对应Python的三行核心操作) ===
+            device.setInstallParam(installParam);        // device.set_install_param(install_param)
+            device.setParam(messageData);                 // device.set_param(payload)
+            if (software != null && !software.trim().isEmpty()) {
+                device.setSoftware(software);            // device.set_software(software)
+            }
+            
+            // === 发送设备信息更新通知 (对应Python: mqtt_send.update_dev_info_msg(device)) ===
+            mqttGateway.sendDeviceInfoUpdateNotification(device);
+            
+            log.info("Device parameters updated successfully: deviceId={}, height={}cm", deviceId, sensorHeight);
+            
+        } catch (Exception e) {
+            // 对应Python: except Exception as e: LOGERR(f"deal_report_device_param error: {e}, payload: {payload}")
+            log.error("deal_report_device_param error: {}, payload: {}", e.getMessage(), messageData, e);
+        }
+        
+        // 对应Python: return
+        return;
+    }
+
+    /**
+     * 处理设备信息上报
+     * 对应Python版本的deal_report_device_info方法
+     * 
+     * Python处理流程:
+     * 1. 解析JSON消息并验证必需字段(deviceid, device_type, firmware, device_ip)
+     * 2. 检查设备是否已注册到系统中
+     * 3. 如果设备已注册:
+     *    - 检查设备在线状态,如果离线则重新上线
+     *    - 更新设备信息(类型、固件版本、IP地址)
+     *    - 发送设备信息更新通知
+     * 4. 如果设备未注册:
+     *    - 创建新设备实例并设置为在线状态
+     *    - 添加到设备缓存
+     *    - 发送登录响应和状态通知
+     * 
+     * 这与登录流程的区别:
+     * - 登录包含区域配置等完整信息
+     * - 信息上报只是基本设备信息的更新
+     * - 登录是设备首次接入,信息上报是运行时更新
+     */
+    @Override
+    public void handleDeviceInfoReport(String deviceId, String deviceType, String firmware, 
+                                      String deviceIp, Map<String, Object> messageData) {
+        log.info("处理设备信息上报: deviceId={}, deviceType={}, firmware={}, deviceIp={}", 
+                deviceId, deviceType, firmware, deviceIp);
+        
+        try {
+            // 1. 检查设备是否已注册(参考Python版本的设备注册检查)
+            Optional<Device> deviceOpt = deviceManagerService.getDeviceFromCache(deviceId);
+            
+            if (deviceOpt.isPresent()) {
+                // 设备已注册,更新设备信息
+                Device device = deviceOpt.get();
+                boolean deviceWasOffline = !Integer.valueOf(1).equals(device.getOnline());
+                
+                // 2. 如果设备离线,使其重新上线(参考Python版本的重新上线逻辑)
+                if (deviceWasOffline) {
+                    log.info("设备重新上线: deviceId={}", deviceId);
+                    device.updateOnlineStatus(1);
+                    device.updateKeepAliveTime(System.currentTimeMillis());
+                    
+                    // 发送登录响应(参考Python版本的mqtt_send.resp_dev_login())
+                    mqttGateway.sendDeviceLoginResponse(deviceId, 0); // 0表示成功
+                    
+                    // 发送设备状态通知(参考Python版本的mqtt_send.dev_status_msg())
+                    mqttGateway.sendDeviceStatusMessage(device);
+                    
+                    // 异步更新数据库在线状态
+                    deviceGateway.updateDeviceOnlineStatus(deviceId, 1);
+                }
+                
+                // 3. 更新设备信息(参考Python版本的设备信息更新)
+                boolean infoChanged = false;
+                
+                if (!deviceType.equals(device.getDevType())) {
+                    device.setDevType(deviceType);
+                    infoChanged = true;
+                }
+                
+                if (!firmware.equals(device.getSoftware())) {
+                    device.setSoftware(firmware);
+                    infoChanged = true;
+                }
+                
+                // 更新网络信息
+                if (device.getNetwork() == null) {
+                    device.setNetwork(new Device.NetworkInfo());
+                    infoChanged = true;
+                }
+                if (!deviceIp.equals(device.getNetwork().getIp())) {
+                    device.getNetwork().setIp(deviceIp);
+                    infoChanged = true;
+                }
+                
+                // 处理可选字段(暂时跳过MAC地址和序列号,等Device类支持后再添加)
+                // TODO: 当Device类支持mac_address和serial_number字段时,添加这些字段的处理
+                
+                // 4. 如果信息发生变化,更新缓存和发送通知
+                if (infoChanged) {
+                    // 更新设备缓存
+                    deviceManagerService.updateDeviceInCache(device);
+                    
+                    // 异步更新数据库
+                    deviceGateway.updateDevice(device);
+                    
+                    // 发送设备信息更新通知(参考Python版本的mqtt_send.update_dev_info_msg())
+                    mqttGateway.sendDeviceInfoUpdateNotification(device);
+                    
+                    log.info("设备信息已更新: deviceId={}", deviceId);
+                } else {
+                    log.debug("设备信息无变化: deviceId={}", deviceId);
+                }
+                
+            } else {
+                // 设备未注册,创建新设备(参考Python版本的新设备处理)
+                log.info("创建新设备: deviceId={}", deviceId);
+                
+                // 5. 构造设备实例(参考Python版本的设备构造)
+                Device.NetworkInfo network = new Device.NetworkInfo();
+                network.setIp(deviceIp);
+                
+                Device device = new Device();
+                device.setDevId(deviceId);
+                device.updateOnlineStatus(1);
+                device.setDevType(deviceType);
+                device.setSoftware(firmware);
+                device.setHardware(messageData.containsKey("hardware") ? 
+                                 (String) messageData.get("hardware") : "");
+                device.setNetwork(network);
+                device.updateKeepAliveTime(System.currentTimeMillis());
+                
+                // 6. 保存设备到数据库
+                Device savedDevice = deviceGateway.saveDevice(device);
+                if (savedDevice != null) {
+                    // 7. 添加到设备缓存(参考Python版本的g_dev_map[dev_id] = device)
+                    deviceManagerService.updateDeviceInCache(savedDevice);
+                    
+                    // 8. 发送登录响应(参考Python版本的mqtt_send.resp_dev_login())
+                    mqttGateway.sendDeviceLoginResponse(deviceId, 0); // 0表示成功
+                    
+                    // 9. 发送设备状态通知(参考Python版本的mqtt_send.dev_status_msg())
+                    mqttGateway.sendDeviceStatusMessage(savedDevice);
+                    
+                    log.info("新设备创建成功: deviceId={}", deviceId);
+                } else {
+                    log.error("新设备创建失败: deviceId={}", deviceId);
+                }
+            }
+            
+            log.info("设备信息上报处理完成: deviceId={}", deviceId);
+            
+        } catch (Exception e) {
+            log.error("处理设备信息上报异常: deviceId={}, error={}", deviceId, e.getMessage(), e);
+        }
+    }
 } 

+ 380 - 2
device-service-domain/src/main/java/com/hfln/device/domain/entity/Device.java

@@ -14,7 +14,10 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.Queue;
+import java.util.LinkedList;
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * 设备实体类 - 聚合根(Aggregate Root)
@@ -63,6 +66,9 @@ public class Device {
     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分钟
@@ -92,12 +98,22 @@ public class Device {
     // 设备最近的活动记录
     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();
     
     /**
@@ -133,6 +149,9 @@ public class Device {
         this.retentionTime = 60000L;     // 默认60秒
         this.retentionKeepTime = 30000L; // 默认30秒
         this.retentionAlarmTime = 180000L; // 默认180秒(3分钟)
+        
+        // 初始化跌倒状态 (对应Python版本)
+        this.falling_ = 0; // 默认无跌倒状态
     }
     
     /**
@@ -338,8 +357,8 @@ public class Device {
     }
     
     /**
-     * 设置最后一次上报跌倒时间
-     * @param timestamp 上报时间
+     * 设置最后上报跌倒时间 (对应Python版本的set_last_report_fall_time方法)
+     * @param timestamp 时间
      */
     public void setLastReportFallTime(Long timestamp) {
         try {
@@ -351,6 +370,19 @@ public class Device {
     }
     
     /**
+     * 获取最后上报跌倒时间 (对应Python版本的last_report_fall_time方法)
+     * @return 最后上报跌倒时间
+     */
+    public Long getLastReportFallTime() {
+        try {
+            lock.lock();
+            return lastReportFallTime != null ? lastReportFallTime : 0L;
+        } finally {
+            lock.unlock();
+        }
+    }
+    
+    /**
      * 添加告警记录
      * @param alarm 告警对象
      */
@@ -903,6 +935,34 @@ public class Device {
     }
     
     /**
+     * 设置设备参数信息
+     * 对应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 参数值
@@ -1017,6 +1077,226 @@ public class Device {
     }
     
     /**
+     * 更新设备目标位置 (对应Python版本的update_targets方法)
+     * @param newTargets 新的目标位置列表
+     * @return 稳定的目标位置列表
+     */
+    public List<List<Float>> updateTargets(List<List<Float>> newTargets) {
+        try {
+            lock.lock();
+            if (newTargets != null && !newTargets.isEmpty()) {
+                // 简单实现:直接更新targets字段
+                // 在实际应用中,这里可能需要更复杂的目标稳定算法
+                this.targets = newTargets.get(0); // 取第一个目标
+                return newTargets; // 返回稳定的目标
+            }
+            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 姿态
@@ -1063,6 +1343,104 @@ public class Device {
     }
     
     /**
+     * 放入点云数据到队列 (对应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

+ 61 - 2
device-service-domain/src/main/java/com/hfln/device/domain/gateway/MqttGateway.java

@@ -115,6 +115,35 @@ public interface MqttGateway {
     void sendDeviceStatusMessage(Device device);
 
     /**
+     * 发送设备信息更新通知
+     * 对应Python版本的mqtt_send.update_dev_info_msg(device)
+     * 
+     * 用于通知系统设备的基本信息发生了变化,包括:
+     * - 设备类型、固件版本、硬件版本
+     * - 网络信息(IP地址、SSID等)
+     * - 安装参数(高度、跟踪区域等)
+     * 
+     * @param device 设备信息
+     */
+    void sendDeviceInfoUpdateNotification(Device device);
+
+    /**
+     * 发送实时位置姿态消息
+     * 对应Python版本的mqtt_send.realtime_pos_msg(dev_id, raw_points, pose, targets)
+     * 
+     * 用于发送设备检测到的实时位置和姿态信息,包括:
+     * - 点云数据(raw_points)
+     * - 姿态信息(pose)
+     * - 目标位置(targets)
+     * 
+     * @param deviceId 设备ID
+     * @param rawPoints 原始点云数据
+     * @param pose 姿态信息
+     * @param targets 目标位置列表
+     */
+    void sendRealtimePositionMessage(String deviceId, List<List<Float>> rawPoints, List<Integer> pose, List<List<Float>> targets);
+
+    /**
      * 发送实时姿态消息
      * @param deviceId 设备ID
      * @param pose 姿态
@@ -139,12 +168,15 @@ public interface MqttGateway {
 
     /**
      * 发送事件消息(跌倒等)
+     * 对应Python版本的mqtt_send.event_msg(dev_id=dev_id, RawPoints=[], pose=pose, targets=targets, event=event)
+     * 
      * @param deviceId 设备ID
+     * @param rawPoints 原始点云数据(跌倒事件通常为空列表)
      * @param pose 姿态
-     * @param targetPoint 目标点
+     * @param targets 目标位置列表
      * @param event 事件类型
      */
-    void sendEventMessage(String deviceId, int pose, Object targetPoint, String event);
+    void sendEventMessage(String deviceId, List<List<Float>> rawPoints, int pose, List<List<Float>> targets, String event);
 
     /**
      * 发送告警事件消息
@@ -353,4 +385,31 @@ public interface MqttGateway {
      * @param messageData 消息数据
      */
     void sendGenericMessage(String topic, String messageType, Map<String, Object> messageData);
+
+    /**
+     * 发送存在事件消息
+     * 对应Python版本的mqtt_send.exist_event_msg(dev_id, event)
+     * 
+     * @param deviceId 设备ID
+     * @param event 存在事件类型
+     */
+    void sendExistEventMessage(String deviceId, String event);
+    
+    /**
+     * 发送调试参数响应
+     * 对应Python版本的发送调试参数功能
+     * 
+     * @param deviceId 设备ID
+     * @param debugParams 调试参数
+     */
+    void sendDebugParamResponse(String deviceId, Map<String, Object> debugParams);
+    
+    /**
+     * 发送告警参数报告
+     * 对应Python版本的mqtt_send.report_alarm_param(code, format_json)
+     * 
+     * @param code 响应码
+     * @param alarmConfig 告警配置
+     */
+    void reportAlarmParam(int code, Map<String, Object> alarmConfig);
 }

+ 28 - 3
device-service-domain/src/main/java/com/hfln/device/domain/port/DeviceEventPort.java

@@ -31,6 +31,31 @@ public interface DeviceEventPort {
     void handleDeviceKeepAlive(String deviceId);
     
     /**
+     * 处理设备信息上报
+     * 对应Python版本的deal_report_device_info方法
+     * 
+     * 业务流程:
+     * 1. 验证设备信息字段的完整性
+     * 2. 检查设备是否已注册到系统中
+     * 3. 如果设备已注册:
+     *    - 检查设备在线状态,离线则重新上线
+     *    - 更新设备类型、固件版本、IP地址等信息
+     *    - 发送设备信息更新通知
+     * 4. 如果设备未注册:
+     *    - 创建新设备并设置为在线状态
+     *    - 添加到设备缓存
+     *    - 发送登录响应和状态通知
+     * 
+     * @param deviceId 设备ID
+     * @param deviceType 设备类型
+     * @param firmware 固件版本
+     * @param deviceIp 设备IP地址
+     * @param messageData 完整的消息数据(包含可选字段如MAC地址、序列号等)
+     */
+    void handleDeviceInfoReport(String deviceId, String deviceType, String firmware, 
+                               String deviceIp, Map<String, Object> messageData);
+    
+    /**
      * 处理设备参数上报
      * 对应Python版本的deal_report_device_param方法
      * 
@@ -268,6 +293,6 @@ public interface DeviceEventPort {
      * 
      * @param code 响应码 (0:成功, -1:失败)
      * @param response 响应数据JSON字符串
-     */
-    void sendSetAlarmParamAck(int code, String response);
-} 
+           */
+     void sendSetAlarmParamAck(int code, String response);
+ } 

+ 84 - 0
device-service-domain/src/main/java/com/hfln/device/domain/service/PointCloudProcessService.java

@@ -189,4 +189,88 @@ public class PointCloudProcessService {
             return Collections.emptyList();
         }
     }
+    
+    /**
+     * 从点云数据计算跟踪目标 (对应Python版本的get_tracker_targets方法)
+     * 
+     * Python版本功能:
+     * 1. 对点云数据进行聚类分析
+     * 2. 识别人员目标
+     * 3. 计算目标的边界框和中心位置
+     * 4. 返回跟踪目标列表,格式:[[x, y, z, id], ...]
+     * 
+     * @param cloudPoints 点云数据,格式:List<List<Float>>,每个点包含[x, y, z]坐标
+     * @return 跟踪目标列表,格式:List<List<Float>>,每个目标包含[x, y, z, id]
+     */
+    public List<List<Float>> getTrackerTargets(List<List<Float>> cloudPoints) {
+        if (cloudPoints == null || cloudPoints.isEmpty()) {
+            log.debug("Point cloud is empty, returning empty targets");
+            return new ArrayList<>();
+        }
+        
+        try {
+            log.trace("Processing {} cloud points for target tracking", cloudPoints.size());
+            
+            // 简化实现:使用聚类算法识别目标
+            // 实际应用中应使用更复杂的3D目标检测算法
+            List<List<Float>> targets = new ArrayList<>();
+            
+            // 基本的聚类方法:计算点云的质心作为主要目标
+            List<Float> centroid = calculateCentroidFromFloat(cloudPoints);
+            if (!centroid.isEmpty()) {
+                // 添加目标ID (第4个元素)
+                List<Float> target = new ArrayList<>(centroid);
+                target.add(1.0f); // 目标ID = 1
+                targets.add(target);
+                
+                log.trace("Detected target at position: [{}, {}, {}]", 
+                         centroid.get(0), centroid.get(1), centroid.get(2));
+            }
+            
+            // TODO: 实现更复杂的目标检测算法
+            // 1. DBSCAN聚类算法识别多个目标
+            // 2. 卡尔曼滤波跟踪目标轨迹
+            // 3. 目标关联和ID管理
+            // 4. 噪声过滤和异常点检测
+            
+            log.debug("Extracted {} targets from {} cloud points", targets.size(), cloudPoints.size());
+            return targets;
+            
+        } catch (Exception e) {
+            log.error("Error extracting tracker targets from cloud points: {}", e.getMessage(), e);
+            return new ArrayList<>();
+        }
+    }
+    
+    /**
+     * 计算Float类型点云的中心点
+     * 
+     * @param pointCloud Float类型点云数据
+     * @return 中心点坐标 [x, y, z]
+     */
+    private List<Float> calculateCentroidFromFloat(List<List<Float>> pointCloud) {
+        int numPoints = pointCloud.size();
+        if (numPoints == 0) {
+            return new ArrayList<>();
+        }
+
+        float sumX = 0.0f;
+        float sumY = 0.0f;
+        float sumZ = 0.0f;
+
+        for (List<Float> point : pointCloud) {
+            if (point.size() >= 3) {
+                sumX += point.get(0);
+                sumY += point.get(1);
+                sumZ += point.get(2);
+            }
+        }
+
+        List<Float> centroid = new ArrayList<>();
+        centroid.add(sumX / numPoints);
+        centroid.add(sumY / numPoints);
+        centroid.add(sumZ / numPoints);
+
+        return centroid;
+    }
 }

+ 2 - 1
device-service-domain/src/main/java/com/hfln/device/domain/service/impl/AlarmServiceImpl.java

@@ -65,7 +65,8 @@ public class AlarmServiceImpl implements AlarmService {
             
             // 如果有位置信息,发送事件消息
             if (targetPoint != null) {
-                mqttGateway.sendEventMessage(deviceId, pose, targetPoint, EventConstants.EventType.FALL_EVENT);
+                List<List<Float>> targets = Collections.singletonList(targetPoint);
+                mqttGateway.sendEventMessage(deviceId, Collections.emptyList(), pose, targets, EventConstants.EventType.FALL_EVENT);
             }
             
             // 记录告警事件

+ 185 - 31
device-service-infrastructure/src/main/java/com/hfln/device/infrastructure/gateway/MqttGatewayImpl.java

@@ -16,6 +16,7 @@ import org.springframework.messaging.Message;
 import org.springframework.messaging.support.MessageBuilder;
 import org.springframework.stereotype.Component;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -109,55 +110,100 @@ public class MqttGatewayImpl implements MqttGateway {
     @Override
     public void sendDeviceStatusMessage(Device device) {
         try {
-            Map<String, Object> payload = new HashMap<>();
-            payload.put("message", "notify");
-            payload.put("timestamp", System.currentTimeMillis());
-            payload.put("dev_id", device.getDevId());
-            payload.put("online", device.getOnline());
-            payload.put("dev_type", device.getDevType());
-            payload.put("software", device.getSoftware());
-            payload.put("hardware", device.getHardware());
+            Map<String, Object> message = new HashMap<>();
+            message.put("message", "notify");
+            message.put("timestamp", System.currentTimeMillis());
+            message.put("dev_id", device.getDevId());
+            message.put("online", device.getOnline());
+            message.put("dev_type", device.getDevType());
+            message.put("software", device.getSoftware());
+            message.put("hardware", device.getHardware());
             
             // 网络信息
-            Map<String, Object> network = new HashMap<>();
             if (device.getNetwork() != null) {
+                Map<String, Object> network = new HashMap<>();
                 network.put("ssid", device.getNetwork().getSsid());
                 network.put("password", device.getNetwork().getPassword());
                 network.put("ip", device.getNetwork().getIp());
+                message.put("network", network);
             }
-            payload.put("network", network);
             
             // 雷达参数
-            Map<String, Object> radarParam = new HashMap<>();
             if (device.getInstallParam() != null) {
+                Map<String, Object> radarParam = new HashMap<>();
                 radarParam.put("mount_plain", device.getInstallParam().getMountPlain());
                 radarParam.put("height", device.getInstallParam().getHeight());
                 
-                // 跟踪区域
-                Map<String, Object> trackingRegion = getStringObjectMap(device.getInstallParam().getTrackingRegion());
-                radarParam.put("tracking_region", trackingRegion);
+                if (device.getInstallParam().getTrackingRegion() != null) {
+                    Map<String, Object> trackingRegion = new HashMap<>();
+                    trackingRegion.put("start_x", device.getInstallParam().getTrackingRegion().getStartX());
+                    trackingRegion.put("start_y", device.getInstallParam().getTrackingRegion().getStartY());
+                    trackingRegion.put("start_z", device.getInstallParam().getTrackingRegion().getStartZ());
+                    trackingRegion.put("stop_x", device.getInstallParam().getTrackingRegion().getStopX());
+                    trackingRegion.put("stop_y", device.getInstallParam().getTrackingRegion().getStopY());
+                    trackingRegion.put("stop_z", device.getInstallParam().getTrackingRegion().getStopZ());
+                    radarParam.put("tracking_region", trackingRegion);
+                }
+                message.put("radar_param", radarParam);
             }
-            payload.put("radar_param", radarParam);
             
-            sendMessage(MqttTopics.DAS_STATUS, payload);
-            log.debug("Device status message sent: {}", device.getDevId());
+            String topic = "/das/status";
+            publishJson(topic, message, 1, false);
+            log.debug("发送设备状态消息: deviceId={}, topic={}", device.getDevId(), topic);
         } catch (Exception e) {
-            log.error("Error sending device status message: {}", device.getDevId(), e);
+            log.error("发送设备状态消息失败: deviceId={}, error={}", device.getDevId(), e.getMessage(), e);
         }
     }
     
-    @NotNull
-    private static Map<String, Object> getStringObjectMap(Device.TrackingRegion trackingRegion) {
-        Map<String, Object> trackingRegionMap = new HashMap<>();
-        if (trackingRegion != null) {
-            trackingRegionMap.put("start_x", trackingRegion.getStartX());
-            trackingRegionMap.put("start_y", trackingRegion.getStartY());
-            trackingRegionMap.put("start_z", trackingRegion.getStartZ());
-            trackingRegionMap.put("stop_x", trackingRegion.getStopX());
-            trackingRegionMap.put("stop_y", trackingRegion.getStopY());
-            trackingRegionMap.put("stop_z", trackingRegion.getStopZ());
+    /**
+     * 发送设备信息更新通知
+     * 对应Python版本的mqtt_send.update_dev_info_msg(device)
+     */
+    @Override
+    public void sendDeviceInfoUpdateNotification(Device device) {
+        try {
+            Map<String, Object> message = new HashMap<>();
+            message.put("dev_id", device.getDevId());
+            message.put("dev_type", device.getDevType());
+            message.put("software", device.getSoftware());
+            message.put("hardware", device.getHardware());
+            message.put("online", device.getOnline());
+            
+            if (device.getNetwork() != null) {
+                Map<String, Object> network = new HashMap<>();
+                network.put("ssid", device.getNetwork().getSsid());
+                network.put("ip", device.getNetwork().getIp());
+                message.put("network", network);
+            }
+            
+            if (device.getInstallParam() != null) {
+                Map<String, Object> installParam = new HashMap<>();
+                installParam.put("mount_plain", device.getInstallParam().getMountPlain());
+                installParam.put("height", device.getInstallParam().getHeight());
+                installParam.put("is_ceiling", device.getInstallParam().getIsCeiling());
+                
+                if (device.getInstallParam().getTrackingRegion() != null) {
+                    Map<String, Object> trackingRegion = new HashMap<>();
+                    trackingRegion.put("start_x", device.getInstallParam().getTrackingRegion().getStartX());
+                    trackingRegion.put("start_y", device.getInstallParam().getTrackingRegion().getStartY());
+                    trackingRegion.put("start_z", device.getInstallParam().getTrackingRegion().getStartZ());
+                    trackingRegion.put("stop_x", device.getInstallParam().getTrackingRegion().getStopX());
+                    trackingRegion.put("stop_y", device.getInstallParam().getTrackingRegion().getStopY());
+                    trackingRegion.put("stop_z", device.getInstallParam().getTrackingRegion().getStopZ());
+                    installParam.put("tracking_region", trackingRegion);
+                }
+                
+                message.put("install_param", installParam);
+            }
+            
+            String topic = "/mps/update_dev_info";
+            publishJson(topic, message);
+            
+            log.info("Device info update notification sent: deviceId={}", device.getDevId());
+        } catch (Exception e) {
+            log.error("Failed to send device info update notification: deviceId={}, error={}", 
+                      device.getDevId(), e.getMessage(), e);
         }
-        return trackingRegionMap;
     }
     
     @Override
@@ -386,7 +432,7 @@ public class MqttGatewayImpl implements MqttGateway {
     }
     
     @Override
-    public void sendEventMessage(String deviceId, int pose, Object targetPoint, String event) {
+    public void sendEventMessage(String deviceId, List<List<Float>> rawPoints, int pose, List<List<Float>> targets, String event) {
         try {
             Map<String, Object> payload = new HashMap<>();
             payload.put("message", "notify");
@@ -395,11 +441,14 @@ public class MqttGatewayImpl implements MqttGateway {
             payload.put("event", event);
             payload.put("timestamp", System.currentTimeMillis());
             payload.put("pose", pose);
-            payload.put("target_point", targetPoint);
+            payload.put("RawPoints", rawPoints != null ? rawPoints : new ArrayList<>());  // 对应Python版本的RawPoints参数
+            payload.put("targets", targets != null ? targets : new ArrayList<>());        // 对应Python版本的targets参数
             
             // 对于确认的跌倒事件,使用QoS 2
             int qos = "fall_confirmed".equals(event) ? 2 : 0;
             sendMessage(MqttTopics.DAS_EVENT, payload, qos);
+            log.debug("Event message sent: deviceId={}, event={}, pose={}, targetsCount={}", 
+                     deviceId, event, pose, targets != null ? targets.size() : 0);
         } catch (Exception e) {
             log.error("Error sending event message: {}, event: {}", deviceId, event, e);
         }
@@ -686,4 +735,109 @@ public class MqttGatewayImpl implements MqttGateway {
             log.error("Error sending MQTT message to topic: {}", topic, e);
         }
     }
+    
+    @NotNull
+    private static Map<String, Object> getStringObjectMap(Device.TrackingRegion trackingRegion) {
+        Map<String, Object> trackingRegionMap = new HashMap<>();
+        if (trackingRegion != null) {
+            trackingRegionMap.put("start_x", trackingRegion.getStartX());
+            trackingRegionMap.put("start_y", trackingRegion.getStartY());
+            trackingRegionMap.put("start_z", trackingRegion.getStartZ());
+            trackingRegionMap.put("stop_x", trackingRegion.getStopX());
+            trackingRegionMap.put("stop_y", trackingRegion.getStopY());
+            trackingRegionMap.put("stop_z", trackingRegion.getStopZ());
+        }
+        return trackingRegionMap;
+    }
+
+    @Override
+    public void sendRealtimePositionMessage(String deviceId, List<List<Float>> rawPoints, List<Integer> pose, List<List<Float>> targets) {
+        try {
+            Map<String, Object> message = new HashMap<>();
+            message.put("dev_id", deviceId);
+            message.put("timestamp", System.currentTimeMillis());
+            
+            // 原始点云数据 (对应Python版本的raw_points)
+            if (rawPoints != null) {
+                message.put("raw_points", rawPoints);
+            } else {
+                message.put("raw_points", new ArrayList<>());
+            }
+            
+            // 姿态信息 (对应Python版本的pose)
+            if (pose != null && !pose.isEmpty()) {
+                message.put("pose", pose.get(0)); // 取第一个姿态值
+            } else {
+                message.put("pose", 0); // 默认姿态
+            }
+            
+            // 目标位置 (对应Python版本的targets)
+            if (targets != null) {
+                message.put("targets", targets);
+            } else {
+                message.put("targets", new ArrayList<>());
+            }
+            
+            // 发送到实时位置主题 (对应Python版本的MQTT主题)
+            String topic = "/mps/realtime_pos";
+            publishJson(topic, message);
+            
+            log.trace("Realtime position message sent: deviceId={}, targetCount={}", 
+                     deviceId, targets != null ? targets.size() : 0);
+        } catch (Exception e) {
+            log.error("Failed to send realtime position message: deviceId={}, error={}", 
+                      deviceId, e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public void sendExistEventMessage(String deviceId, String event) {
+        try {
+            Map<String, Object> payload = new HashMap<>();
+            payload.put("message", "notify");
+            payload.put("message_type", DeviceConstants.MessageType.MSG_EVENT_EXIST.getCode());
+            payload.put("dev_id", deviceId);
+            payload.put("event", event);
+            payload.put("timestamp", System.currentTimeMillis());
+            
+            sendMessage(MqttTopics.DAS_EXIST_EVENT, payload);
+            log.debug("Exist event message sent: deviceId={}, event={}", deviceId, event);
+        } catch (Exception e) {
+            log.error("Error sending exist event message: {}, event: {}", deviceId, event, e);
+        }
+    }
+    
+    @Override
+    public void sendDebugParamResponse(String deviceId, Map<String, Object> debugParams) {
+        try {
+            Map<String, Object> payload = new HashMap<>();
+            payload.put("message", "response");
+            payload.put("dev_id", deviceId);
+            payload.put("debug_params", debugParams != null ? debugParams : new HashMap<>());
+            payload.put("timestamp", System.currentTimeMillis());
+            
+            String topic = DeviceConstants.MqttConstant.TOPIC_DEVICE_PREFIX + deviceId + "/debug_params";
+            sendMessage(topic, payload);
+            log.debug("Debug param response sent: deviceId={}, paramsCount={}", 
+                     deviceId, debugParams != null ? debugParams.size() : 0);
+        } catch (Exception e) {
+            log.error("Error sending debug param response: {}", deviceId, e);
+        }
+    }
+    
+    @Override
+    public void reportAlarmParam(int code, Map<String, Object> alarmConfig) {
+        try {
+            Map<String, Object> payload = new HashMap<>();
+            payload.put("code", code);
+            payload.put("global", alarmConfig != null ? alarmConfig : new HashMap<>());
+            payload.put("timestamp", System.currentTimeMillis());
+            
+            sendMessage(MqttTopics.DAS_REPORT_ALARM_PARAM, payload);
+            log.debug("Alarm param report sent: code={}, configSize={}", 
+                     code, alarmConfig != null ? alarmConfig.size() : 0);
+        } catch (Exception e) {
+            log.error("Error sending alarm param report: code={}", code, e);
+        }
+    }
 } 

+ 91 - 61
device-service-infrastructure/src/main/java/com/hfln/device/infrastructure/mqtt/handler/DeviceMessageHandler.java

@@ -1,6 +1,7 @@
 package com.hfln.device.infrastructure.mqtt.handler;
 
 import com.hfln.device.domain.port.DeviceEventPort;
+import com.hfln.device.domain.service.DeviceManagerService;
 import com.hfln.device.common.util.JsonUtil;
 import com.hfln.device.common.constant.mqtt.topic.MqttTopics;
 import lombok.extern.slf4j.Slf4j;
@@ -10,6 +11,7 @@ import org.springframework.messaging.Message;
 import org.springframework.stereotype.Component;
 
 import java.util.List;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -48,6 +50,9 @@ public class DeviceMessageHandler {
     @Autowired
     @Qualifier("deviceEventServiceImpl")
     private DeviceEventPort deviceEventPort;
+    
+    @Autowired
+    private DeviceManagerService deviceManagerService;
 
     /**
      * MQTT消息统一入口处理方法
@@ -264,9 +269,9 @@ public class DeviceMessageHandler {
                 log.info("Device {} info: type={}, firmware={}, ip={}", 
                         deviceId, deviceType, firmware, deviceIp);
                 
-                // 委托给应用层服务处理
-                // 应用层将处理:设备信息验证、数据库更新、缓存刷新、版本检查
-                deviceEventPort.handleDeviceLogin(deviceId, messageData, messageData);
+                // 委托给应用层专门的设备信息上报处理方法
+                // 区别于登录流程,这里只处理设备基本信息的更新
+                deviceEventPort.handleDeviceInfoReport(deviceId, deviceType, firmware, deviceIp, messageData);
             }
         } catch (Exception e) {
             log.error("Error handling device info report: {}", e.getMessage(), e);
@@ -547,51 +552,70 @@ public class DeviceMessageHandler {
     private void handleDeviceReportPresenceEvent(String topic, String payload) {
         try {
             String deviceId = extractDeviceIdFromTopic(topic);
-            if (deviceId != null) {
-                Map<String, Object> messageData = JsonUtil.parseMap(payload);
-                
-                log.info("Processing device presence event: {}, payload: {}", deviceId, payload);
-                
-                // 验证必要字段
-                if (!messageData.containsKey("timestamp") || !messageData.containsKey("type") ||
-                    !messageData.containsKey("event")) {
-                    log.warn("Invalid presence event message, missing required fields: {}", payload);
-                    return;
-                }
-                
-                Long timestamp = ((Number) messageData.get("timestamp")).longValue();
-                String type = (String) messageData.get("type");
-                String event = (String) messageData.get("event");
-                
-                // 记录存在事件的详细信息
-                log.info("Device {} presence event: type={}, event={}, time={}", 
-                        deviceId, type, event, timestamp);
-                
-                // 根据事件类型进行不同的处理
-                switch (event) {
-                    case "presence_detected":
-                        log.info("Person entered monitoring area of device {}", deviceId);
-                        break;
-                    case "presence_lost":
-                        log.info("Person left monitoring area of device {}", deviceId);
-                        break;
-                    case "motion_detected":
-                        log.debug("Motion detected by device {}", deviceId);
-                        break;
-                    case "motion_stopped":
-                        log.debug("Motion stopped at device {}", deviceId);
-                        break;
-                    default:
-                        log.debug("Unknown presence event: {} from device {}", event, deviceId);
-                        break;
-                }
-                
-                // 委托给应用层服务处理
-                // 应用层将处理:状态更新、活动统计、模式分析、异常检测
-                deviceEventPort.handleExistEvent(deviceId, timestamp, type, event);
+            if (deviceId == null) {
+                log.warn("Could not extract device ID from topic: {}", topic);
+                return;
+            }
+            
+            // === 设备验证 (对应Python: with g_dev_map_lock: if dev_id not in g_dev_map) ===
+            // 未注册的设备,不处理
+            if (!deviceManagerService.getDeviceFromCache(deviceId).isPresent()) {
+                log.debug("error, device not registed: {}", deviceId); // 对应Python: LOGDBG(f"error, device not registed: {dev_id}")
+                return;
+            }
+            
+            Map<String, Object> messageData = JsonUtil.parseMap(payload);
+            
+            log.info("Processing device presence event: {}, payload: {}", deviceId, payload);
+            
+            // === 参数验证 (对应Python的payload验证) ===
+            if (!messageData.containsKey("timestamp") || !messageData.containsKey("type") ||
+                !messageData.containsKey("event")) {
+                log.debug("error, invalid device_param, {}", deviceId); // 对应Python: LOGDBG(f"error, invalid device_param, {dev_id}")
+                return;
+            }
+            
+            Long timestamp = ((Number) messageData.get("timestamp")).longValue();
+            String type = (String) messageData.get("type");
+            String event = (String) messageData.get("event");
+            
+            // 记录存在事件的详细信息
+            log.info("Device {} presence event: type={}, event={}, time={}", 
+                    deviceId, type, event, timestamp);
+            
+            // 根据事件类型进行不同的处理
+            switch (event) {
+                case "presence_detected":
+                    log.info("Person entered monitoring area of device {}", deviceId);
+                    break;
+                case "presence_lost":
+                    log.info("Person left monitoring area of device {}", deviceId);
+                    break;
+                case "motion_detected":
+                    log.debug("Motion detected by device {}", deviceId);
+                    break;
+                case "motion_stopped":
+                    log.debug("Motion stopped at device {}", deviceId);
+                    break;
+                default:
+                    log.debug("Unknown presence event: {} from device {}", event, deviceId);
+                    break;
+            }
+            
+            // === 委托给应用层服务处理 (对应Python: mqtt_send.exist_msg(dev_id=dev_id, event=event)) ===
+            // 应用层将进行设备验证,并处理:状态更新、活动统计、模式分析、异常检测,发送存在事件消息
+            deviceEventPort.handleExistEvent(deviceId, timestamp, type, event);
+            
+        } catch (RuntimeException e) {
+            // 对应Python: except json.JSONDecodeError: LOGERR(f"parse payload failed, {msg.topic}, {msg.payload}")
+            if (e.getCause() instanceof com.fasterxml.jackson.core.JsonProcessingException) {
+                log.error("parse payload failed, topic: {}, payload: {}", topic, payload, e);
+            } else {
+                throw e; // 重新抛出非JSON异常
             }
         } catch (Exception e) {
-            log.error("Error handling device presence event: {}", e.getMessage(), e);
+            // 对应Python: except Exception as e: LOGERR(f"deal_report_presence_event error: {e}")
+            log.error("deal_report_presence_event error: {}, topic: {}", e.getMessage(), topic, e);
         }
     }
 
@@ -654,8 +678,16 @@ public class DeviceMessageHandler {
                 // 应用层将处理:参数验证、权限检查、设备下发、状态跟踪
                 deviceEventPort.handleSetDebugParam(deviceId, messageData);
             }
+        } catch (RuntimeException e) {
+            // 对应Python: except json.JSONDecodeError: LOGERR(f"parse payload failed, {msg.topic}, {msg.payload}")
+            if (e.getCause() instanceof com.fasterxml.jackson.core.JsonProcessingException) {
+                log.error("parse payload failed, topic: {}, payload: {}", topic, payload, e);
+            } else {
+                throw e; // 重新抛出非JSON异常
+            }
         } catch (Exception e) {
-            log.error("Error handling set debug param: {}", e.getMessage(), e);
+            // 对应Python: except Exception as e: LOGERR(f"deal_set_debug_param error: {e}")
+            log.error("deal_set_debug_param error: {}, topic: {}", e.getMessage(), topic, e);
         }
     }
 
@@ -690,25 +722,23 @@ public class DeviceMessageHandler {
         try {
             String deviceId = extractDeviceIdFromTopic(topic);
             if (deviceId != null) {
-                Map<String, Object> messageData = JsonUtil.parseMap(payload);
-                
-                log.info("Processing get debug param request: {}, payload: {}", deviceId, payload);
-                
-                // 检查查询的参数类型
-                if (messageData.containsKey("param_type")) {
-                    String paramType = (String) messageData.get("param_type");
-                    log.debug("Requested debug param type for device {}: {}", deviceId, paramType);
-                }
-                
-                // 记录调试参数查询请求
-                log.debug("Debug param query from device {} with request: {}", deviceId, messageData);
+                // 对应Python版本:直接处理,不需要解析payload(Python版本没有payload解析)
+                log.info("Processing get debug param request: {}", deviceId);
                 
                 // 委托给应用层服务处理
                 // 应用层将处理:权限验证、参数获取、响应构造、消息发送
-                deviceEventPort.handleGetDebugParam(deviceId, messageData);
+                deviceEventPort.handleGetDebugParam(deviceId, new HashMap<>());
+            }
+        } catch (RuntimeException e) {
+            // 对应Python: except json.JSONDecodeError: LOGERR(f"parse payload failed, {msg.topic}, {msg.payload}")
+            if (e.getCause() instanceof com.fasterxml.jackson.core.JsonProcessingException) {
+                log.error("parse payload failed, topic: {}, payload: {}", topic, payload, e);
+            } else {
+                throw e; // 重新抛出非JSON异常
             }
         } catch (Exception e) {
-            log.error("Error handling get debug param: {}", e.getMessage(), e);
+            // 对应Python: except Exception as e: LOGERR(f"deal_get_debug_param error: {e}")
+            log.error("deal_get_debug_param error: {}, topic: {}", e.getMessage(), topic, e);
         }
     }
 

+ 29 - 130
device-service-infrastructure/src/main/java/com/hfln/device/infrastructure/mqtt/handler/MpsMessageHandler.java

@@ -229,7 +229,7 @@ public class MpsMessageHandler {
             
             // 委托给应用层服务处理
             // 应用层将处理:设备状态检查、参数获取、格式化、响应发送
-            deviceCommandService.handleGetDeviceParam(devId);
+            deviceCommandService.handleGetDeviceParam(payload);
             
             log.debug("Device param request submitted for processing: {}", devId);
             
@@ -456,51 +456,20 @@ public class MpsMessageHandler {
      * - 自动分配设备ID和初始配置
      * - 批量权限设置和组织架构绑定
      * 
-     * @param topic MQTT主题:/mps/add_device
+     * 注意:为保持与Python版本一致性,实际处理逻辑已简化为:
+     * 1. 解析payload获取dev_id
+     * 2. 查询数据库获取设备信息
+     * 3. 通过回调更新设备缓存
+     * 
+     * @param topic MQTT主题:/mps/{dev_id}/add_device
      * @param payload JSON格式的添加设备请求
      */
     private void handleAddDevice(String topic, String payload) {
         try {
-            Map<String, Object> messageData = JsonUtil.parseMap(payload);
-            
-            String devId = (String) messageData.get("dev_id");
-            if (devId == null) {
-                log.warn("Invalid add device message, missing dev_id: {}", payload);
-                return;
-            }
-            
-            log.info("Processing add device request: {}", devId);
+            log.info("Processing add device request, topic: {}, payload: {}", topic, payload);
             
-            // 获取设备详细信息
-            String deviceType = (String) messageData.get("device_type");
-            String deviceModel = (String) messageData.get("device_model");
-            String serialNumber = (String) messageData.get("serial_number");
-            String location = (String) messageData.get("location");
-            String department = (String) messageData.get("department");
-            
-            // 获取操作者信息
-            String operatorId = (String) messageData.get("operator_id");
-            String operatorType = (String) messageData.get("operator_type");
-            
-            log.info("Adding device: {} (type={}, model={}, sn={}) by operator: {} ({})", 
-                    devId, deviceType, deviceModel, serialNumber, operatorId, operatorType);
-            
-            // 设备分组和权限信息
-            String deviceGroup = (String) messageData.get("device_group");
-            String assignedTo = (String) messageData.get("assigned_to");
-            
-            if (deviceGroup != null) {
-                log.info("Device {} will be assigned to group: {}", devId, deviceGroup);
-            }
-            if (assignedTo != null) {
-                log.info("Device {} will be assigned to user: {}", devId, assignedTo);
-            }
-            
-            // 委托给应用层服务处理
-            // 应用层将处理:重复性检查、数据库插入、配置初始化、权限设置
-            deviceCommandService.handleAddDevice(devId);
-            
-            log.info("Device addition request submitted for processing: {}", devId);
+            // 委托给应用层服务处理(对应Python版本逻辑)
+            deviceCommandService.handleAddDevice(payload);
             
         } catch (Exception e) {
             log.error("Error handling add device request: {}", e.getMessage(), e);
@@ -510,7 +479,7 @@ public class MpsMessageHandler {
     /**
      * 处理删除设备请求
      * 
-     * Python对应方法:deal_delete_device
+     * Python对应方法:deal_del_device
      * 业务流程:
      * 1. 解析删除设备请求
      * 2. 验证设备ID和删除权限
@@ -537,58 +506,20 @@ public class MpsMessageHandler {
      * - 重要设备删除需要多级审批
      * - 删除操作不可逆,需要谨慎确认
      * 
-     * @param topic MQTT主题:/mps/del_device
+     * 注意:为保持与Python版本一致性,实际处理逻辑已简化为:
+     * 1. 解析payload获取dev_id
+     * 2. 检查设备是否存在于缓存
+     * 3. 从缓存中删除设备
+     * 
+     * @param topic MQTT主题:/mps/{dev_id}/del_device
      * @param payload JSON格式的删除设备请求
      */
     private void handleDeleteDevice(String topic, String payload) {
         try {
-            Map<String, Object> messageData = JsonUtil.parseMap(payload);
+            log.info("Processing delete device request, topic: {}, payload: {}", topic, payload);
             
-            String devId = (String) messageData.get("dev_id");
-            if (devId == null) {
-                log.warn("Invalid delete device message, missing dev_id: {}", payload);
-                return;
-            }
-            
-            log.warn("Processing device deletion request: {}", devId);
-            
-            // 获取删除操作信息
-            String operatorId = (String) messageData.get("operator_id");
-            String operatorType = (String) messageData.get("operator_type");
-            String deleteReason = (String) messageData.get("reason");
-            String deleteType = (String) messageData.get("delete_type"); // soft/hard/archive
-            Boolean forceDelete = (Boolean) messageData.get("force_delete");
-            
-            // 记录重要的删除操作
-            log.warn("DEVICE DELETION INITIATED - Device: {}, Operator: {} ({}), Reason: {}, Type: {}, Force: {}", 
-                    devId, operatorId, operatorType, deleteReason, deleteType, forceDelete);
-            
-            // 验证删除权限(高风险操作)
-            if (!"admin".equals(operatorType) && !"manager".equals(operatorType)) {
-                log.error("UNAUTHORIZED DELETE ATTEMPT - Device: {}, Operator: {} ({})", 
-                         devId, operatorId, operatorType);
-                return;
-            }
-            
-            // 检查删除类型
-            if (deleteType == null) {
-                deleteType = "soft"; // 默认软删除
-                log.info("Using default soft delete for device: {}", devId);
-            }
-            
-            // 强制删除警告
-            if (Boolean.TRUE.equals(forceDelete)) {
-                log.error("FORCE DELETE REQUESTED for device: {} - This will bypass safety checks!", devId);
-            }
-            
-            // 记录删除前状态用于审计
-            log.info("Recording device state before deletion: {}", devId);
-            
-            // 委托给应用层服务处理
-            // 应用层将处理:依赖检查、数据归档、关系解除、最终删除
-            deviceCommandService.handleDeleteDevice(devId);
-            
-            log.warn("Device deletion request submitted for processing: {}", devId);
+            // 委托给应用层服务处理(对应Python版本逻辑)
+            deviceCommandService.handleDeleteDevice(payload);
             
         } catch (Exception e) {
             log.error("Error handling delete device request: {}", e.getMessage(), e);
@@ -625,53 +556,21 @@ public class MpsMessageHandler {
      * - 更新统计数据
      * - 触发后续关怀流程
      * 
+     * 注意:为保持与Python版本一致性,实际处理逻辑已简化为:
+     * 1. 解析payload获取dev_id
+     * 2. 检查设备是否存在于缓存
+     * 3. 检查设备告警确认状态
+     * 4. 设置告警确认并更新时间戳
+     * 
      * @param topic MQTT主题:/mps/fall_event/ack
      * @param payload JSON格式的确认消息
      */
     private void handleFallEventAck(String topic, String payload) {
         try {
-            Map<String, Object> messageData = JsonUtil.parseMap(payload);
-            
-            String devId = (String) messageData.get("dev_id");
-            if (devId == null) {
-                log.warn("Invalid fall event ack message, missing dev_id: {}", payload);
-                return;
-            }
-            
-            log.info("Processing MPS fall event acknowledgment: {}", devId);
-            
-            // 获取事件和确认信息
-            String eventId = (String) messageData.get("event_id");
-            String ackType = (String) messageData.get("ack_type"); // management/emergency/routine
-            String operatorId = (String) messageData.get("operator_id");
-            String operatorType = (String) messageData.get("operator_type");
-            String ackReason = (String) messageData.get("ack_reason");
-            String followUpAction = (String) messageData.get("follow_up_action");
-            
-            // 记录管理端确认操作
-            log.info("MANAGEMENT ACK - Device: {}, Event: {}, Operator: {} ({}), Type: {}, Reason: {}", 
-                    devId, eventId, operatorId, operatorType, ackType, ackReason);
-            
-            // 检查确认类型
-            if ("emergency".equals(ackType)) {
-                log.error("EMERGENCY ACK - Immediate response required for device: {}, event: {}", 
-                         devId, eventId);
-            }
-            
-            // 记录后续行动计划
-            if (followUpAction != null) {
-                log.info("Follow-up action planned for device {}: {}", devId, followUpAction);
-            }
-            
-            // 记录确认时间用于响应时间统计
-            long ackTime = System.currentTimeMillis();
-            log.info("Management acknowledgment received at: {} for device: {}", ackTime, devId);
-            
-            // 委托给应用层服务处理
-            // 应用层将处理:事件状态更新、通知停止、报告生成、统计更新
-            deviceCommandService.handleFallEventAck(devId);
+            log.info("Processing fall event ack request, topic: {}, payload: {}", topic, payload);
             
-            log.info("MPS fall event acknowledgment processed for device: {}", devId);
+            // 委托给应用层服务处理(对应Python版本逻辑)
+            deviceCommandService.handleFallEventAck(payload);
             
         } catch (Exception e) {
             log.error("Error handling fall event ack: {}", e.getMessage(), e);