sean.zhou
2023-04-25 694b9483c7a551626244cbc222c602ea9ff74094
src/main/java/com/dji/sample/manage/service/impl/DevicePayloadServiceImpl.java
@@ -2,21 +2,31 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.dji.sample.component.mqtt.model.ChannelName;
import com.dji.sample.component.redis.RedisConst;
import com.dji.sample.component.redis.RedisOpsUtils;
import com.dji.sample.component.websocket.model.BizCodeEnum;
import com.dji.sample.component.websocket.service.ISendMessageService;
import com.dji.sample.control.model.enums.DroneAuthorityEnum;
import com.dji.sample.manage.dao.IDevicePayloadMapper;
import com.dji.sample.manage.model.dto.DeviceAuthorityDTO;
import com.dji.sample.manage.model.dto.DeviceDTO;
import com.dji.sample.manage.model.dto.DeviceDictionaryDTO;
import com.dji.sample.manage.model.dto.DevicePayloadDTO;
import com.dji.sample.manage.model.entity.DevicePayloadEntity;
import com.dji.sample.manage.model.enums.ControlSourceEnum;
import com.dji.sample.manage.model.enums.DeviceDomainEnum;
import com.dji.sample.manage.model.enums.UserTypeEnum;
import com.dji.sample.manage.model.receiver.DevicePayloadReceiver;
import com.dji.sample.manage.model.receiver.FirmwareVersionReceiver;
import com.dji.sample.manage.service.ICapacityCameraService;
import com.dji.sample.manage.service.IDeviceDictionaryService;
import com.dji.sample.manage.service.IDevicePayloadService;
import com.dji.sample.manage.service.IDeviceRedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@@ -43,6 +53,12 @@
    @Autowired
    private ICapacityCameraService capacityCameraService;
    @Autowired
    private ISendMessageService sendMessageService;
    @Autowired
    private IDeviceRedisService deviceRedisService;
    @Override
    public Integer checkPayloadExist(String payloadSn) {
        DevicePayloadEntity devicePayload = mapper.selectOne(
@@ -56,7 +72,9 @@
        // If it already exists, update the data directly.
        if (id > 0) {
            entity.setId(id);
            return mapper.updateById(entity);
            // For the payload of the drone itself, there is no firmware version.
            entity.setFirmwareVersion(null);
            return mapper.updateById(entity) > 0 ? entity.getId() : 0;
        }
        return mapper.insert(entity) > 0 ? entity.getId() : 0;
    }
@@ -68,9 +86,17 @@
        }
        String deviceSn = payloadReceiverList.get(0).getDeviceSn();
        String key = RedisConst.DEVICE_ONLINE_PREFIX + deviceSn;
        DeviceDTO device = (DeviceDTO) RedisOpsUtils.get(key);
        Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(deviceSn);
        if (deviceOpt.isEmpty()) {
            return false;
        }
        DeviceDTO device = deviceOpt.get();
        List<DevicePayloadDTO> payloads = new ArrayList<>();
        Map<String, String> controlMap = CollectionUtils.isEmpty(device.getPayloadsList()) ?
                Collections.emptyMap() :
                device.getPayloadsList().stream()
                        .collect(Collectors.toMap(DevicePayloadDTO::getPayloadIndex, DevicePayloadDTO::getControlSource));
        for (DevicePayloadReceiver payloadReceiver : payloadReceiverList) {
            int payloadId = this.saveOnePayloadDTO(payloadReceiver);
@@ -78,13 +104,23 @@
                return false;
            }
            payloads.add(this.receiver2Dto(payloadReceiver));
            if (!controlMap.getOrDefault(payloadReceiver.getPayloadIndex(), "").equals(payloadReceiver.getControlSource())) {
                sendMessageService.sendBatch(device.getWorkspaceId(), UserTypeEnum.WEB.getVal(),
                                    BizCodeEnum.CONTROL_SOURCE_CHANGE.getCode(),
                                    DeviceAuthorityDTO.builder()
                                            .controlSource(payloadReceiver.getControlSource())
                                            .sn(payloadReceiver.getSn())
                                            .type(DroneAuthorityEnum.PAYLOAD)
                                            .build());
            }
        }
        if (payloads.isEmpty()) {
            payloads = this.getDevicePayloadEntitiesByDeviceSn(deviceSn);
        }
        device.setPayloadsList(payloads);
        RedisOpsUtils.setWithExpire(RedisConst.DEVICE_ONLINE_PREFIX + device.getDeviceSn(), device, RedisConst.DEVICE_ALIVE_SECOND);
        deviceRedisService.setDeviceOnline(device);
        return true;
    }
@@ -122,33 +158,35 @@
                        .eq(DevicePayloadEntity::getDeviceSn, receiver.getSn()));
    }
    @Override
    public void saveDeviceBasicPayload(List<DevicePayloadReceiver> payloadReceiverList, Long timestamp) {
    /**
     * Handle payload data for devices.
     * @param payloadReceiverList
     * @param headers
     */
    @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_PAYLOAD)
    public void handleDeviceBasicPayload(List<DevicePayloadReceiver> payloadReceiverList, MessageHeaders headers) {
        if (payloadReceiverList.isEmpty()) {
            return;
        }
        String deviceSn = payloadReceiverList.stream().findAny().get().getDeviceSn();
        String deviceSn = payloadReceiverList.get(0).getDeviceSn();
        String key = RedisConst.STATE_PAYLOAD_PREFIX + deviceSn;
        // Solve timing problems
        long last = (long) Objects.requireNonNullElse(RedisOpsUtils.get(key), 0L);
        long timestamp = headers.getTimestamp();
        if (last > timestamp) {
            return;
        }
        // Filter unsaved payload information.
        Set<String> payloadSns = this.getDevicePayloadEntitiesByDeviceSn(payloadReceiverList.get(0).getDeviceSn())
                .stream().map(DevicePayloadDTO::getPayloadSn).collect(Collectors.toSet());
        Set<String> newPayloadSns = payloadReceiverList.stream().map(DevicePayloadReceiver::getSn).collect(Collectors.toSet());
        Set<String> needToDel = payloadSns.stream().filter(sn -> !newPayloadSns.contains(sn)).collect(Collectors.toSet());
        this.deletePayloadsByPayloadsSn(needToDel);
        List<DevicePayloadReceiver> needToSave = payloadReceiverList.stream()
                .filter(payload -> !payloadSns.contains(payload.getSn())).collect(Collectors.toList());
        payloadSns.removeAll(newPayloadSns);
        this.deletePayloadsByPayloadsSn(payloadSns);
        // Save the new payload information.
        boolean isSave = this.savePayloadDTOs(needToSave);
        boolean isSave = this.savePayloadDTOs(payloadReceiverList);
        if (isSave) {
            RedisOpsUtils.setWithExpire(key, timestamp, RedisConst.DEVICE_ALIVE_SECOND);
        }
@@ -164,6 +202,19 @@
                .or(wrapper -> payloadSns.forEach(sn -> wrapper.eq(DevicePayloadEntity::getPayloadSn, sn))));
    }
    @Override
    public Boolean checkAuthorityPayload(String deviceSn, String payloadIndex) {
        return deviceRedisService.getDeviceOnline(deviceSn).flatMap(device ->
                Optional.of(DeviceDomainEnum.SUB_DEVICE.getVal() == device.getDomain()
                        && !CollectionUtils.isEmpty(device.getPayloadsList())
                        && ControlSourceEnum.A.getControlSource()
                        .equals(device.getPayloadsList().stream()
                                .filter(payload -> payloadIndex.equals(payload.getPayloadIndex()))
                                .map(DevicePayloadDTO::getControlSource).findAny()
                                .orElse(ControlSourceEnum.B.getControlSource())))).orElse(true);
    }
    /**
     * Convert database entity objects into payload data transfer object.
     * @param entity
@@ -175,7 +226,9 @@
            builder.payloadSn(entity.getPayloadSn())
                    .payloadName(entity.getPayloadName())
                    .payloadDesc(entity.getPayloadDesc())
                    .payloadIndex(entity.getPayloadIndex());
                    .index(entity.getPayloadIndex())
                    .payloadIndex(entity.getPayloadType() + "-" + entity.getSubType() + "-" + entity.getPayloadIndex())
                    .controlSource(entity.getControlSource());
        }
        return builder.build();
    }
@@ -196,25 +249,23 @@
        String[] payloadIndexArr = dto.getPayloadIndex().split("-");
        try {
            int[] arr = Arrays.stream(payloadIndexArr)
                    .map(Integer::valueOf)
                    .mapToInt(Integer::intValue)
                    .mapToInt(Integer::parseInt)
                    .toArray();
            if (arr.length == 3) {
                Optional<DeviceDictionaryDTO> dictionaryOpt = dictionaryService
                        .getOneDictionaryInfoByTypeSubType(DeviceDomainEnum.PAYLOAD.getVal(), arr[0], arr[1]);
                dictionaryOpt.ifPresent(dictionary ->
                        builder.payloadName(dictionary.getDeviceName())
                                .payloadDesc(dictionary.getDeviceDesc()));
            Optional<DeviceDictionaryDTO> dictionaryOpt = dictionaryService
                    .getOneDictionaryInfoByTypeSubType(DeviceDomainEnum.PAYLOAD.getVal(), arr[0], arr[1]);
            dictionaryOpt.ifPresent(dictionary ->
                    builder.payloadName(dictionary.getDeviceName())
                            .payloadDesc(dictionary.getDeviceDesc()));
            }
            builder.payloadType(arr[0])
                    .subType(arr[1])
                    .payloadIndex(arr[2]);
                    .payloadIndex(arr[2])
                    .controlSource(dto.getControlSource());
        } catch (NumberFormatException e) {
            builder.payloadType(Integer.valueOf(payloadIndexArr[0]))
            builder.payloadType(-1)
                    .subType(-1)
                    .payloadIndex(Integer.valueOf(payloadIndexArr[2]));
                    .payloadIndex(-1);
        }
        return builder
@@ -229,7 +280,8 @@
            return builder.build();
        }
        return builder.payloadSn(receiver.getSn())
                .payloadName(receiver.getPayloadIndex())
                .payloadIndex(receiver.getPayloadIndex())
                .controlSource(receiver.getControlSource())
                .build();
    }