a-tuoheng-device/src/main/java/com/ruoyi/device/service/impl/BufferDeviceImpl.java

251 lines
9.1 KiB
Java
Raw Normal View History

2026-01-20 14:54:53 +08:00
package com.ruoyi.device.service.impl;
2026-01-21 13:43:27 +08:00
import com.alibaba.fastjson2.JSON;
2026-01-21 17:05:10 +08:00
import com.ruoyi.device.api.domain.PayloadVO;
import com.ruoyi.device.api.enums.PayloadStatusEnum;
2026-01-21 16:12:50 +08:00
import com.ruoyi.device.domain.api.*;
2026-01-21 17:05:10 +08:00
import com.ruoyi.device.domain.model.*;
2026-01-21 15:37:43 +08:00
import com.ruoyi.device.domain.model.thingsboard.AttributeMap;
import com.ruoyi.device.domain.model.thingsboard.TelemetryMap;
2026-01-21 15:47:50 +08:00
import com.ruoyi.device.domain.model.thingsboard.constants.DeviceAttributes;
2026-01-21 16:29:46 +08:00
import com.ruoyi.device.domain.model.thingsboard.constants.DeviceTelemetry;
2026-01-20 14:54:53 +08:00
import com.ruoyi.device.service.api.IBufferDeviceService;
2026-01-21 16:12:50 +08:00
import com.ruoyi.device.service.dto.AircraftDTO;
2026-01-20 15:37:54 +08:00
import com.ruoyi.device.service.dto.AircraftDetailDTO;
import com.ruoyi.device.service.dto.DockDetailDTO;
2026-01-21 16:29:46 +08:00
import com.ruoyi.device.api.enums.AircraftStatusEnum;
2026-01-21 15:58:12 +08:00
import com.ruoyi.device.api.enums.DockStatusEnum;
2026-01-21 15:19:55 +08:00
2026-01-21 13:43:27 +08:00
import lombok.extern.slf4j.Slf4j;
2026-01-20 15:37:54 +08:00
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
2026-01-21 16:12:50 +08:00
import org.springframework.util.CollectionUtils;
2026-01-20 15:37:54 +08:00
2026-01-21 17:05:10 +08:00
import java.util.ArrayList;
2026-01-20 15:37:54 +08:00
import java.util.List;
import java.util.stream.Collectors;
2026-01-20 14:54:53 +08:00
/**
2026-01-20 15:37:54 +08:00
* 设备缓冲服务实现
* 整合数据库数据和ThingsBoard数据
2026-01-20 14:54:53 +08:00
*
2026-01-20 15:37:54 +08:00
* @author ruoyi
* @date 2026-01-20
2026-01-20 14:54:53 +08:00
*/
2026-01-20 15:37:54 +08:00
@Service
2026-01-21 13:43:27 +08:00
@Slf4j
2026-01-20 15:37:54 +08:00
public class BufferDeviceImpl implements IBufferDeviceService
{
@Autowired
private IDockDomain dockDomain;
2026-01-20 17:05:25 +08:00
@Autowired
private IDeviceDomain deviceDomain;
2026-01-20 15:37:54 +08:00
@Autowired
private IAircraftDomain aircraftDomain;
2026-01-21 17:05:10 +08:00
@Autowired
private IAircraftPayloadDomain aircraftPayloadDomain;
2026-01-21 16:12:50 +08:00
@Autowired
private IDockAircraftDomain dockAircraftDomain;
2026-01-20 15:37:54 +08:00
@Autowired
private IThingsBoardDomain thingsBoardDomain;
2026-01-21 17:05:10 +08:00
@Autowired
private IPayloadDomain payloadDomain;
2026-01-20 15:37:54 +08:00
@Override
public DockDetailDTO getDockDetailById(Long dockId)
{
2026-01-21 14:16:24 +08:00
2026-01-20 15:37:54 +08:00
Dock dock = dockDomain.selectDockByDockId(dockId);
2026-01-21 14:16:24 +08:00
log.info("selectDockByDockId {}",JSON.toJSONString(dock));
2026-01-20 15:37:54 +08:00
if (dock == null)
{
return null;
}
2026-01-21 14:16:24 +08:00
2026-01-20 17:05:25 +08:00
Device device = deviceDomain.selectDeviceByDeviceId(dock.getDeviceId());
2026-01-21 14:16:24 +08:00
log.info("selectDeviceByDeviceId {}",JSON.toJSONString(device));
2026-01-21 15:16:32 +08:00
DockDetailDTO dto = getChangeAbleDockDetailDTO(device.getIotDeviceId());
dto.setDockId(dock.getDockId());
dto.setDockName(dock.getDockName());
dto.setDockLocation(dock.getDockLocation());
dto.setDockIotId(device.getIotDeviceId());
2026-01-21 16:12:50 +08:00
2026-01-21 16:29:46 +08:00
2026-01-21 16:12:50 +08:00
List<DockAircraft> aircrafts = dockAircraftDomain.selectDockAircraftByDockId(dockId);
if(!CollectionUtils.isEmpty(aircrafts)){
DockAircraft dockAircraft = aircrafts.get(0);
Aircraft aircraft = aircraftDomain.selectAircraftByAircraftId(dockAircraft.getAircraftId());
dto.setAircraftId(aircraft.getAircraftId());
dto.setAircraftName(aircraft.getAircraftName());
Device airDevice = deviceDomain.selectDeviceByDeviceId(aircraft.getDeviceId());
dto.setAircraftIotId(airDevice.getIotDeviceId());
2026-01-21 17:05:10 +08:00
List<AircraftPayload> aircraftPayloads =
aircraftPayloadDomain.selectAircraftPayloadByAircraftId(aircraft.getAircraftId());
if(!CollectionUtils.isEmpty(aircraftPayloads)){
List<PayloadVO> payloads = new ArrayList<>(aircraftPayloads.size());
for(AircraftPayload aircraftPayload : aircraftPayloads){
Payload payload = payloadDomain.selectPayloadByPayloadId(aircraftPayload.getPayloadId());
PayloadVO payloadVO = new PayloadVO();
payloadVO.setPayloadId(aircraftPayload.getPayloadId());
payloadVO.setPayloadName(payload.getPayloadName());
payloadVO.setPayloadType(payload.getPayloadType());
payloadVO.setPayloadStatus(PayloadStatusEnum.ONLINE.getCode());
}
dto.setPayloadList(payloads);
}
2026-01-21 16:29:46 +08:00
AircraftDetailDTO aircraftDetailDTO = getChangeAbleAirDetailDTO(airDevice.getIotDeviceId());
/**
* 设置无人机状态
*/
2026-01-21 16:34:15 +08:00
dto.setAircraftStatus(aircraftDetailDTO.getAircraftStatus());
2026-01-21 16:12:50 +08:00
}
2026-01-21 15:37:43 +08:00
return dto;
2026-01-21 14:16:24 +08:00
2026-01-20 15:37:54 +08:00
}
@Override
2026-01-21 16:29:46 +08:00
public AircraftDetailDTO getAircraftDetailById(Long aircraftId) {
2026-01-21 15:16:32 +08:00
return null;
2026-01-20 15:37:54 +08:00
}
2026-01-21 16:29:46 +08:00
2026-01-21 15:16:32 +08:00
private DockDetailDTO getChangeAbleDockDetailDTO(String deviceIotId)
2026-01-20 15:37:54 +08:00
{
2026-01-21 15:37:43 +08:00
DockDetailDTO dto = new DockDetailDTO();
AttributeMap attributeMap = thingsBoardDomain.getPredefinedDeviceAttributes(deviceIotId);
TelemetryMap telemetryMap = thingsBoardDomain.getPredefinedDeviceTelemetry(deviceIotId);
2026-01-20 15:37:54 +08:00
2026-01-21 15:47:50 +08:00
// 根据 MODE_CODE 设置机场状态
// MODE_CODE 定义: {"0":"空闲中","1":"现场调试","2":"远程调试","3":"固件升级中","4":"作业中","5":"待标定"}
attributeMap.get(DeviceAttributes.MODE_CODE).ifPresent(modeCode -> {
String dockStatus = mapModeCodeToDockStatus(modeCode);
dto.setDockStatus(dockStatus);
});
2026-01-21 15:37:43 +08:00
return dto;
2026-01-20 15:37:54 +08:00
}
2026-01-21 15:47:50 +08:00
/**
* MODE_CODE 映射到机场状态
* @param modeCode 模式代码
* @return 机场状态字符串
*/
private String mapModeCodeToDockStatus(Integer modeCode) {
switch (modeCode) {
case 0:
return DockStatusEnum.IDLE.getCode();
case 1:
case 2:
return DockStatusEnum.Debugging.getCode();
case 3:
return DockStatusEnum.FIRMWARE_UPGRADING.getCode();
case 4:
return DockStatusEnum.WORKING.getCode();
case 5:
default:
return DockStatusEnum.UNKNOWN.getCode();
}
}
2026-01-21 15:16:32 +08:00
private AircraftDetailDTO getChangeAbleAirDetailDTO(String deviceIotId)
2026-01-20 15:37:54 +08:00
{
2026-01-21 16:29:46 +08:00
AircraftDetailDTO dto = new AircraftDetailDTO();
AttributeMap attributeMap = thingsBoardDomain.getPredefinedDeviceAttributes(deviceIotId);
TelemetryMap telemetryMap = thingsBoardDomain.getPredefinedDeviceTelemetry(deviceIotId);
2026-01-20 15:37:54 +08:00
2026-01-21 16:29:46 +08:00
//设置aircraftStatus
// drone_in_dock 表示是否在舱外
// device_online_status 表示是否开机
// 先判断机场的状态是否是
// 任务中 和 调试, 这两个状态用机场的, 暂时不要用离线状态
//
String aircraftStatus = determineAircraftStatus(attributeMap, telemetryMap);
dto.setAircraftStatus(aircraftStatus);
return dto;
}
/**
* 根据设备属性和遥测数据确定无人机状态
*
* @param attributeMap 设备属性映射
* @param telemetryMap 设备遥测数据映射
* @return 无人机状态字符串
*/
private String determineAircraftStatus(AttributeMap attributeMap, TelemetryMap telemetryMap) {
// 先检查 MODE_CODE判断是否处于任务中或调试状态
// MODE_CODE 定义: {"0":"待机","1":"起飞准备","2":"起飞准备完毕","3":"手动飞行","4":"自动起飞",
// "5":"航线飞行","6":"全景拍照","7":"智能跟随","8":"ADS-B 躲避","9":"自动返航",
// "10":"自动降落","11":"强制降落","12":"三桨叶降落","13":"升级中","14":"未连接",
// "15":"APAS","16":"虚拟摇杆状态","17":"指令飞行","18":"空中 RTK 收敛模式",
// "19":"机场选址中","20":"POI环绕"}
Integer modeCode = attributeMap.get(DeviceAttributes.MODE_CODE).orElse(null);
if (modeCode != null) {
// 14 = 未连接,直接返回离线状态
if (modeCode == 14) {
return AircraftStatusEnum.OFFLINE.getCode();
}
// 判断是否在任务中 (飞行相关状态: 1-12, 15-20)
if (modeCode >= 1 && modeCode <= 12 || modeCode >= 15 && modeCode <= 20) {
return AircraftStatusEnum.IN_MISSION.getCode();
}
}
// 获取无人机是否在舱内: {"0":"舱外","1":"舱内"}
Integer droneInDock = telemetryMap.get(DeviceTelemetry.Drone_In_Dock)
.map(telemetryValue -> telemetryValue.getValue())
.orElse(null);
// 获取无人机是否开机: {"0":"关机","1":"开机"}
Integer deviceOnlineStatus = telemetryMap.get(DeviceTelemetry.Sub_Device_Online_Status)
.map(telemetryValue -> telemetryValue.getValue())
.orElse(null);
// 根据舱内/舱外和开机/关机状态确定无人机状态
boolean isInCabin = droneInDock != null && droneInDock == 1;
boolean isPowerOn = deviceOnlineStatus != null && deviceOnlineStatus == 1;
if (isInCabin) {
// 舱内
if (isPowerOn) {
return AircraftStatusEnum.POWER_ON_IN_CABIN.getCode();
} else {
return AircraftStatusEnum.POWER_OFF_IN_CABIN.getCode();
}
} else {
// 舱外
if (isPowerOn) {
return AircraftStatusEnum.POWER_ON_OUT_CABIN.getCode();
} else {
return AircraftStatusEnum.POWER_OFF_OUT_CABIN.getCode();
}
}
2026-01-20 15:37:54 +08:00
}
2026-01-21 15:16:32 +08:00
2026-01-20 14:54:53 +08:00
}