diff --git a/README.md b/README.md
index faf73ce..79abe85 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ For more documentation, please visit the [DJI Developer Documentation](https://d
## Latest Release
-Cloud API 1.1.0 was released on 22 July 2022. For more information, please visit the [Release Note](https://developer.dji.com/doc/cloud-api-tutorial/cn/).
+Cloud API 1.8.0 was released on 11 Dec 2023. For more information, please visit the [Release Note](https://developer.dji.com/doc/cloud-api-tutorial/cn/).
## License
diff --git a/pom.xml b/pom.xml
index 249aa19..65db1ed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
com.dji
cloud-api-sample
- 1.7.0
+ 1.8.0
cloud-api-sample
@@ -180,6 +180,11 @@
spring-boot-starter-validation
+
+
+
+
+
org.springdoc
diff --git a/sql/cloud_sample.sql b/sql/cloud_sample.sql
index 18b9c78..2e76af1 100644
--- a/sql/cloud_sample.sql
+++ b/sql/cloud_sample.sql
@@ -110,32 +110,38 @@ LOCK TABLES `manage_device_dictionary` WRITE;
INSERT INTO `manage_device_dictionary` (`id`, `domain`, `device_type`, `sub_type`, `device_name`, `device_desc`)
VALUES
- (1,0,60,0,'Matrice 300 RTK',NULL),
- (2,0,67,0,'Matrice 30',NULL),
- (3,0,67,1,'Matrice 30T',NULL),
- (4,1,20,0,'Z30',NULL),
- (5,1,26,0,'XT2',NULL),
- (6,1,39,0,'FPV',NULL),
- (7,1,41,0,'XTS',NULL),
- (8,1,42,0,'H20',NULL),
- (9,1,43,0,'H20T',NULL),
- (10,1,50,65535,'P1','include 24 and 35 and 50mm'),
- (11,1,52,0,'M30 Camera',NULL),
- (12,1,53,0,'M30T Camera',NULL),
- (13,1,61,0,'H20N',NULL),
- (14,1,165,0,'DJI Dock Camera',NULL),
- (15,1,90742,0,'L1',NULL),
- (16,2,56,0,'DJI Smart Controller','Remote control for M300'),
- (17,2,119,0,'DJI RC Plus','Remote control for M30'),
- (18,3,1,0,'DJI Dock',''),
- (19,0,77,0,'Mavic 3E',NULL),
- (20,0,77,1,'Mavic 3T',NULL),
- (21,1,66,0,'Mavic 3E Camera',NULL),
- (22,1,67,0,'Mavic 3T Camera',NULL),
- (23,2,144,0,'DJI RC Pro','Remote control for Mavic 3E/T and Mavic 3M'),
- (24,0,77,2,'Mavic 3M',NULL),
- (25,1,68,0,'Mavic 3M Camera',NULL),
- (26,0,89,0,'Matrice 350 RTK',NULL);
+ (1, 0, 60, 0, 'Matrice 300 RTK', NULL),
+ (2, 0, 67, 0, 'Matrice 30', NULL),
+ (3, 0, 67, 1, 'Matrice 30T', NULL),
+ (4, 1, 20, 0, 'Z30', NULL),
+ (5, 1, 26, 0, 'XT2', NULL),
+ (6, 1, 39, 0, 'FPV', NULL),
+ (7, 1, 41, 0, 'XTS', NULL),
+ (8, 1, 42, 0, 'H20', NULL),
+ (9, 1, 43, 0, 'H20T', NULL),
+ (10, 1, 50, 65535, 'P1', 'include 24 and 35 and 50mm'),
+ (11, 1, 52, 0, 'M30 Camera', NULL),
+ (12, 1, 53, 0, 'M30T Camera', NULL),
+ (13, 1, 61, 0, 'H20N', NULL),
+ (14, 1, 165, 0, 'DJI Dock Camera', NULL),
+ (15, 1, 90742, 0, 'L1', NULL),
+ (16, 2, 56, 0, 'DJI Smart Controller', 'Remote control for M300'),
+ (17, 2, 119, 0, 'DJI RC Plus', 'Remote control for M30'),
+ (18, 3, 1, 0, 'DJI Dock', ''),
+ (19, 0, 77, 0, 'Mavic 3E', NULL),
+ (20, 0, 77, 1, 'Mavic 3T', NULL),
+ (21, 1, 66, 0, 'Mavic 3E Camera', NULL),
+ (22, 1, 67, 0, 'Mavic 3T Camera', NULL),
+ (23, 2, 144, 0, 'DJI RC Pro', 'Remote control for Mavic 3E/T and Mavic 3M'),
+ (24, 0, 77, 2, 'Mavic 3M', NULL),
+ (25, 1, 68, 0, 'Mavic 3M Camera', NULL),
+ (26, 0, 89, 0, 'Matrice 350 RTK', NULL),
+ (27, 3, 2, 0, 'DJI Dock2', NULL),
+ (28, 0, 91, 0, 'M3D', NULL),
+ (29, 0, 91, 1, 'M3TD', NULL),
+ (30, 1, 80, 0, 'M3D Camera', NULL),
+ (31, 1, 81, 0, 'M3TD Camera', NULL);
+
/*!40000 ALTER TABLE `manage_device_dictionary` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/src/main/java/com/dji/sample/manage/service/IDeviceService.java b/src/main/java/com/dji/sample/manage/service/IDeviceService.java
index ec0452c..df0efa2 100644
--- a/src/main/java/com/dji/sample/manage/service/IDeviceService.java
+++ b/src/main/java/com/dji/sample/manage/service/IDeviceService.java
@@ -9,7 +9,7 @@ import com.dji.sdk.cloudapi.device.ControlSourceEnum;
import com.dji.sdk.cloudapi.device.DeviceOsdHost;
import com.dji.sdk.cloudapi.device.DockModeCodeEnum;
import com.dji.sdk.cloudapi.device.DroneModeCodeEnum;
-import com.dji.sdk.common.GatewayManager;
+import com.dji.sdk.config.version.GatewayManager;
import com.dji.sdk.common.HttpResultResponse;
import com.dji.sdk.common.PaginationData;
import com.fasterxml.jackson.databind.JsonNode;
diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
index f5bbe95..c4107c6 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
@@ -24,6 +24,7 @@ import com.dji.sdk.cloudapi.property.api.AbstractPropertyService;
import com.dji.sdk.cloudapi.tsa.DeviceIconUrl;
import com.dji.sdk.cloudapi.tsa.TopologyDeviceModel;
import com.dji.sdk.common.*;
+import com.dji.sdk.config.version.GatewayManager;
import com.dji.sdk.exception.CloudSDKException;
import com.dji.sdk.mqtt.IMqttTopicService;
import com.dji.sdk.mqtt.MqttGatewayPublish;
diff --git a/src/main/java/com/dji/sample/manage/service/impl/SDKDeviceService.java b/src/main/java/com/dji/sample/manage/service/impl/SDKDeviceService.java
index 81db422..f882487 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/SDKDeviceService.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/SDKDeviceService.java
@@ -14,7 +14,7 @@ import com.dji.sdk.cloudapi.device.*;
import com.dji.sdk.cloudapi.device.api.AbstractDeviceService;
import com.dji.sdk.cloudapi.tsa.DeviceIconUrl;
import com.dji.sdk.cloudapi.tsa.IconUrlEnum;
-import com.dji.sdk.common.GatewayManager;
+import com.dji.sdk.config.version.GatewayManager;
import com.dji.sdk.common.SDKManager;
import com.dji.sdk.mqtt.MqttReply;
import com.dji.sdk.mqtt.osd.TopicOsdRequest;
@@ -99,7 +99,6 @@ public class SDKDeviceService extends AbstractDeviceService {
// Subscribe to topic related to drone devices.
deviceService.subDeviceOnlineSubscribeTopic(gatewayManager);
deviceService.pushDeviceOnlineTopo(gateway.getWorkspaceId(), gateway.getDeviceSn(), subDevice.getDeviceSn());
- deviceRedisService.setDeviceOnline(subDevice);
log.debug("{} online.", subDevice.getDeviceSn());
return new TopicStatusResponse().setData(MqttReply.success());
@@ -143,14 +142,16 @@ public class SDKDeviceService extends AbstractDeviceService {
log.error("Please restart the drone.");
return;
}
-
- if (!StringUtils.hasText(deviceOpt.get().getWorkspaceId())) {
- log.error("Please bind the dock first.");
- return;
- }
}
DeviceDTO device = deviceOpt.get();
+ if (!StringUtils.hasText(device.getWorkspaceId())) {
+ log.error("Please bind the dock first.");
+ }
+ if (StringUtils.hasText(device.getChildDeviceSn())) {
+ deviceRedisService.getDeviceOnline(device.getChildDeviceSn()).ifPresent(device::setChildren);
+ }
+
deviceRedisService.setDeviceOnline(device);
fillDockOsd(from, request.getData());
@@ -193,6 +194,9 @@ public class SDKDeviceService extends AbstractDeviceService {
}
}
DeviceDTO device = deviceOpt.get();
+ if (StringUtils.hasText(device.getChildDeviceSn())) {
+ deviceRedisService.getDeviceOnline(device.getChildDeviceSn()).ifPresent(device::setChildren);
+ }
deviceRedisService.setDeviceOnline(device);
OsdRemoteControl data = request.getData();
@@ -216,14 +220,13 @@ public class SDKDeviceService extends AbstractDeviceService {
return;
}
}
- if (!StringUtils.hasText(deviceOpt.get().getWorkspaceId())) {
+ DeviceDTO device = deviceOpt.get();
+ deviceRedisService.setDeviceOnline(device);
+ if (!StringUtils.hasText(device.getWorkspaceId())) {
log.error("Please bind the drone first.");
return;
}
- DeviceDTO device = deviceOpt.get();
- deviceRedisService.setDeviceOnline(device);
-
OsdRcDrone data = request.getData();
deviceService.pushOsdDataToPilot(device.getWorkspaceId(), from,
new DeviceOsdHost()
@@ -349,9 +352,10 @@ public class SDKDeviceService extends AbstractDeviceService {
}
if (!Objects.requireNonNullElse(subDevice.getBoundStatus(), false)) {
// Directly bind the drone of the dock to the same workspace as the dock.
- deviceService.bindDevice(DeviceDTO.builder().deviceSn(subDevice.getChildDeviceSn()).workspaceId(gateway.getWorkspaceId()).build());
+ deviceService.bindDevice(DeviceDTO.builder().deviceSn(subDevice.getDeviceSn()).workspaceId(gateway.getWorkspaceId()).build());
subDevice.setWorkspaceId(gateway.getWorkspaceId());
}
+ deviceRedisService.setDeviceOnline(subDevice);
}
private void changeSubDeviceParent(String deviceSn, String gatewaySn) {
diff --git a/src/main/java/com/dji/sample/wayline/service/impl/WaylineFileServiceImpl.java b/src/main/java/com/dji/sample/wayline/service/impl/WaylineFileServiceImpl.java
index ae79c37..e478e8a 100644
--- a/src/main/java/com/dji/sample/wayline/service/impl/WaylineFileServiceImpl.java
+++ b/src/main/java/com/dji/sample/wayline/service/impl/WaylineFileServiceImpl.java
@@ -12,6 +12,8 @@ import com.dji.sample.wayline.model.entity.WaylineFileEntity;
import com.dji.sample.wayline.service.IWaylineFileService;
import com.dji.sdk.cloudapi.device.DeviceDomainEnum;
import com.dji.sdk.cloudapi.device.DeviceEnum;
+import com.dji.sdk.cloudapi.device.DeviceSubTypeEnum;
+import com.dji.sdk.cloudapi.device.DeviceTypeEnum;
import com.dji.sdk.cloudapi.wayline.GetWaylineListRequest;
import com.dji.sdk.cloudapi.wayline.GetWaylineListResponse;
import com.dji.sdk.cloudapi.wayline.WaylineTypeEnum;
@@ -206,21 +208,15 @@ public class WaylineFileServiceImpl implements IWaylineFileService {
throw new RuntimeException("The file format is incorrect.");
}
- String type = droneNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_DRONE_ENUM_VALUE);
- String subType = droneNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_DRONE_SUB_ENUM_VALUE);
- String payloadType = payloadNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_PAYLOAD_ENUM_VALUE);
- String payloadSubType = payloadNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_PAYLOAD_SUB_ENUM_VALUE);
+ DeviceTypeEnum type = DeviceTypeEnum.find(Integer.parseInt(droneNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_DRONE_ENUM_VALUE)));
+ DeviceSubTypeEnum subType = DeviceSubTypeEnum.find(Integer.parseInt(droneNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_DRONE_SUB_ENUM_VALUE)));
+ DeviceTypeEnum payloadType = DeviceTypeEnum.find(Integer.parseInt(payloadNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_PAYLOAD_ENUM_VALUE)));
+ DeviceSubTypeEnum payloadSubType = DeviceSubTypeEnum.find(Integer.parseInt(payloadNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_PAYLOAD_SUB_ENUM_VALUE)));
String templateType = document.valueOf("//" + KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_TEMPLATE_TYPE);
- if (!StringUtils.hasText(type) || !StringUtils.hasText(subType) ||
- !StringUtils.hasText(payloadSubType) || !StringUtils.hasText(payloadType) ||
- !StringUtils.hasText(templateType)) {
- throw new RuntimeException("The file format is incorrect.");
- }
-
return Optional.of(WaylineFileDTO.builder()
- .droneModelKey(String.format("%s-%s-%s", DeviceDomainEnum.DRONE.getDomain(), type, subType))
- .payloadModelKeys(List.of(String.format("%s-%s-%s",DeviceDomainEnum.PAYLOAD.getDomain(), payloadType, payloadSubType)))
+ .droneModelKey(DeviceEnum.find(DeviceDomainEnum.DRONE, type, subType).getDevice())
+ .payloadModelKeys(List.of(DeviceEnum.find(DeviceDomainEnum.PAYLOAD, payloadType, payloadSubType).getDevice()))
.objectKey(OssConfiguration.objectDirPrefix + File.separator + filename)
.name(filename.substring(0, filename.lastIndexOf(WAYLINE_FILE_SUFFIX)))
.sign(DigestUtils.md5DigestAsHex(file.getInputStream()))
diff --git a/src/main/java/com/dji/sdk/annotations/CloudSDKVersion.java b/src/main/java/com/dji/sdk/annotations/CloudSDKVersion.java
index e7476d1..0bcee6f 100644
--- a/src/main/java/com/dji/sdk/annotations/CloudSDKVersion.java
+++ b/src/main/java/com/dji/sdk/annotations/CloudSDKVersion.java
@@ -1,7 +1,7 @@
package com.dji.sdk.annotations;
-import com.dji.sdk.common.CloudSDKVersionEnum;
-import com.dji.sdk.common.GatewayTypeEnum;
+import com.dji.sdk.config.version.CloudSDKVersionEnum;
+import com.dji.sdk.config.version.GatewayTypeEnum;
import java.lang.annotation.*;
diff --git a/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java
index 2c5424e..d3d7e39 100644
--- a/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java
+++ b/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java
@@ -5,7 +5,7 @@ import com.dji.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum;
import com.dji.sdk.cloudapi.device.RcLostActionEnum;
import com.dji.sdk.cloudapi.wayline.RthModeEnum;
import com.dji.sdk.common.BaseModel;
-import com.dji.sdk.common.CloudSDKVersionEnum;
+import com.dji.sdk.config.version.CloudSDKVersionEnum;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
diff --git a/src/main/java/com/dji/sdk/cloudapi/control/api/AbstractControlService.java b/src/main/java/com/dji/sdk/cloudapi/control/api/AbstractControlService.java
index 8ea9e77..b95af0d 100644
--- a/src/main/java/com/dji/sdk/cloudapi/control/api/AbstractControlService.java
+++ b/src/main/java/com/dji/sdk/cloudapi/control/api/AbstractControlService.java
@@ -4,9 +4,9 @@ import com.dji.sdk.annotations.CloudSDKVersion;
import com.dji.sdk.cloudapi.control.*;
import com.dji.sdk.common.BaseModel;
import com.dji.sdk.common.Common;
-import com.dji.sdk.common.GatewayManager;
-import com.dji.sdk.common.GatewayTypeEnum;
-import com.dji.sdk.exception.CloudSDKErrorEnum;
+import com.dji.sdk.common.SpringBeanUtils;
+import com.dji.sdk.config.version.GatewayManager;
+import com.dji.sdk.config.version.GatewayTypeEnum;
import com.dji.sdk.exception.CloudSDKException;
import com.dji.sdk.mqtt.ChannelName;
import com.dji.sdk.mqtt.MqttReply;
@@ -23,7 +23,8 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import javax.annotation.Resource;
-import java.util.Objects;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
/**
* @author sean
@@ -278,16 +279,17 @@ public abstract class AbstractControlService {
* @param request data
* @return services_reply
*/
- @CloudSDKVersion(exclude = GatewayTypeEnum.RC)
public TopicServicesResponse payloadControl(GatewayManager gateway, PayloadControlMethodEnum methodEnum, BaseModel request) {
- if (Objects.isNull(request) || request.getClass() != methodEnum.getClazz()) {
- throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER);
+ try {
+ AbstractControlService abstractControlService = SpringBeanUtils.getBean(this.getClass());
+ Method method = abstractControlService.getClass().getDeclaredMethod(
+ Common.convertSnake(methodEnum.getPayloadMethod().getMethod()),GatewayManager.class, methodEnum.getClazz());
+ return (TopicServicesResponse) method.invoke(abstractControlService, gateway, request);
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new CloudSDKException(e);
+ } catch (InvocationTargetException e) {
+ throw new CloudSDKException(e.getTargetException());
}
- Common.validateModel(request);
- return servicesPublish.publish(
- gateway.getGatewaySn(),
- methodEnum.getPayloadMethod().getMethod(),
- request);
}
diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/api/AbstractDebugService.java b/src/main/java/com/dji/sdk/cloudapi/debug/api/AbstractDebugService.java
index 1d3e6a1..08d3933 100644
--- a/src/main/java/com/dji/sdk/cloudapi/debug/api/AbstractDebugService.java
+++ b/src/main/java/com/dji/sdk/cloudapi/debug/api/AbstractDebugService.java
@@ -4,9 +4,9 @@ import com.dji.sdk.annotations.CloudSDKVersion;
import com.dji.sdk.cloudapi.debug.*;
import com.dji.sdk.common.BaseModel;
import com.dji.sdk.common.Common;
-import com.dji.sdk.common.GatewayManager;
-import com.dji.sdk.common.GatewayTypeEnum;
-import com.dji.sdk.exception.CloudSDKErrorEnum;
+import com.dji.sdk.common.SpringBeanUtils;
+import com.dji.sdk.config.version.GatewayManager;
+import com.dji.sdk.config.version.GatewayTypeEnum;
import com.dji.sdk.exception.CloudSDKException;
import com.dji.sdk.mqtt.ChannelName;
import com.dji.sdk.mqtt.MqttReply;
@@ -22,6 +22,10 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import javax.annotation.Resource;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
/**
@@ -242,7 +246,7 @@ public abstract class AbstractDebugService {
* @param gateway
* @return services_reply
*/
- @CloudSDKVersion(exclude = GatewayTypeEnum.RC)
+ @CloudSDKVersion(exclude = {GatewayTypeEnum.RC, GatewayTypeEnum.DOCK2})
public TopicServicesResponse> putterOpen(GatewayManager gateway) {
return servicesPublish.publish(
new TypeReference() {},
@@ -255,7 +259,7 @@ public abstract class AbstractDebugService {
* @param gateway
* @return services_reply
*/
- @CloudSDKVersion(exclude = GatewayTypeEnum.RC)
+ @CloudSDKVersion(exclude = {GatewayTypeEnum.RC, GatewayTypeEnum.DOCK2})
public TopicServicesResponse> putterClose(GatewayManager gateway) {
return servicesPublish.publish(
new TypeReference() {},
@@ -311,19 +315,24 @@ public abstract class AbstractDebugService {
* @param request data
* @return services_reply
*/
- @CloudSDKVersion(exclude = GatewayTypeEnum.RC)
public TopicServicesResponse> remoteDebug(GatewayManager gateway, DebugMethodEnum methodEnum, BaseModel request) {
- if (Objects.nonNull(methodEnum.getClazz())) {
- if (methodEnum.getClazz() != request.getClass()) {
- throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER);
+ try {
+ List clazz = new ArrayList<>();
+ List