rain
2024-06-14 8d9a2d656e4ae007590c622e5f7c228adacdca49
src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java
@@ -1,22 +1,32 @@
package com.dji.sample.manage.service.impl;
import com.dji.sample.component.mqtt.model.TopicStateReceiver;
import com.dji.sample.component.mqtt.model.CommonTopicReceiver;
import com.dji.sample.component.redis.RedisConst;
import com.dji.sample.component.redis.RedisOpsUtils;
import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession;
import com.dji.sample.component.websocket.model.BizCodeEnum;
import com.dji.sample.component.websocket.model.CustomWebSocketMessage;
import com.dji.sample.manage.model.DeviceStatusManager;
import com.dji.sample.log.model.entity.DroneFlightLogEntity;
import com.dji.sample.log.model.entity.DroneFlightLogInfoEntity;
import com.dji.sample.log.service.IDroneFlightLogInfoService;
import com.dji.sample.log.service.IDroneFlightLogService;
import com.dji.sample.manage.model.dto.DeviceDTO;
import com.dji.sample.manage.model.dto.DevicePayloadDTO;
import com.dji.sample.manage.model.dto.TelemetryDTO;
import com.dji.sample.manage.model.dto.TelemetryDeviceDTO;
import com.dji.sample.manage.model.enums.DeviceDomainEnum;
import com.dji.sample.manage.model.enums.DeviceModeCodeEnum;
import com.dji.sample.manage.model.receiver.OsdPayloadReceiver;
import com.dji.sample.manage.model.receiver.OsdSubDeviceReceiver;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * @author sean
@@ -24,10 +34,17 @@
 * @date 2022/2/21
 */
@Service
@Slf4j
public class DeviceOSDServiceImpl extends AbstractTSAService {
    protected DeviceOSDServiceImpl() {
        super(null);
    @Autowired
    private IDroneFlightLogService droneFlightLogService;
    @Autowired
    private IDroneFlightLogInfoService droneFlightLogInfoService;
    protected DeviceOSDServiceImpl(@Autowired @Qualifier("dockOSDServiceImpl") AbstractTSAService tsaService) {
        super(tsaService);
    }
    @Override
@@ -50,20 +67,85 @@
        }
    }
    @Override
    protected void handleOSD(TopicStateReceiver receiver, String sn, String workspaceId, JsonNode hostNode,
                             Collection<ConcurrentWebSocketSession> webSessions, CustomWebSocketMessage wsMessage) throws JsonProcessingException {
        // Real-time update of device status in memory
        DeviceStatusManager.STATUS_MANAGER.put(
                DeviceDomainEnum.SUB_DEVICE.getVal() + "/" + sn, LocalDateTime.now());
        wsMessage.setBizCode(BizCodeEnum.DEVICE_OSD.getCode());
    public void handleOSD(CommonTopicReceiver receiver, DeviceDTO device,
                          Collection<ConcurrentWebSocketSession> webSessions,
                          CustomWebSocketMessage<TelemetryDTO> wsMessage) {
        if (DeviceDomainEnum.SUB_DEVICE.getVal() == device.getDomain()) {
            wsMessage.setBizCode(BizCodeEnum.DEVICE_OSD.getCode());
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        OsdSubDeviceReceiver data = mapper.treeToValue(hostNode, OsdSubDeviceReceiver.class);
            OsdSubDeviceReceiver data = mapper.convertValue(receiver.getData(), OsdSubDeviceReceiver.class);
        wsMessage.setData(data);
            //保存飞行日志 状态启动 "3":"手动飞行","4":"自动起飞","5":"航线飞行"
            if (DeviceModeCodeEnum.MANUAL.getVal() == data.getModeCode().getVal() ||
                    DeviceModeCodeEnum.TAKEOFF_AUTO.getVal() == data.getModeCode().getVal() ||
                    DeviceModeCodeEnum.WAYLINE.getVal() == data.getModeCode().getVal() ) {
                if (!RedisOpsUtils.checkExist(RedisConst.FLIGHT_LOG + device.getDeviceSn())) {
                    // 开始记录日志
                    DroneFlightLogEntity dflPo = DroneFlightLogEntity.builder()
                            .deviceSn(device.getDeviceSn())
                            .deviceName(device.getDeviceName())
                            .nickname(device.getNickname())
                            .workspaceId(device.getWorkspaceId())
                            .title(data.getModeCode().getVal() == 3?"手动飞行":data.getModeCode().getVal() == 4?"自动起飞":data.getModeCode().getVal() == 5?"航线飞行":"未知")
                            .startTime(System.currentTimeMillis())
                            .trackId(data.getTrackId())
                            .jobId(String.valueOf(RedisOpsUtils.get(RedisConst.FLIGHT_LOG + "job_id")))
                            .startFlightDistance(data.getTotalFlightDistance())
                            .build();
                    droneFlightLogService.save(dflPo);
                    //缓存对象用于关联数据
                    RedisOpsUtils.set(RedisConst.FLIGHT_LOG + device.getDeviceSn(),dflPo);
                }
            }
        sendMessageService.sendBatch(webSessions, wsMessage);
        this.pushTelemetryData(workspaceId, data, sn);
            //状态0时取消
            if (DeviceModeCodeEnum.IDLE.getVal() == data.getModeCode().getVal()) {
                //如果存在则删除并保存结束时间
                if (RedisOpsUtils.checkExist(RedisConst.FLIGHT_LOG + device.getDeviceSn())) {
                    DroneFlightLogEntity dflPo = (DroneFlightLogEntity) RedisOpsUtils.get(RedisConst.FLIGHT_LOG + device.getDeviceSn());
                    dflPo.setEndTime(System.currentTimeMillis());
                    dflPo.setTotalFlightDistance(data.getTotalFlightDistance());
                    dflPo.setEndFlightDistance(data.getTotalFlightDistance());
                    droneFlightLogService.update(dflPo);
                    RedisOpsUtils.del(RedisConst.FLIGHT_LOG + device.getDeviceSn());
                }
            }
            //保存无人机实时位置信息
            if (RedisOpsUtils.checkExist(RedisConst.FLIGHT_LOG + device.getDeviceSn())) {
                DroneFlightLogEntity dflPo = (DroneFlightLogEntity) RedisOpsUtils.get(RedisConst.FLIGHT_LOG + device.getDeviceSn());
                DroneFlightLogInfoEntity dfliPo = DroneFlightLogInfoEntity.builder()
                        .latitude(data.getLatitude())
                        .longitude(data.getLongitude())
                        .flightId(dflPo.getId())
                        .height(data.getHeight())
                        .elevation(data.getElevation())
                        .build();
                droneFlightLogInfoService.save(dfliPo);
            }
            List<DevicePayloadDTO> payloadsList = device.getPayloadsList();
            try {
                Map<String, Object> receiverData = (Map<String, Object>) receiver.getData();
                data.setPayloads(payloadsList.stream()
                        .map(payload -> mapper.convertValue(
                                receiverData.getOrDefault(payload.getPayloadIndex(), Map.of()),
                                OsdPayloadReceiver.class))
                        .collect(Collectors.toList()));
            } catch (NullPointerException e) {
                log.warn("Please remount the payload, or restart the drone. Otherwise the data of the payload will not be received.");
            }
            RedisOpsUtils.setWithExpire(RedisConst.OSD_PREFIX + device.getDeviceSn(), data, RedisConst.DEVICE_ALIVE_SECOND);
            wsMessage.getData().setHost(data);
            sendMessageService.sendBatch(webSessions, wsMessage);
            this.pushTelemetryData(device.getWorkspaceId(), data, device.getDeviceSn());
        }
        tsaService.handleOSD(receiver, device, webSessions, wsMessage);
    }
}