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 { // 获取拓恒设备属性 AttributeMap attributes = thingsBoardDomain.getPredefinedTuohengDeviceAttributes(iotDeviceId); // 获取拓恒设备遥测数据 TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(iotDeviceId); // 设置在线状态 Boolean isActive = attributes.get(TuohengDeviceAttributes.ACTIVE).orElse(false); if (isActive) { telemetry.get(TuohengDeviceTelemetry.STATUS).ifPresent(statusValue -> { String status = statusValue.getValue(); dto.setDockStatus("online".equals(status) ? "IDLE" : "OFFLINE"); }); } else { dto.setDockStatus("OFFLINE"); } // 设置舱内温度和湿度 telemetry.get(TuohengDeviceTelemetry.NEST_INNER_TEMP) .ifPresent(value -> dto.setCabinTemperature(value.getValue())); telemetry.get(TuohengDeviceTelemetry.NEST_INNER_HUM) .ifPresent(value -> dto.setCabinHumidity(value.getValue())); // 设置环境数据 telemetry.get(TuohengDeviceTelemetry.NEST_INNER_TEMP) .ifPresent(value -> dto.setEnvironmentTemperature(value.getValue())); telemetry.get(TuohengDeviceTelemetry.WEATHER_WIND_SPEED) .ifPresent(value -> dto.setWindSpeed(value.getValue())); telemetry.get(TuohengDeviceTelemetry.WEATHER_RAINFALL) .ifPresent(value -> dto.setRainfall(value.getValue())); // 设置电池信息 telemetry.get(TuohengDeviceTelemetry.BATTERY_LEVEL) .ifPresent(value -> dto.setCapacity_percent(value.getValue())); // 设置充电状态 telemetry.get(TuohengDeviceTelemetry.BATTERY_B_CHARGING) .ifPresent(value -> { dto.setChargingStatus(value.getValue() == 1 ? "CHARGING" : "FREE"); }); log.debug("拓恒机场详情填充完成: iotDeviceId={}", iotDeviceId); } 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 { // 获取拓恒无人机遥测数据 TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(aircraftIotDeviceId); // 设置无人机状态 - 根据 armed 状态判断 telemetry.get(TuohengDeviceTelemetry.ARMED).ifPresent(armedValue -> { String armed = armedValue.getValue(); if ("true".equals(armed) || "1".equals(armed)) { dto.setAircraftStatus("IN_MISSION"); // 解锁状态表示在任务中 } else { dto.setAircraftStatus("POWER_ON_IN_CABIN"); // 未解锁表示在舱内待机 } }); // 设置作业架次 - 暂时设置为0,拓恒设备可能没有这个数据 dto.setMissionCount(0); log.debug("拓恒无人机状态填充完成: aircraftIotDeviceId={}", aircraftIotDeviceId); } 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 { // 获取拓恒设备属性 AttributeMap attributes = thingsBoardDomain.getPredefinedTuohengDeviceAttributes(iotDeviceId); // 获取拓恒设备遥测数据 TelemetryMap telemetry = thingsBoardDomain.getPredefinedTuohengDeviceTelemetry(iotDeviceId); // 设置无人机状态 telemetry.get(TuohengDeviceTelemetry.ARMED).ifPresent(armedValue -> { String armed = armedValue.getValue(); if ("true".equals(armed) || "1".equals(armed)) { dto.setAircraftStatus("IN_MISSION"); } else { dto.setAircraftStatus("POWER_ON_IN_CABIN"); } }); // 设置作业架次 - 暂时设置为0 dto.setMissionCount(0); // 设置GPS信号 telemetry.get(TuohengDeviceTelemetry.SAT_COUNT) .ifPresent(value -> dto.setGpsSignal(value.getValue())); // 设置电池信息 telemetry.get(TuohengDeviceTelemetry.BATTERY_REMAIN) .ifPresent(value -> dto.setBatteryLevel(value.getValue())); telemetry.get(TuohengDeviceTelemetry.VOLTAGE) .ifPresent(value -> { Double voltage = value.getValue(); if (voltage != null) { dto.setVoltage(voltage.intValue()); } }); // 设置飞行时长(秒) telemetry.get(TuohengDeviceTelemetry.FLIGHT_TIME) .ifPresent(value -> dto.setFlightDuration(value.getValue())); log.debug("拓恒无人机详情填充完成: iotDeviceId={}", iotDeviceId); } catch (Exception e) { log.error("填充拓恒无人机详情失败: iotDeviceId={}, error={}", iotDeviceId, e.getMessage(), e); } } }