package com.ruoyi.device.service.impl; import com.ruoyi.device.domain.api.*; import com.ruoyi.device.domain.model.*; import com.ruoyi.device.domain.model.thingsboard.AttributeMap; import com.ruoyi.device.domain.model.thingsboard.TelemetryMap; import com.ruoyi.device.domain.model.thingsboard.TelemetryValue; import com.ruoyi.device.domain.model.thingsboard.tuoheng.constants.TuohengDeviceAttributes; import com.ruoyi.device.domain.model.thingsboard.tuoheng.constants.TuohengDeviceTelemetry; import com.ruoyi.device.service.api.IBufferDeviceService; import com.ruoyi.device.service.dto.AircraftDetailDTO; import com.ruoyi.device.service.dto.DockDetailDTO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 拓恒设备缓冲服务实现 * 专门处理拓恒设备的数据整合 * * @author ruoyi * @date 2026-02-04Ï */ @Service("tuohengBufferDeviceService") @Slf4j public class TuohengBufferDeviceImpl implements IBufferDeviceService { @Autowired private IDockDomain dockDomain; @Autowired private IDeviceDomain deviceDomain; @Autowired private IAircraftDomain aircraftDomain; @Autowired private IDockAircraftDomain dockAircraftDomain; @Autowired private IThingsBoardDomain thingsBoardDomain; @Override public DockDetailDTO getDockDetailById(Long dockId) { log.info("获取拓恒机场详情: dockId={}", dockId); // 查询机场基础信息 Dock dock = dockDomain.selectDockByDockId(dockId); if (dock == null) { log.warn("机场不存在: dockId={}", dockId); return null; } // 查询设备信息 Device device = deviceDomain.selectDeviceByDeviceId(dock.getDeviceId()); if (device == null) { log.warn("机场对应的设备不存在: deviceId={}", dock.getDeviceId()); return null; } // 检查是否是拓恒设备 if (!"tuoheng".equals(device.getDeviceManufacturer())) { log.warn("设备不是拓恒厂商: deviceId={}, manufacturer={}", device.getDeviceId(), device.getDeviceManufacturer()); return null; } // 构建机场详情DTO DockDetailDTO dto = new DockDetailDTO(); dto.setDockId(dock.getDockId()); dto.setDockName(dock.getDockName()); dto.setDockLocation(dock.getDockLocation()); dto.setDockIotId(device.getIotDeviceId()); dto.setSnNumber(device.getDeviceSn()); dto.setBindTime(device.getCreateTime().getTime()); // 获取ThingsBoard数据并填充到DTO fillTuohengDockDetail(dto, device.getIotDeviceId()); // 查询关联的无人机 List aircrafts = dockAircraftDomain.selectDockAircraftByDockId(dockId); if (!CollectionUtils.isEmpty(aircrafts)) { DockAircraft dockAircraft = aircrafts.get(0); Aircraft aircraft = aircraftDomain.selectAircraftByAircraftId(dockAircraft.getAircraftId()); if (aircraft != null) { dto.setAircraftId(aircraft.getAircraftId()); dto.setAircraftName(aircraft.getAircraftName()); Device airDevice = deviceDomain.selectDeviceByDeviceId(aircraft.getDeviceId()); if (airDevice != null) { dto.setAircraftIotId(airDevice.getIotDeviceId()); // 填充无人机状态信息 fillTuohengAircraftStatus(dto, airDevice.getIotDeviceId()); } } } return dto; } @Override public AircraftDetailDTO getAircraftDetailById(Long aircraftId) { log.info("获取拓恒无人机详情: aircraftId={}", aircraftId); // 查询无人机基础信息 Aircraft aircraft = aircraftDomain.selectAircraftByAircraftId(aircraftId); if (aircraft == null) { log.warn("无人机不存在: aircraftId={}", aircraftId); return null; } // 查询设备信息 Device device = deviceDomain.selectDeviceByDeviceId(aircraft.getDeviceId()); if (device == null) { log.warn("无人机对应的设备不存在: deviceId={}", aircraft.getDeviceId()); return null; } // 检查是否是拓恒设备 if (!"tuoheng".equals(device.getDeviceManufacturer())) { log.warn("设备不是拓恒厂商: deviceId={}, manufacturer={}", device.getDeviceId(), device.getDeviceManufacturer()); return null; } // 构建无人机详情DTO AircraftDetailDTO dto = new AircraftDetailDTO(); dto.setAircraftId(aircraft.getAircraftId()); dto.setAircraftName(aircraft.getAircraftName()); dto.setSnNumber(device.getDeviceSn()); dto.setBindTime(device.getCreateTime().getTime()); // 获取ThingsBoard数据并填充到DTO fillTuohengAircraftDetail(dto, device.getIotDeviceId()); return dto; } @Override public Map getDockDetailsByIds(List dockIds) { if (CollectionUtils.isEmpty(dockIds)) { return new HashMap<>(); } Map resultMap = new HashMap<>(dockIds.size()); for (Long dockId : dockIds) { try { DockDetailDTO dto = getDockDetailById(dockId); if (dto != null) { resultMap.put(dockId, dto); } } catch (Exception e) { log.error("获取拓恒机场详情失败, dockId: {}", dockId, e); } } return resultMap; } @Override public Map getAircraftDetailsByIds(List aircraftIds) { if (CollectionUtils.isEmpty(aircraftIds)) { return new HashMap<>(); } Map resultMap = new HashMap<>(aircraftIds.size()); for (Long aircraftId : aircraftIds) { try { AircraftDetailDTO dto = getAircraftDetailById(aircraftId); if (dto != null) { resultMap.put(aircraftId, dto); } } catch (Exception e) { log.error("获取拓恒无人机详情失败, aircraftId: {}", aircraftId, e); } } return resultMap; } /** * 填充拓恒机场详情数据 * * @param dto 机场详情DTO * @param iotDeviceId ThingsBoard设备ID */ private void fillTuohengDockDetail(DockDetailDTO dto, String iotDeviceId) { try { log.info("========== 开始填充拓恒机场详情 =========="); log.info("iotDeviceId: {}", iotDeviceId); // 获取拓恒设备属性 AttributeMap attributes = thingsBoardDomain.getPredefinedTuohengDeviceAttributes(iotDeviceId); log.info("拓恒设备属性数据: {}", attributes); // 获取拓恒设备遥测数据 TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(iotDeviceId); log.info("拓恒设备遥测数据: {}", telemetry); // 设置在线状态 Boolean isActive = attributes.get(TuohengDeviceAttributes.ACTIVE).orElse(false); log.info("设备在线状态 ACTIVE: {}", isActive); if (isActive) { telemetry.get(TuohengDeviceTelemetry.STATUS).ifPresent(statusValue -> { String status = statusValue.getValue(); log.info("STATUS 遥测值: {}", status); String dockStatus = "online".equals(status) ? "IDLE" : "OFFLINE"; dto.setDockStatus(dockStatus); log.info("设置机场状态: {}", dockStatus); }); } else { dto.setDockStatus("OFFLINE"); log.info("设备离线,设置机场状态为 OFFLINE"); } // 设置舱内温度和湿度 log.info("---------- 解析舱内环境数据 ----------"); telemetry.get(TuohengDeviceTelemetry.NEST_INNER_TEMP) .ifPresent(value -> { log.info("NEST_INNER_TEMP 舱内温度: {}", value.getValue()); dto.setCabinTemperature(value.getValue()); }); telemetry.get(TuohengDeviceTelemetry.NEST_INNER_HUM) .ifPresent(value -> { log.info("NEST_INNER_HUM 舱内湿度: {}", value.getValue()); dto.setCabinHumidity(value.getValue()); }); // 设置环境数据 log.info("---------- 解析气象数据 ----------"); telemetry.get(TuohengDeviceTelemetry.NEST_INNER_TEMP) .ifPresent(value -> { log.info("环境温度(使用舱内温度): {}", value.getValue()); dto.setEnvironmentTemperature(value.getValue()); }); telemetry.get(TuohengDeviceTelemetry.WEATHER_WIND_SPEED) .ifPresent(value -> { log.info("WEATHER_WIND_SPEED 风速: {}", value.getValue()); dto.setWindSpeed(value.getValue()); }); telemetry.get(TuohengDeviceTelemetry.WEATHER_RAINFALL) .ifPresent(value -> { log.info("WEATHER_RAINFALL 降雨量: {}", value.getValue()); dto.setRainfall(value.getValue()); }); // 设置电池信息 log.info("---------- 解析电池数据 ----------"); telemetry.get(TuohengDeviceTelemetry.BATTERY_LEVEL) .ifPresent(value -> { log.info("BATTERY_LEVEL 电池电量: {}", value.getValue()); dto.setCapacity_percent(value.getValue()); }); // 设置充电状态 telemetry.get(TuohengDeviceTelemetry.BATTERY_B_CHARGING) .ifPresent(value -> { log.info("BATTERY_B_CHARGING 充电状态原始值: {}", value.getValue()); String chargingStatus = value.getValue() == 1 ? "CHARGING" : "FREE"; dto.setChargingStatus(chargingStatus); log.info("设置充电状态: {}", chargingStatus); }); log.info("拓恒机场详情填充完成: iotDeviceId={}, dockStatus={}", iotDeviceId, dto.getDockStatus()); log.info("========== 拓恒机场详情填充结束 =========="); } catch (Exception e) { log.error("填充拓恒机场详情失败: iotDeviceId={}, error={}", iotDeviceId, e.getMessage(), e); } } /** * 填充拓恒无人机状态信息(用于机场详情中的无人机状态) * * @param dto 机场详情DTO * @param aircraftIotDeviceId 无人机ThingsBoard设备ID */ private void fillTuohengAircraftStatus(DockDetailDTO dto, String aircraftIotDeviceId) { try { log.info("========== 开始填充拓恒无人机状态(机场详情中) =========="); log.info("aircraftIotDeviceId: {}", aircraftIotDeviceId); // 获取拓恒无人机遥测数据 TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(aircraftIotDeviceId); log.info("拓恒无人机遥测数据: {}", telemetry); // 设置无人机状态 - 根据 armed 状态判断 telemetry.get(TuohengDeviceTelemetry.ARMED).ifPresent(armedValue -> { String armed = armedValue.getValue(); log.info("ARMED 解锁状态原始值: {}", armed); if ("true".equals(armed) || "1".equals(armed)) { dto.setAircraftStatus("IN_MISSION"); // 解锁状态表示在任务中 log.info("设置无人机状态: IN_MISSION (任务中)"); } else { dto.setAircraftStatus("POWER_ON_IN_CABIN"); // 未解锁表示在舱内待机 log.info("设置无人机状态: POWER_ON_IN_CABIN (舱内待机)"); } }); // 设置作业架次 - 暂时设置为0,拓恒设备可能没有这个数据 dto.setMissionCount(0); log.info("设置作业架次: 0 (拓恒设备暂无此数据)"); log.info("拓恒无人机状态填充完成: aircraftIotDeviceId={}, aircraftStatus={}", aircraftIotDeviceId, dto.getAircraftStatus()); log.info("========== 拓恒无人机状态填充结束 =========="); } catch (Exception e) { log.error("填充拓恒无人机状态失败: aircraftIotDeviceId={}, error={}", aircraftIotDeviceId, e.getMessage(), e); } } /** * 填充拓恒无人机详情数据 * * @param dto 无人机详情DTO * @param iotDeviceId ThingsBoard设备ID */ private void fillTuohengAircraftDetail(AircraftDetailDTO dto, String iotDeviceId) { try { log.info("========== 开始填充拓恒无人机详情 =========="); log.info("iotDeviceId: {}", iotDeviceId); // 获取拓恒设备属性 AttributeMap attributes = thingsBoardDomain.getPredefinedTuohengDeviceAttributes(iotDeviceId); log.info("拓恒无人机属性数据: {}", attributes); // 获取拓恒设备遥测数据 TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(iotDeviceId); log.info("拓恒无人机遥测数据: {}", telemetry); // 设置无人机状态 log.info("---------- 解析无人机状态 ----------"); telemetry.get(TuohengDeviceTelemetry.ARMED).ifPresent(armedValue -> { String armed = armedValue.getValue(); log.info("ARMED 解锁状态: {}", armed); if ("true".equals(armed) || "1".equals(armed)) { dto.setAircraftStatus("IN_MISSION"); log.info("设置无人机状态: IN_MISSION"); } else { dto.setAircraftStatus("POWER_ON_IN_CABIN"); log.info("设置无人机状态: POWER_ON_IN_CABIN"); } }); // 设置作业架次 - 暂时设置为0 dto.setMissionCount(0); log.info("设置作业架次: 0"); // 设置GPS信号 log.info("---------- 解析GPS数据 ----------"); telemetry.get(TuohengDeviceTelemetry.SAT_COUNT) .ifPresent(value -> { log.info("SAT_COUNT 卫星数量: {}", value.getValue()); dto.setGpsSignal(value.getValue()); }); // 设置电池信息 log.info("---------- 解析电池数据 ----------"); telemetry.get(TuohengDeviceTelemetry.BATTERY_REMAIN) .ifPresent(value -> { log.info("BATTERY_REMAIN 剩余电量: {}", value.getValue()); dto.setBatteryLevel(value.getValue()); }); telemetry.get(TuohengDeviceTelemetry.VOLTAGE) .ifPresent(value -> { log.info("VOLTAGE 电压原始值: {}", value.getValue()); Double voltage = value.getValue(); if (voltage != null) { dto.setVoltage(voltage.intValue()); log.info("VOLTAGE 电压转换后: {}", voltage.intValue()); } }); // 设置飞行时长(秒) log.info("---------- 解析飞行数据 ----------"); telemetry.get(TuohengDeviceTelemetry.FLIGHT_TIME) .ifPresent(value -> { log.info("FLIGHT_TIME 飞行时长(秒): {}", value.getValue()); dto.setFlightDuration(value.getValue()); }); log.info("拓恒无人机详情填充完成: iotDeviceId={}, aircraftStatus={}", iotDeviceId, dto.getAircraftStatus()); log.info("========== 拓恒无人机详情填充结束 =========="); } catch (Exception e) { log.error("填充拓恒无人机详情失败: iotDeviceId={}, error={}", iotDeviceId, e.getMessage(), e); } } }