diff --git a/pom.xml b/pom.xml index 9bc22a3..249aa19 100644 --- a/pom.xml +++ b/pom.xml @@ -1,85 +1,86 @@ - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.4.11 - - - - com.dji - cloud-api-sample - 1.5.0 - cloud-api-sample - - - 11 - 3.4.2 - 1.2.6 - 3.12.1 - 5.5.5 - 8.3.7 - 4.9.1 - 3.1.0 - 3.12.0 - 1.1.1 - 2.3.3 - 2.15.0 - 2.3.0 - - - - - org.springframework.boot - spring-boot-starter-web - - - - mysql - mysql-connector-java - - - - org.projectlombok - lombok - true - - - org.springframework.boot - spring-boot-starter-test - test - - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus.version} - - - - com.alibaba - druid-spring-boot-starter - ${druid.version} - - - - com.auth0 - java-jwt - ${jwt.version} - - - - org.springframework.integration - spring-integration-mqtt - ${mqtt.version} - - - - org.springframework.boot - spring-boot-starter-websocket - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.12 + + + + com.dji + cloud-api-sample + 1.7.0 + cloud-api-sample + + + 11 + 3.4.2 + 1.2.6 + 3.12.1 + 5.5.5 + 8.3.7 + 4.9.1 + 3.1.0 + 3.12.0 + 1.1.1 + 2.3.3 + 2.15.0 + 2.3.0 + + + + + org.springframework.boot + spring-boot-starter-web + + + + mysql + mysql-connector-java + 8.0.31 + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + com.auth0 + java-jwt + ${jwt.version} + + + + org.springframework.integration + spring-integration-mqtt + ${mqtt.version} + + + + org.springframework.boot + spring-boot-starter-websocket + org.jetbrains annotations @@ -87,115 +88,121 @@ compile - - io.minio - minio - ${minio.version} - - - - com.squareup.okhttp3 - okhttp - ${okhttp3.version} - - - - com.aliyun - aliyun-java-sdk-sts - ${aliyun-sdk-sts.version} - - - - com.aliyun.oss - aliyun-sdk-oss - ${aliyun-oss.version} - - - - javax.xml.bind - jaxb-api - - - javax.activation - activation - ${javax-activation.version} - - - - org.glassfish.jaxb - jaxb-runtime - ${glassfish-jaxb.version} - - - - org.springframework.boot - spring-boot-starter-data-redis - - - org.apache.commons - commons-pool2 - - - - com.amazonaws - aws-java-sdk-s3 - 1.12.261 - - - com.amazonaws - aws-java-sdk-sts - 1.12.261 - - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - - - - org.springframework.boot - spring-boot-starter-aop - - - - org.dom4j - dom4j - 2.1.3 - - - - jaxen - jaxen - - - - org.bouncycastle - bcpkix-jdk15on - 1.69 - - - - org.springframework.boot - spring-boot-starter-validation - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - - - - + + io.minio + minio + ${minio.version} + + + + com.squareup.okhttp3 + okhttp + ${okhttp3.version} + + + + com.aliyun + aliyun-java-sdk-sts + ${aliyun-sdk-sts.version} + + + + com.aliyun.oss + aliyun-sdk-oss + ${aliyun-oss.version} + + + + javax.xml.bind + jaxb-api + + + javax.activation + activation + ${javax-activation.version} + + + + org.glassfish.jaxb + jaxb-runtime + ${glassfish-jaxb.version} + + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.apache.commons + commons-pool2 + + + + com.amazonaws + aws-java-sdk-s3 + 1.12.261 + + + com.amazonaws + aws-java-sdk-sts + 1.12.261 + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + + org.springframework.boot + spring-boot-starter-aop + + + + org.dom4j + dom4j + 2.1.3 + + + + jaxen + jaxen + + + + org.bouncycastle + bcpkix-jdk15on + 1.69 + + + + org.springframework.boot + spring-boot-starter-validation + + + + + org.springdoc + springdoc-openapi-ui + 1.7.0 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + diff --git a/sql/cloud_sample.sql b/sql/cloud_sample.sql index ef864d9..18b9c78 100644 --- a/sql/cloud_sample.sql +++ b/sql/cloud_sample.sql @@ -21,7 +21,7 @@ CREATE TABLE `logs_file` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT, `file_id` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'uuid', `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The name of the file in the bucket.', - `size` int NOT NULL DEFAULT '0' COMMENT 'file size', + `size` bigint NOT NULL DEFAULT '0' COMMENT 'file size', `logs_id` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The logs_id in the manage_device_logs table.', `device_sn` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The sn of the device.', `fingerprint` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'file fingerprint', @@ -152,7 +152,7 @@ CREATE TABLE `manage_device_firmware` ( `file_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'undefined' COMMENT 'The file name of the firmware package, including the file suffix', `firmware_version` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'It needs to be formatted according to the official firmware version. 00.00.0000', `object_key` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'The object key of the firmware package in the bucket.', - `file_size` int NOT NULL COMMENT 'The size of the firmware package.', + `file_size` bigint NOT NULL COMMENT 'The size of the firmware package.', `file_md5` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The md5 of the firmware package.', `workspace_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `release_note` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The release note of the firmware package.', @@ -393,7 +393,7 @@ CREATE TABLE `media_file` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `file_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'uuid', `file_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The original name of the file.', - `file_path` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The path of the file.', + `file_path` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The path of the file.', `workspace_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The workspace to which the file belongs.', `fingerprint` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT 'The fingerprint of the file. This property exists only for media files uploaded by Pilot.', `tinny_fingerprint` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT 'The tiny fingerprint of the file. This property exists only for media files uploaded by Pilot.', diff --git a/src/main/java/com/dji/sample/CloudApiSampleApplication.java b/src/main/java/com/dji/sample/CloudApiSampleApplication.java index a3619ab..b36e909 100644 --- a/src/main/java/com/dji/sample/CloudApiSampleApplication.java +++ b/src/main/java/com/dji/sample/CloudApiSampleApplication.java @@ -3,12 +3,13 @@ package com.dji.sample; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableScheduling; @MapperScan("com.dji.sample.*.dao") @SpringBootApplication @EnableScheduling -//@EnableConfigurationProperties(OssConfiguration.class) +@ComponentScan("com.dji") public class CloudApiSampleApplication { public static void main(String[] args) { diff --git a/src/main/java/com/dji/sample/common/error/CommonErrorEnum.java b/src/main/java/com/dji/sample/common/error/CommonErrorEnum.java index 1ab3b32..73043a6 100644 --- a/src/main/java/com/dji/sample/common/error/CommonErrorEnum.java +++ b/src/main/java/com/dji/sample/common/error/CommonErrorEnum.java @@ -1,5 +1,7 @@ package com.dji.sample.common.error; +import com.dji.sdk.common.IErrorInfo; + /** * @author sean.zhou * @version 0.1 @@ -43,12 +45,13 @@ public enum CommonErrorEnum implements IErrorInfo { } @Override - public String getErrorMsg() { + public String getMessage() { return this.msg; } @Override - public Integer getErrorCode() { + public Integer getCode() { return this.code; } + } diff --git a/src/main/java/com/dji/sample/common/error/LiveErrorEnum.java b/src/main/java/com/dji/sample/common/error/LiveErrorEnum.java deleted file mode 100644 index 6ba3f95..0000000 --- a/src/main/java/com/dji/sample/common/error/LiveErrorEnum.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.dji.sample.common.error; - -/** - * Live streaming related error codes. When on-demand via mqtt, - * it can be matched with the error code information replied by the pilot. - * @author sean.zhou - * @version 0.1 - * @date 2021/11/25 - */ -public enum LiveErrorEnum implements IErrorInfo { - - NO_AIRCRAFT(613001, "No aircraft."), - - NO_CAMERA(613002, "No camera."), - - LIVE_STREAM_ALREADY_STARTED(613003, "The camera has started live streaming."), - - FUNCTION_NOT_SUPPORT(613004, "The function is not supported."), - - STRATEGY_NOT_SUPPORT(613005, "The strategy is not supported."), - - NOT_IN_CAMERA_INTERFACE(613006, "The current app is not in the camera interface."), - - NO_FLIGHT_CONTROL(613007, "The remote control has no flight control rights and cannot respond to control commands"), - - NO_STREAM_DATA(613008, "The current app has no stream data."), - - TOO_FREQUENT(613009, "The operation is too frequent."), - - ENABLE_FAILED(613010, "Please check whether the live stream service is normal."), - - NO_LIVE_STREAM(613011, "There are no live stream currently."), - - SWITCH_NOT_SUPPORT(613012, "There is already another camera in the live stream. It's not support to switch the stream directly."), - - URL_TYPE_NOT_SUPPORTED(613013, "This url type is not supported."), - - ERROR_PARAMETERS(613014, "The live stream parameters are abnormal or incomplete."), - - NO_REPLY(613098, "No live reply received."), - - UNKNOWN(613099, "UNKNOWN"); - - - private String msg; - - private int code; - - LiveErrorEnum(int code, String msg) { - this.code = code; - this.msg = msg; - } - - @Override - public String getErrorMsg() { - return this.msg; - } - - @Override - public Integer getErrorCode() { - return this.code; - } - - /** - * Get the corresponding enumeration object based on the error code. - * @param code error code - * @return enumeration object - */ - public static LiveErrorEnum find(int code) { - final int MOD = 100_000; - for (LiveErrorEnum errorEnum : LiveErrorEnum.class.getEnumConstants()) { - if (errorEnum.code % MOD == code % MOD) { - return errorEnum; - } - } - return UNKNOWN; - } -} diff --git a/src/main/java/com/dji/sample/common/model/Pagination.java b/src/main/java/com/dji/sample/common/model/Pagination.java deleted file mode 100644 index 74d1e8a..0000000 --- a/src/main/java/com/dji/sample/common/model/Pagination.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.dji.sample.common.model; - -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import lombok.Data; - -/** - * Used for paging display in the wayline. These field names cannot be changed. - * Because they need to be the same as the pilot. - * @author sean - * @version 0.3 - * @date 2021/12/22 - */ -@Data -public class Pagination { - - /** - * The current page number. - */ - private long page; - - /** - * The amount of data displayed per page. - */ - private long pageSize; - - /** - * The total amount of all data. - */ - private long total; - - public Pagination(Page page) { - this.page = page.getCurrent(); - this.pageSize = page.getSize(); - this.total = page.getTotal(); - } -} diff --git a/src/main/java/com/dji/sample/common/model/PaginationData.java b/src/main/java/com/dji/sample/common/model/PaginationData.java deleted file mode 100644 index 95e2442..0000000 --- a/src/main/java/com/dji/sample/common/model/PaginationData.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.dji.sample.common.model; - -import lombok.Data; - -import java.util.List; - -/** - * The format of the data response when a paginated display is required. - * @author sean - * @version 0.3 - * @date 2021/12/22 - */ -@Data -public class PaginationData { - - /** - * The collection in which the data list is stored. - */ - private List list; - - private Pagination pagination; - - public PaginationData(List list, Pagination pagination) { - this.list = list; - this.pagination = pagination; - } -} diff --git a/src/main/java/com/dji/sample/common/model/ResponseResult.java b/src/main/java/com/dji/sample/common/model/ResponseResult.java deleted file mode 100644 index 8ad8e1b..0000000 --- a/src/main/java/com/dji/sample/common/model/ResponseResult.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.dji.sample.common.model; - -import com.dji.sample.common.error.IErrorInfo; -import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.http.HttpStatus; - -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -@JsonInclude -public class ResponseResult { - - public static final int CODE_SUCCESS = 0; - public static final String MESSAGE_SUCCESS = "success"; - - private int code; - - private String message; - - private T data; - - public static ResponseResult success(T data) { - return ResponseResult.builder() - .code(CODE_SUCCESS) - .message(MESSAGE_SUCCESS) - .data(data) - .build(); - } - - public static ResponseResult success() { - return ResponseResult.builder() - .code(0) - .message(MESSAGE_SUCCESS) - .build(); - } - - public static ResponseResult error() { - return ResponseResult.builder() - .code(HttpStatus.INTERNAL_SERVER_ERROR.value()) - .message(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()) - .build(); - } - - public static ResponseResult error(String message) { - return ResponseResult.builder() - .code(HttpStatus.INTERNAL_SERVER_ERROR.value()) - .message(message) - .build(); - } - - public static ResponseResult error(int code, String message) { - return ResponseResult.builder() - .code(code) - .message(message) - .build(); - } - - public static ResponseResult error(IErrorInfo errorInfo) { - return ResponseResult.builder() - .code(errorInfo.getErrorCode()) - .message(errorInfo.getErrorMsg()) - .build(); - } -} diff --git a/src/main/java/com/dji/sample/common/util/JwtUtil.java b/src/main/java/com/dji/sample/common/util/JwtUtil.java index c04168e..d1e9c03 100644 --- a/src/main/java/com/dji/sample/common/util/JwtUtil.java +++ b/src/main/java/com/dji/sample/common/util/JwtUtil.java @@ -105,7 +105,7 @@ public class JwtUtil { } if (Objects.nonNull(age)) { - builder.withExpiresAt(new Date(now.getTime() + age * 1000)); + builder.withExpiresAt(new Date(now.getTime() + age)); } String token = builder diff --git a/src/main/java/com/dji/sample/common/util/SpringBeanUtilsTest.java b/src/main/java/com/dji/sample/common/util/SpringBeanUtilsTest.java new file mode 100644 index 0000000..cbe4ab1 --- /dev/null +++ b/src/main/java/com/dji/sample/common/util/SpringBeanUtilsTest.java @@ -0,0 +1,30 @@ +package com.dji.sample.common.util; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +@Component +public class SpringBeanUtilsTest implements ApplicationContextAware { + + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringBeanUtilsTest.applicationContext = applicationContext; + } + + public static T getBean(Class clazz) { + return applicationContext.getBean(clazz); + } + + public static Object getBean(String beanName) { + return applicationContext.getBean(beanName); + } +} diff --git a/src/main/java/com/dji/sample/component/ApplicationBootInitial.java b/src/main/java/com/dji/sample/component/ApplicationBootInitial.java index d99f58d..16a691c 100644 --- a/src/main/java/com/dji/sample/component/ApplicationBootInitial.java +++ b/src/main/java/com/dji/sample/component/ApplicationBootInitial.java @@ -2,11 +2,17 @@ package com.dji.sample.component; import com.dji.sample.component.redis.RedisConst; import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.service.IDeviceRedisService; import com.dji.sample.manage.service.IDeviceService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.common.SDKManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; +import java.util.Optional; + /** * @author sean.zhou * @date 2021/11/24 @@ -18,6 +24,9 @@ public class ApplicationBootInitial implements CommandLineRunner { @Autowired private IDeviceService deviceService; + @Autowired + private IDeviceRedisService deviceRedisService; + /** * Subscribe to the devices that exist in the redis when the program starts, * to prevent the data from being different from the pilot side due to program interruptions. @@ -29,7 +38,15 @@ public class ApplicationBootInitial implements CommandLineRunner { int start = RedisConst.DEVICE_ONLINE_PREFIX.length(); RedisOpsUtils.getAllKeys(RedisConst.DEVICE_ONLINE_PREFIX + "*") - .forEach(key -> deviceService.subscribeTopicOnline(key.substring(start))); + .stream() + .map(key -> key.substring(start)) + .map(deviceRedisService::getDeviceOnline) + .map(Optional::get) + .filter(device -> DeviceDomainEnum.DRONE != device.getDomain()) + .forEach(device -> deviceService.subDeviceOnlineSubscribeTopic( + SDKManager.registerDevice(device.getDeviceSn(), device.getChildDeviceSn(), device.getDomain(), + device.getType(), device.getSubType(), device.getThingVersion(), + deviceRedisService.getDeviceOnline(device.getChildDeviceSn()).map(DeviceDTO::getThingVersion).orElse(null)))); } } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/AuthInterceptor.java b/src/main/java/com/dji/sample/component/AuthInterceptor.java index 0d3b8f7..9933466 100644 --- a/src/main/java/com/dji/sample/component/AuthInterceptor.java +++ b/src/main/java/com/dji/sample/component/AuthInterceptor.java @@ -26,7 +26,7 @@ public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String uri = request.getRequestURI(); - log.debug("request uri: {}", uri); + log.debug("request uri: {}, IP: {}", uri, request.getRemoteAddr()); // The options method is passed directly. if (HttpMethod.OPTIONS.matches(request.getMethod())) { response.setStatus(HttpStatus.OK.value()); @@ -36,7 +36,7 @@ public class AuthInterceptor implements HandlerInterceptor { // Check if the token exists. if (!StringUtils.hasText(token)) { response.setStatus(HttpStatus.UNAUTHORIZED.value()); - log.error(CommonErrorEnum.NO_TOKEN.getErrorMsg()); + log.error(CommonErrorEnum.NO_TOKEN.getMessage()); return false; } diff --git a/src/main/java/com/dji/sample/component/GlobalExceptionHandler.java b/src/main/java/com/dji/sample/component/GlobalExceptionHandler.java index 0b6b6b0..f7e79c2 100644 --- a/src/main/java/com/dji/sample/component/GlobalExceptionHandler.java +++ b/src/main/java/com/dji/sample/component/GlobalExceptionHandler.java @@ -1,6 +1,6 @@ package com.dji.sample.component; -import com.dji.sample.common.model.ResponseResult; +import com.dji.sdk.common.HttpResultResponse; import org.springframework.validation.BindException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; @@ -22,21 +22,21 @@ public class GlobalExceptionHandler { * @return */ @ExceptionHandler(Exception.class) - public ResponseResult exceptionHandler(Exception e) { + public HttpResultResponse exceptionHandler(Exception e) { e.printStackTrace(); - return ResponseResult.error(e.getLocalizedMessage()); + return HttpResultResponse.error(e.getLocalizedMessage()); } @ExceptionHandler(NullPointerException.class) - public ResponseResult nullPointerExceptionHandler(NullPointerException e) { + public HttpResultResponse nullPointerExceptionHandler(NullPointerException e) { e.printStackTrace(); - return ResponseResult.error("A null object appeared."); + return HttpResultResponse.error("A null object appeared."); } @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class}) - public ResponseResult methodArgumentNotValidExceptionHandler(BindException e) { + public HttpResultResponse methodArgumentNotValidExceptionHandler(BindException e) { e.printStackTrace(); - return ResponseResult.error(e.getFieldError().getField() + e.getFieldError().getDefaultMessage()); + return HttpResultResponse.error(e.getFieldError().getField() + e.getFieldError().getDefaultMessage()); } } diff --git a/src/main/java/com/dji/sample/component/GlobalScheduleService.java b/src/main/java/com/dji/sample/component/GlobalScheduleService.java index 7e77a34..fe4dfd2 100644 --- a/src/main/java/com/dji/sample/component/GlobalScheduleService.java +++ b/src/main/java/com/dji/sample/component/GlobalScheduleService.java @@ -1,12 +1,11 @@ package com.dji.sample.component; -import com.dji.sample.component.mqtt.service.IMqttTopicService; import com.dji.sample.component.redis.RedisConst; import com.dji.sample.component.redis.RedisOpsUtils; import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.enums.DeviceDomainEnum; import com.dji.sample.manage.service.IDeviceService; -import com.dji.sample.wayline.service.IWaylineJobService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.mqtt.IMqttTopicService; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -31,8 +30,6 @@ public class GlobalScheduleService { @Autowired private IMqttTopicService topicService; - @Autowired - private IWaylineJobService waylineJobService; @Autowired private ObjectMapper mapper; /** @@ -46,14 +43,13 @@ public class GlobalScheduleService { long expire = RedisOpsUtils.getExpire(key); if (expire <= 30) { DeviceDTO device = (DeviceDTO) RedisOpsUtils.get(key); - if (DeviceDomainEnum.SUB_DEVICE.getVal() == device.getDomain()) { + if (null == device) { + return; + } + if (DeviceDomainEnum.DRONE == device.getDomain()) { deviceService.subDeviceOffline(key.substring(start)); } else { - deviceService.unsubscribeTopicOffline(key.substring(start)); - deviceService.pushDeviceOfflineTopo(device.getWorkspaceId(), device.getDeviceSn()); - RedisOpsUtils.hashDel(RedisConst.LIVE_CAPACITY, new String[]{device.getDeviceSn()}); - RedisOpsUtils.del(RedisConst.HMS_PREFIX + device.getDeviceSn()); - RedisOpsUtils.del(RedisConst.OSD_PREFIX + device.getDeviceSn()); + deviceService.gatewayOffline(key.substring(start)); } RedisOpsUtils.del(key); } diff --git a/src/main/java/com/dji/sample/component/mqtt/config/MqttMessageChannel.java b/src/main/java/com/dji/sample/component/mqtt/config/MqttMessageChannel.java index 8ff8629..aba87cb 100644 --- a/src/main/java/com/dji/sample/component/mqtt/config/MqttMessageChannel.java +++ b/src/main/java/com/dji/sample/component/mqtt/config/MqttMessageChannel.java @@ -1,6 +1,6 @@ package com.dji.sample.component.mqtt.config; -import com.dji.sample.component.mqtt.model.ChannelName; +import com.dji.sdk.mqtt.ChannelName; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -27,18 +27,13 @@ public class MqttMessageChannel { return new ExecutorChannel(threadPool); } - @Bean(name = ChannelName.INBOUND_STATUS) - public MessageChannel statusChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_STATUS_ONLINE) - public MessageChannel statusOnlineChannel() { + @Bean(name = ChannelName.DEFAULT) + public MessageChannel defaultChannel() { return new DirectChannel(); } - @Bean(name = ChannelName.INBOUND_STATUS_OFFLINE) - public MessageChannel statusOffChannel() { + @Bean(name = ChannelName.INBOUND_STATUS) + public MessageChannel statusChannel() { return new DirectChannel(); } @@ -47,158 +42,34 @@ public class MqttMessageChannel { return new DirectChannel(); } - @Bean(name = ChannelName.INBOUND_STATE_BASIC) - public MessageChannel stateBasicChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_STATE_PAYLOAD) - public MessageChannel statePayloadChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_SERVICE_REPLY) + @Bean(name = ChannelName.INBOUND_SERVICES_REPLY) public MessageChannel serviceReplyChannel() { return new DirectChannel(); } - @Bean(name = ChannelName.INBOUND_STATE_CAPACITY) - public MessageChannel stateCapacityChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_STATE_PAYLOAD_UPDATE) - public MessageChannel statePayloadUpdateChannel() { - return new DirectChannel(); - } - @Bean(name = ChannelName.INBOUND_OSD) public MessageChannel osdChannel() { return new ExecutorChannel(threadPool); } - @Bean(name = ChannelName.DEFAULT) - public MessageChannel defaultChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.OUTBOUND) - public MessageChannel outboundChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_STATE_FIRMWARE_VERSION) - public MessageChannel stateFirmwareVersionChannel() { - return new DirectChannel(); - } - @Bean(name = ChannelName.INBOUND_REQUESTS) public MessageChannel requestsChannel() { return new DirectChannel(); } - @Bean(name = ChannelName.INBOUND_REQUESTS_STORAGE_CONFIG_GET) - public MessageChannel requestsConfigGetChannel() { - return new DirectChannel(); - } - @Bean(name = ChannelName.INBOUND_EVENTS) public MessageChannel eventsChannel() { return new DirectChannel(); } - @Bean(name = ChannelName.OUTBOUND_EVENTS) - public MessageChannel eventsOutboundChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_EVENTS_FLIGHT_TASK_PROGRESS) - public MessageChannel eventsFlightTaskProgressChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_EVENTS_FILE_UPLOAD_CALLBACK) - public MessageChannel eventsFileUploadCallbackChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_REQUESTS_AIRPORT_BIND_STATUS) - public MessageChannel requestsAirportBindStatusChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET) - public MessageChannel requestsAirportOrganizationGetChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_BIND) - public MessageChannel requestsAirportOrganizationBindChannel() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_EVENTS_HMS) - public MessageChannel eventsHms() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS) - public MessageChannel eventsControlProgress() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_EVENTS_OTA_PROGRESS) - public MessageChannel eventsOtaProgress() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_EVENTS_FILE_UPLOAD_PROGRESS) - public MessageChannel eventsFileUploadProgress() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_REQUESTS_FLIGHT_TASK_RESOURCE_GET) - public MessageChannel requestsFlightTaskResourceGet() { - return new DirectChannel(); - } - @Bean(name = ChannelName.INBOUND_PROPERTY_SET_REPLY) public MessageChannel propertySetReply() { return new DirectChannel(); } - @Bean(name = ChannelName.INBOUND_REQUESTS_CONFIG) - public MessageChannel requestsConfig() { + @Bean(name = ChannelName.INBOUND_DRC_UP) + public MessageChannel drcUp() { return new DirectChannel(); } - @Bean(name = ChannelName.INBOUND_EVENTS_HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA) - public MessageChannel eventsHighestPriorityUploadFlightTaskMedia() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_EVENTS_FLIGHT_TASK_READY) - public MessageChannel eventsEventsFlightTaskReady() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_EVENTS_FLY_TO_POINT_PROGRESS) - public MessageChannel eventsFlyToPointProgress() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_EVENTS_TAKE_OFF_TO_POINT_PROGRESS) - public MessageChannel eventsTakeoffToPointProgress() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_EVENTS_DRC_STATUS_NOTIFY) - public MessageChannel eventsDrcStatusNotify() { - return new DirectChannel(); - } - - @Bean(name = ChannelName.INBOUND_EVENTS_DRC_MODE_EXIT_NOTIFY) - public MessageChannel eventsDrcModeExitNotify() { - return new DirectChannel(); - } } diff --git a/src/main/java/com/dji/sample/component/mqtt/config/MqttOutboundConfiguration.java b/src/main/java/com/dji/sample/component/mqtt/config/MqttOutboundConfiguration.java deleted file mode 100644 index a376093..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/config/MqttOutboundConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.dji.sample.component.mqtt.config; - -import com.dji.sample.component.mqtt.model.ChannelName; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.mqtt.core.MqttPahoClientFactory; -import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler; -import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter; -import org.springframework.messaging.MessageHandler; - -/** - * Client configuration for outbound messages. - * @author sean.zhou - * @date 2021/11/10 - * @version 0.1 - */ -@Configuration -public class MqttOutboundConfiguration { - - @Autowired - private MqttConfiguration mqttConfiguration; - - @Autowired - private MqttPahoClientFactory mqttClientFactory; - - /** - * Clients of outbound message channels. - * @return - */ - @Bean - @ServiceActivator(inputChannel = ChannelName.OUTBOUND) - public MessageHandler mqttOutbound() { - MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler( - MqttConfiguration.getBasicClientOptions().getClientId() + "_producer_" + System.currentTimeMillis(), - mqttClientFactory); - DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter(); - // use byte types uniformly - converter.setPayloadAsBytes(true); - - messageHandler.setAsync(true); - messageHandler.setDefaultQos(0); - messageHandler.setConverter(converter); - return messageHandler; - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/config/MqttConfiguration.java b/src/main/java/com/dji/sample/component/mqtt/config/MqttPropertyConfiguration.java similarity index 86% rename from src/main/java/com/dji/sample/component/mqtt/config/MqttConfiguration.java rename to src/main/java/com/dji/sample/component/mqtt/config/MqttPropertyConfiguration.java index ba8d939..2f7dd86 100644 --- a/src/main/java/com/dji/sample/component/mqtt/config/MqttConfiguration.java +++ b/src/main/java/com/dji/sample/component/mqtt/config/MqttPropertyConfiguration.java @@ -5,7 +5,7 @@ import com.dji.sample.common.util.JwtUtil; import com.dji.sample.component.mqtt.model.MqttClientOptions; import com.dji.sample.component.mqtt.model.MqttProtocolEnum; import com.dji.sample.component.mqtt.model.MqttUseEnum; -import com.dji.sample.control.model.dto.MqttBrokerDTO; +import com.dji.sdk.cloudapi.control.DrcModeMqttBroker; import lombok.Data; import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -26,12 +26,12 @@ import java.util.Map; @Configuration @Data @ConfigurationProperties -public class MqttConfiguration { +public class MqttPropertyConfiguration { private static Map mqtt; public void setMqtt(Map mqtt) { - MqttConfiguration.mqtt = mqtt; + MqttPropertyConfiguration.mqtt = mqtt; } /** @@ -79,7 +79,7 @@ public class MqttConfiguration { * @param map Custom data added in token. * @return */ - public static MqttBrokerDTO getMqttBrokerWithDrc(String clientId, String username, Long age, Map map) { + public static DrcModeMqttBroker getMqttBrokerWithDrc(String clientId, String username, Long age, Map map) { if (!mqtt.containsKey(MqttUseEnum.DRC)) { throw new RuntimeException("Please configure the drc link parameters of mqtt in the backend configuration file first."); } @@ -87,13 +87,13 @@ public class MqttConfiguration { String token = JwtUtil.createToken(map, age, algorithm, null, null); - return MqttBrokerDTO.builder() - .address(getMqttAddress(mqtt.get(MqttUseEnum.DRC))) - .username(username) - .clientId(clientId) - .expireTime(System.currentTimeMillis() / 1000 + age) - .password(token) - .build(); + return new DrcModeMqttBroker() + .setAddress(getMqttAddress(mqtt.get(MqttUseEnum.DRC))) + .setUsername(username) + .setClientId(clientId) + .setExpireTime(System.currentTimeMillis() / 1000 + age) + .setPassword(token) + .setEnableTls(false); } diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/AbstractStateTopicHandler.java b/src/main/java/com/dji/sample/component/mqtt/handler/AbstractStateTopicHandler.java deleted file mode 100644 index c3969f3..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/handler/AbstractStateTopicHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.dji.sample.component.mqtt.handler; - -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.component.redis.RedisOpsUtils; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Autowired; - -import java.util.Map; - -/** - * @author sean - * @version 0.3 - * @date 2022/2/21 - */ -public abstract class AbstractStateTopicHandler { - - protected AbstractStateTopicHandler handler; - - @Autowired - protected ObjectMapper mapper; - - @Autowired - protected RedisOpsUtils redisOps; - - protected AbstractStateTopicHandler(AbstractStateTopicHandler handler) { - this.handler = handler; - } - - /** - * Passing dataNode data, using different processing methods depending on the data selection. - * @param dataNode - * @param stateReceiver - * @param sn - * @return - * @throws JsonProcessingException - */ - public abstract CommonTopicReceiver handleState(Map dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException; -} diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/EventsRouter.java b/src/main/java/com/dji/sample/component/mqtt/handler/EventsRouter.java deleted file mode 100644 index 152ae81..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/handler/EventsRouter.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.dji.sample.component.mqtt.handler; - -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.IMessageSenderService; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.dsl.IntegrationFlow; -import org.springframework.integration.dsl.IntegrationFlows; -import org.springframework.integration.mqtt.support.MqttHeaders; -import org.springframework.messaging.MessageHeaders; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Optional; - -/** - * @author sean - * @version 1.1 - * @date 2022/6/1 - */ -@Configuration -public class EventsRouter { - - @Autowired - private ObjectMapper mapper; - - @Autowired - private IMessageSenderService messageSenderService; - - @Bean - public IntegrationFlow eventsMethodRouterFlow() { - return IntegrationFlows - .from(ChannelName.INBOUND_EVENTS) - .transform(payload -> { - try { - return mapper.readValue(payload, CommonTopicReceiver.class); - } catch (IOException e) { - e.printStackTrace(); - } - return new CommonTopicReceiver(); - }) - .route( - receiver -> EventsMethodEnum.find(receiver.getMethod()), - mapping -> Arrays.stream(EventsMethodEnum.values()).forEach( - methodEnum -> mapping.channelMapping(methodEnum, methodEnum.getChannelName()))) - .get(); - } - - @ServiceActivator(inputChannel = ChannelName.OUTBOUND_EVENTS, outputChannel = ChannelName.OUTBOUND) - public void replyEventsOutbound(CommonTopicReceiver receiver, MessageHeaders headers) { - if (Optional.ofNullable(receiver).map(CommonTopicReceiver::getNeedReply).flatMap(val -> Optional.of(1 != val)).orElse(true)) { - return; - } - messageSenderService.publish(headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF, - CommonTopicResponse.builder() - .tid(receiver.getTid()) - .bid(receiver.getBid()) - .method(receiver.getMethod()) - .timestamp(System.currentTimeMillis()) - .data(RequestsReply.success()) - .build()); - - } - -} diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/PropertySetReplyHandler.java b/src/main/java/com/dji/sample/component/mqtt/handler/PropertySetReplyHandler.java deleted file mode 100644 index 9b503eb..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/handler/PropertySetReplyHandler.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.dji.sample.component.mqtt.handler; - -import com.dji.sample.component.mqtt.model.Chan; -import com.dji.sample.component.mqtt.model.ChannelName; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.messaging.Message; -import org.springframework.stereotype.Component; - -import java.io.IOException; - -/** - * @author sean - * @version 1.2 - * @date 2022/9/9 - */ -@Component -public class PropertySetReplyHandler { - - @Autowired - private ObjectMapper mapper; - - /** - * Handle the reply message from the pilot side to the on-demand video. - * @param message reply message - * @throws IOException - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_PROPERTY_SET_REPLY) - public void serviceReply(Message message) throws IOException { - byte[] payload = (byte[])message.getPayload(); - - CommonTopicReceiver receiver = mapper.readValue(payload, new TypeReference() {}); - Chan> chan = Chan.getInstance(); - // Put the message to the chan object. - chan.put(receiver); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/RequestsRouter.java b/src/main/java/com/dji/sample/component/mqtt/handler/RequestsRouter.java deleted file mode 100644 index 95e0f7d..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/handler/RequestsRouter.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.dji.sample.component.mqtt.handler; - -import com.dji.sample.component.mqtt.model.ChannelName; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.component.mqtt.model.RequestsMethodEnum; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.integration.dsl.IntegrationFlow; -import org.springframework.integration.dsl.IntegrationFlows; - -import java.io.IOException; -import java.util.Arrays; - -/** - * @author sean - * @version 1.0 - * @date 2022/5/25 - */ -@Configuration -public class RequestsRouter { - - @Autowired - private ObjectMapper mapper; - - @Bean - public IntegrationFlow requestsMethodRouterFlow() { - return IntegrationFlows - .from(ChannelName.INBOUND_REQUESTS) - .transform(payload -> { - try { - return mapper.readValue(payload, CommonTopicReceiver.class); - } catch (IOException e) { - e.printStackTrace(); - } - return new CommonTopicReceiver(); - }) - .route( - receiver -> RequestsMethodEnum.find(receiver.getMethod()), - mapping -> Arrays.stream(RequestsMethodEnum.values()).forEach( - methodEnum -> mapping.channelMapping(methodEnum, methodEnum.getChannelName()))) - .get(); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/ServicesReplyHandler.java b/src/main/java/com/dji/sample/component/mqtt/handler/ServicesReplyHandler.java deleted file mode 100644 index 8d8030d..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/handler/ServicesReplyHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.dji.sample.component.mqtt.handler; - -import com.dji.sample.component.mqtt.model.Chan; -import com.dji.sample.component.mqtt.model.ChannelName; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.component.mqtt.model.ServiceReply; -import com.dji.sample.manage.model.enums.LogsFileMethodEnum; -import com.dji.sample.manage.model.receiver.LogsFileUploadList; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.messaging.Message; -import org.springframework.stereotype.Component; - -import java.io.IOException; - -/** - * @author sean - * @version 1.2 - * @date 2022/9/9 - */ -@Component -public class ServicesReplyHandler { - - @Autowired - private ObjectMapper mapper; - - /** - * Handle the reply message from the pilot side to the on-demand video. - * @param message reply message - * @throws IOException - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_SERVICE_REPLY) - public void serviceReply(Message message) throws IOException { - byte[] payload = (byte[])message.getPayload(); - - CommonTopicReceiver receiver = mapper.readValue(payload, new TypeReference() {}); - ServiceReply reply; - if (LogsFileMethodEnum.FILE_UPLOAD_LIST.getMethod().equals(receiver.getMethod())) { - LogsFileUploadList list = mapper.convertValue(receiver.getData(), new TypeReference() {}); - reply = new ServiceReply(); - reply.setResult(list.getResult()); - reply.setOutput(list.getFiles()); - } else { - reply = mapper.convertValue(receiver.getData(), new TypeReference() {}); - } - receiver.setData(reply); - Chan> chan = Chan.getInstance(); - // Put the message to the chan object. - chan.put(receiver); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/StateDefaultHandler.java b/src/main/java/com/dji/sample/component/mqtt/handler/StateDefaultHandler.java deleted file mode 100644 index a1d2624..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/handler/StateDefaultHandler.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.component.mqtt.handler; - -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.fasterxml.jackson.core.JsonProcessingException; -import org.springframework.stereotype.Service; - -import java.util.Map; - -/** - * @author sean - * @version 0.3 - * @date 2022/3/21 - */ -@Service -public class StateDefaultHandler extends AbstractStateTopicHandler { - - protected StateDefaultHandler() { - super(null); - } - - @Override - public CommonTopicReceiver handleState(Map dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException { - // If no suitable handler is found for the data, it is not processed. - return stateReceiver; - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/StateDeviceBasicHandler.java b/src/main/java/com/dji/sample/component/mqtt/handler/StateDeviceBasicHandler.java deleted file mode 100644 index b85ebca..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/handler/StateDeviceBasicHandler.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.dji.sample.component.mqtt.handler; - -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.component.mqtt.model.StateDataEnum; -import com.dji.sample.manage.model.receiver.DeviceBasicReceiver; -import com.fasterxml.jackson.core.JsonProcessingException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Service; - -import java.util.Map; - -/** - * @author sean - * @version 0.3 - * @date 2022/2/21 - */ -@Service -public class StateDeviceBasicHandler extends AbstractStateTopicHandler { - - public StateDeviceBasicHandler(@Autowired @Qualifier("stateLiveCapacityHandler") AbstractStateTopicHandler handler) { - super(handler); - } - - @Override - public CommonTopicReceiver handleState(Map dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException { - // handle device basic data - if (dataNode.containsKey(StateDataEnum.PAYLOADS.getDesc())) { - DeviceBasicReceiver data = mapper.convertValue(stateReceiver.getData(), DeviceBasicReceiver.class); - data.setDeviceSn(sn); - data.getPayloads().forEach(payload -> payload.setDeviceSn(sn)); - - stateReceiver.setData(data); - return stateReceiver; - } - return handler.handleState(dataNode, stateReceiver, sn); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/StateFirmwareVersionHandler.java b/src/main/java/com/dji/sample/component/mqtt/handler/StateFirmwareVersionHandler.java deleted file mode 100644 index aceeae4..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/handler/StateFirmwareVersionHandler.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.dji.sample.component.mqtt.handler; - -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.component.mqtt.model.StateDataEnum; -import com.dji.sample.manage.model.enums.DeviceDomainEnum; -import com.dji.sample.manage.model.enums.PayloadModelEnum; -import com.dji.sample.manage.model.receiver.FirmwareVersionReceiver; -import com.fasterxml.jackson.core.JsonProcessingException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Map; - -/** - * @author sean - * @version 0.3 - * @date 2022/2/21 - */ -@Service -public class StateFirmwareVersionHandler extends AbstractStateTopicHandler { - - protected StateFirmwareVersionHandler(@Autowired @Qualifier("stateDefaultHandler") AbstractStateTopicHandler handler) { - super(handler); - } - - @Override - public CommonTopicReceiver handleState(Map dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException { - // Parse the firmware version of the device. - if (dataNode.containsKey(StateDataEnum.FIRMWARE_VERSION.getDesc())) { - FirmwareVersionReceiver firmware = mapper.convertValue(dataNode, FirmwareVersionReceiver.class); - firmware.setSn(sn); - firmware.setDomain(DeviceDomainEnum.SUB_DEVICE); - stateReceiver.setData(firmware); - return stateReceiver; - } - - // Parse the firmware version of the payload. - List payloads = PayloadModelEnum.getAllModel(); - long count = dataNode.keySet() - .stream() - .map(key -> { - int end = key.indexOf("-"); - return end == -1 ? key : key.substring(0, end); - }) - .filter(payloads::contains) - .count(); - if (count > 0) { - FirmwareVersionReceiver firmware = FirmwareVersionReceiver.builder() - .firmwareVersion(((Map)(dataNode.values().iterator().next())) - .get(StateDataEnum.FIRMWARE_VERSION.getDesc())) - .sn(sn) - .domain(DeviceDomainEnum.PAYLOAD) - .build(); - stateReceiver.setData(firmware); - return stateReceiver; - } - - return handler.handleState(dataNode, stateReceiver, sn); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/StateLiveCapacityHandler.java b/src/main/java/com/dji/sample/component/mqtt/handler/StateLiveCapacityHandler.java deleted file mode 100644 index dc593ab..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/handler/StateLiveCapacityHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.dji.sample.component.mqtt.handler; - -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.component.mqtt.model.StateDataEnum; -import com.dji.sample.manage.model.receiver.LiveCapacityReceiver; -import com.fasterxml.jackson.core.JsonProcessingException; -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.util.Map; - -/** - * @author sean - * @version 0.3 - * @date 2022/2/21 - */ -@Service -@Slf4j -public class StateLiveCapacityHandler extends AbstractStateTopicHandler { - - protected StateLiveCapacityHandler(@Autowired @Qualifier("stateFirmwareVersionHandler") AbstractStateTopicHandler handler) { - super(handler); - } - - @Override - public CommonTopicReceiver handleState(Map dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException { - // Determine if it is live capacity data based on name. - if (dataNode.containsKey(StateDataEnum.LIVE_CAPACITY.getDesc())) { - stateReceiver.setData(mapper.convertValue( - dataNode.get(StateDataEnum.LIVE_CAPACITY.getDesc()), - LiveCapacityReceiver.class)); - log.info("Analyze live stream capabilities."); - return stateReceiver; - } - return handler.handleState(dataNode, stateReceiver, sn); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/StateRouter.java b/src/main/java/com/dji/sample/component/mqtt/handler/StateRouter.java deleted file mode 100644 index 4f0e1e5..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/handler/StateRouter.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.dji.sample.component.mqtt.handler; - -import com.dji.sample.component.mqtt.model.ChannelName; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.manage.model.receiver.DeviceBasicReceiver; -import com.dji.sample.manage.model.receiver.FirmwareVersionReceiver; -import com.dji.sample.manage.model.receiver.LiveCapacityReceiver; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.integration.annotation.MessageEndpoint; -import org.springframework.integration.annotation.Router; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.annotation.Splitter; -import org.springframework.integration.mqtt.support.MqttHeaders; -import org.springframework.integration.router.MessageRouter; -import org.springframework.integration.router.PayloadTypeRouter; -import org.springframework.messaging.Message; - -import javax.annotation.Resource; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; - -import static com.dji.sample.component.mqtt.model.TopicConst.*; - -/** - * - * @author sean.zhou - * @date 2021/11/17 - * @version 0.1 - */ -@MessageEndpoint -@Slf4j -@Configuration -public class StateRouter { - - @Resource(name = "stateDeviceBasicHandler") - private AbstractStateTopicHandler handler; - - @Autowired - private ObjectMapper mapper; - - /** - * Handles the routing of state topic messages. Depending on the data, it is assigned to different channels for handling. - * @param message - * @return - * @throws IOException - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE, outputChannel = ChannelName.INBOUND_STATE_SPLITTER) - public CommonTopicReceiver resolveStateData(Message message) throws IOException { - byte[] payload = (byte[])message.getPayload(); - String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC).toString(); - - CommonTopicReceiver stateReceiver = mapper.readValue(payload, CommonTopicReceiver.class); - // Get the sn of the topic source. - String from = topic.substring((THING_MODEL_PRE + PRODUCT).length(), - topic.indexOf(STATE_SUF)); - - try { - Map data = (Map) (stateReceiver.getData()); - - return handler.handleState(data, stateReceiver, from); - - } catch (UnrecognizedPropertyException e) { - log.info("The {} data is not processed.", e.getPropertyName()); - } - return stateReceiver; - } - - /** - * Split the state message data to different channels for handling according to their different types. - * @param receiver state message - * @return - */ - @Splitter(inputChannel = ChannelName.INBOUND_STATE_SPLITTER, outputChannel = ChannelName.INBOUND_STATE_ROUTER) - public Collection splitState(CommonTopicReceiver receiver) { - ArrayList type = new ArrayList<>(); - type.add(receiver.getData()); - return type; - } - - @Bean - @Router(inputChannel = ChannelName.INBOUND_STATE_ROUTER) - public MessageRouter resolveStateRouter() { - PayloadTypeRouter router = new PayloadTypeRouter(); - // Channel mapping for basic data. - router.setChannelMapping(DeviceBasicReceiver.class.getName(), - ChannelName.INBOUND_STATE_BASIC); - // Channel mapping for live streaming capabilities. - router.setChannelMapping(LiveCapacityReceiver.class.getName(), - ChannelName.INBOUND_STATE_CAPACITY); - router.setChannelMapping(FirmwareVersionReceiver.class.getName(), - ChannelName.INBOUND_STATE_FIRMWARE_VERSION); - router.setChannelMapping(Map.class.getName(), - ChannelName.DEFAULT); - return router; - } - -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/StatusRouter.java b/src/main/java/com/dji/sample/component/mqtt/handler/StatusRouter.java deleted file mode 100644 index 0b34137..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/handler/StatusRouter.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.dji.sample.component.mqtt.handler; - -import com.dji.sample.component.mqtt.model.ChannelName; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.manage.model.receiver.StatusGatewayReceiver; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.MessageEndpoint; -import org.springframework.integration.annotation.Router; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.mqtt.support.MqttHeaders; -import org.springframework.messaging.Message; -import org.springframework.util.CollectionUtils; - -import static com.dji.sample.component.mqtt.model.TopicConst.*; - -/** - * - * @author sean.zhou - * @date 2021/11/12 - * @version 0.1 - */ -@MessageEndpoint -public class StatusRouter { - - @Autowired - private ObjectMapper mapper; - - /** - * Converts the status data sent by the gateway device into an object. - * @param message - * @return - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_STATUS, outputChannel = ChannelName.INBOUND_STATUS_ROUTER) - public CommonTopicReceiver resolveStatus(Message message) { - CommonTopicReceiver statusReceiver = new CommonTopicReceiver<>(); - try { - statusReceiver = mapper.readValue( - (byte[])message.getPayload(), - new TypeReference>() {}); - - String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC).toString(); - - // set gateway's sn - statusReceiver.getData().setSn( - topic.substring((BASIC_PRE + PRODUCT).length(), - topic.indexOf(STATUS_SUF))); - } catch (Exception e) { - e.printStackTrace(); - } - return statusReceiver; - } - - /** - * Handles the routing of status topic messages. Depending on the data, it is assigned to different channels for handling. - * @param receiver - * @return - */ - @Router(inputChannel = ChannelName.INBOUND_STATUS_ROUTER) - public String resolveStatusRouter(CommonTopicReceiver receiver) { - // Determine whether the drone is online or offline according to whether the data of the sub-device is empty. - return CollectionUtils.isEmpty(receiver.getData().getSubDevices()) ? - ChannelName.INBOUND_STATUS_OFFLINE : ChannelName.INBOUND_STATUS_ONLINE; - } - -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/mqtt/model/Chan.java b/src/main/java/com/dji/sample/component/mqtt/model/Chan.java deleted file mode 100644 index f55212a..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/Chan.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import java.util.concurrent.locks.LockSupport; - -/** - * The demo is only for functional closure, which is not recommended. - * @author sean.zhou - * @date 2021/11/22 - * @version 0.1 - */ -public class Chan { - - private static final long THREAD_WAIT_TIME = 1000_000L * 10_000; - - private volatile T data; - - private volatile Thread t; - - private Chan () { - - } - - public static Chan getInstance() { - return ChanSingleton.INSTANCE; - } - - public T get(Object blocker) { - this.t = Thread.currentThread(); - LockSupport.parkNanos(blocker, THREAD_WAIT_TIME); - this.t = null; - return data; - } - - public void put(T data) { - this.data = data; - if (t == null) { - return; - } - LockSupport.unpark(t); - } - - private static class ChanSingleton { - private static final Chan INSTANCE = new Chan<>(); - } -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/mqtt/model/ChannelName.java b/src/main/java/com/dji/sample/component/mqtt/model/ChannelName.java deleted file mode 100644 index cf0ef71..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/ChannelName.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -/** - * The name of all channels. - * - * @author sean.zhou - * @date 2021/11/10 - * @version 0.1 - */ -public class ChannelName { - - public static final String INBOUND = "inbound"; - - public static final String INBOUND_STATUS = "inboundStatus"; - - public static final String INBOUND_STATUS_ROUTER = "inboundStatusRouter"; - - public static final String INBOUND_STATUS_ONLINE = "inboundStatusOnline"; - - public static final String INBOUND_STATUS_OFFLINE = "inboundStatusOffline"; - - public static final String INBOUND_STATE = "inboundState"; - - public static final String INBOUND_STATE_SPLITTER = "inboundStateSplitter"; - - public static final String INBOUND_STATE_ROUTER = "inboundStateRouter"; - - public static final String INBOUND_STATE_BASIC = "inboundStateBasic"; - - public static final String INBOUND_STATE_PAYLOAD = "inboundStatePayload"; - - public static final String INBOUND_STATE_PAYLOAD_UPDATE = "inboundStatePayloadUpdate"; - - public static final String INBOUND_STATE_CAPACITY = "inboundStateCapacity"; - - public static final String INBOUND_STATE_LIST = "inboundStateList"; - - public static final String INBOUND_SERVICE_REPLY = "inboundStateServiceReply"; - - public static final String INBOUND_OSD = "inboundOsd"; - - public static final String DEFAULT = "default"; - - public static final String OUTBOUND = "outbound"; - - public static final String INBOUND_STATE_FIRMWARE_VERSION = "inboundStateFirmwareVersion"; - - public static final String INBOUND_REQUESTS = "inboundRequests"; - - public static final String INBOUND_REQUESTS_STORAGE_CONFIG_GET = "inboundRequestsConfigGet"; - - public static final String INBOUND_EVENTS = "inboundEvents"; - - public static final String OUTBOUND_EVENTS = "outboundEvents"; - - public static final String INBOUND_EVENTS_FLIGHT_TASK_PROGRESS = "inboundEventsFlightTaskProgress"; - - public static final String INBOUND_EVENTS_FILE_UPLOAD_CALLBACK = "inboundEventsFileUploadCallback"; - - public static final String INBOUND_REQUESTS_AIRPORT_BIND_STATUS = "inboundRequestsAirportBindStatus"; - - public static final String INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET = "inboundRequestsAirportOrganizationGet"; - - public static final String INBOUND_REQUESTS_AIRPORT_ORGANIZATION_BIND = "inboundRequestsAirportOrganizationBind"; - - public static final String INBOUND_EVENTS_HMS = "inboundEventsHms"; - - public static final String INBOUND_EVENTS_CONTROL_PROGRESS = "inboundEventsControlProgress"; - - public static final String INBOUND_EVENTS_OTA_PROGRESS = "inboundEventsOtaProgress"; - - public static final String INBOUND_EVENTS_FILE_UPLOAD_PROGRESS = "inboundEventsFileUploadProgress"; - - public static final String INBOUND_REQUESTS_FLIGHT_TASK_RESOURCE_GET = "inboundEventsFlightTaskResourceGet"; - - public static final String INBOUND_PROPERTY_SET_REPLY = "inboundPropertySetReply"; - - public static final String INBOUND_REQUESTS_CONFIG = "inboundRequestsConfig"; - - public static final String INBOUND_EVENTS_HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA = "inboundEventsHighestPriorityUploadFlightTaskMedia"; - - public static final String INBOUND_EVENTS_FLIGHT_TASK_READY = "inboundEventsFlightTaskReady"; - - public static final String INBOUND_EVENTS_FLY_TO_POINT_PROGRESS = "inboundFlyToPointProgress"; - - public static final String INBOUND_EVENTS_TAKE_OFF_TO_POINT_PROGRESS = "inboundTakeoffToPointProgress"; - - public static final String INBOUND_EVENTS_DRC_STATUS_NOTIFY = "inboundDrcStatusNotify"; - - public static final String INBOUND_EVENTS_DRC_MODE_EXIT_NOTIFY = "inboundDrcModeExitNotify"; -} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/CommonTopicReceiver.java b/src/main/java/com/dji/sample/component/mqtt/model/CommonTopicReceiver.java deleted file mode 100644 index 6090338..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/CommonTopicReceiver.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Data; - -/** - * Unified topic receiving format. - * @author sean.zhou - * @date 2021/11/10 - * @version 0.1 - */ -@Data -@JsonIgnoreProperties(ignoreUnknown = true) -public class CommonTopicReceiver { - - /** - * The command is sent and the response is matched by the tid and bid fields in the message, - * and the reply should keep the tid and bid the same. - */ - private String tid; - - private String bid; - - private String method; - - private Long timestamp; - - private T data; - - private String gateway; - - private Integer needReply; - -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/mqtt/model/CommonTopicResponse.java b/src/main/java/com/dji/sample/component/mqtt/model/CommonTopicResponse.java deleted file mode 100644 index e8055c0..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/CommonTopicResponse.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Unified Topic response format - * @author sean.zhou - * @date 2021/11/15 - * @version 0.1 - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -@JsonIgnoreProperties(ignoreUnknown = true) -public class CommonTopicResponse { - - /** - * The command is sent and the response is matched by the tid and bid fields in the message, - * and the reply should keep the tid and bid the same. - */ - private String tid; - - private String bid; - - private String method; - - private T data; - - private Long timestamp; -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/mqtt/model/ConfigScopeEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/ConfigScopeEnum.java deleted file mode 100644 index 7cd4479..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/ConfigScopeEnum.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import com.dji.sample.manage.service.IRequestsConfigService; -import com.dji.sample.manage.service.impl.ConfigProductServiceImpl; -import lombok.Getter; - -import java.util.Arrays; -import java.util.Optional; - -/** - * @author sean - * @version 1.3 - * @date 2022/11/10 - */ -@Getter -public enum ConfigScopeEnum { - - PRODUCT("product", ConfigProductServiceImpl.class); - - String scope; - - Class clazz; - - ConfigScopeEnum(String scope, Class clazz) { - this.scope = scope; - this.clazz = clazz; - } - - public static Optional find(String scope) { - return Arrays.stream(ConfigScopeEnum.values()).filter(scopeEnum -> scopeEnum.scope.equals(scope)).findAny(); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/ErrorInfoReply.java b/src/main/java/com/dji/sample/component/mqtt/model/ErrorInfoReply.java deleted file mode 100644 index 160a86e..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/ErrorInfoReply.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import com.dji.sample.common.model.ResponseResult; -import lombok.AllArgsConstructor; -import lombok.Data; - -/** - * @author sean - * @version 1.1 - * @date 2022/6/14 - */ -@Data -@AllArgsConstructor -public class ErrorInfoReply { - - private String sn; - - private Integer errCode; - - public static ErrorInfoReply success(String sn) { - return new ErrorInfoReply(sn, ResponseResult.CODE_SUCCESS); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/EventsMethodEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/EventsMethodEnum.java deleted file mode 100644 index 37205bc..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/EventsMethodEnum.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import java.util.Arrays; - -/** - * @author sean - * @version 1.1 - * @date 2022/6/1 - */ -public enum EventsMethodEnum { - - FLIGHT_TASK_PROGRESS("flighttask_progress", ChannelName.INBOUND_EVENTS_FLIGHT_TASK_PROGRESS), - - FILE_UPLOAD_CALLBACK("file_upload_callback", ChannelName.INBOUND_EVENTS_FILE_UPLOAD_CALLBACK), - - HMS("hms", ChannelName.INBOUND_EVENTS_HMS), - - DEVICE_REBOOT("device_reboot", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - DRONE_OPEN("drone_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - DRONE_CLOSE("drone_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - DEVICE_CHECK("device_check", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - DRONE_FORMAT("drone_format", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - DEVICE_FORMAT("device_format", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - COVER_OPEN("cover_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - COVER_CLOSE("cover_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - PUTTER_OPEN("putter_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - PUTTER_CLOSE("putter_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - CHARGE_OPEN("charge_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - CHARGE_CLOSE("charge_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS), - - OTA_PROGRESS("ota_progress", ChannelName.INBOUND_EVENTS_OTA_PROGRESS), - - FILE_UPLOAD_PROGRESS("fileupload_progress", ChannelName.INBOUND_EVENTS_FILE_UPLOAD_PROGRESS), - - HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA("highest_priority_upload_flighttask_media", ChannelName.INBOUND_EVENTS_HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA), - - FLIGHT_TASK_READY("flighttask_ready", ChannelName.INBOUND_EVENTS_FLIGHT_TASK_READY), - - FLY_TO_POINT_PROGRESS("fly_to_point_progress", ChannelName.INBOUND_EVENTS_FLY_TO_POINT_PROGRESS), - - TAKE_OFF_TO_POINT_PROGRESS("takeoff_to_point_progress", ChannelName.INBOUND_EVENTS_TAKE_OFF_TO_POINT_PROGRESS), - - DRC_STATUS_NOTIFY("drc_status_notify", ChannelName.INBOUND_EVENTS_DRC_STATUS_NOTIFY), - - JOYSTICK_INVALID_NOTIFY("joystick_invalid_notify", ChannelName.INBOUND_EVENTS_DRC_MODE_EXIT_NOTIFY), - - UNKNOWN("Unknown", ChannelName.DEFAULT); - - private String method; - - private String channelName; - - EventsMethodEnum(String method, String channelName) { - this.method = method; - this.channelName = channelName; - } - - public String getMethod() { - return method; - } - - public String getChannelName() { - return channelName; - } - - public static EventsMethodEnum find(String method) { - return Arrays.stream(EventsMethodEnum.values()) - .filter(methodEnum -> methodEnum.method.equals(method)) - .findAny() - .orElse(UNKNOWN); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/EventsOutputProgressReceiver.java b/src/main/java/com/dji/sample/component/mqtt/model/EventsOutputProgressReceiver.java deleted file mode 100644 index 499d85a..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/EventsOutputProgressReceiver.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import lombok.Data; - -/** - * @author sean - * @version 1.2 - * @date 2022/7/29 - */ -@Data -public class EventsOutputProgressReceiver { - - private String status; - - private OutputProgressReceiver progress; - - private T ext; -} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/EventsReceiver.java b/src/main/java/com/dji/sample/component/mqtt/model/EventsReceiver.java index 1597e21..f24f6af 100644 --- a/src/main/java/com/dji/sample/component/mqtt/model/EventsReceiver.java +++ b/src/main/java/com/dji/sample/component/mqtt/model/EventsReceiver.java @@ -1,29 +1,64 @@ package com.dji.sample.component.mqtt.model; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.EventsErrorCode; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; +import lombok.*; /** * @author sean * @version 1.1 * @date 2022/6/9 */ +@EqualsAndHashCode(callSuper = true) @Data @JsonIgnoreProperties(ignoreUnknown = true) @Builder @NoArgsConstructor @AllArgsConstructor -public class EventsReceiver { - - private Integer result; - - private T output; +public class EventsReceiver extends EventsDataRequest { private String bid; private String sn; + @Override + public EventsErrorCode getResult() { + return super.getResult(); + } + + @Override + public EventsReceiver setResult(EventsErrorCode result) { + super.setResult(result); + return this; + } + + @Override + public T getOutput() { + return super.getOutput(); + } + + @Override + public EventsReceiver setOutput(T output) { + super.setOutput(output); + return this; + } + + public String getBid() { + return bid; + } + + public EventsReceiver setBid(String bid) { + this.bid = bid; + return this; + } + + public String getSn() { + return sn; + } + + public EventsReceiver setSn(String sn) { + this.sn = sn; + return this; + } } diff --git a/src/main/java/com/dji/sample/component/mqtt/model/EventsResultStatusEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/EventsResultStatusEnum.java deleted file mode 100644 index dd37ac6..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/EventsResultStatusEnum.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import lombok.Getter; - -import java.util.Arrays; - -/** - * @author sean - * @version 1.2 - * @date 2022/8/17 - */ -@Getter -public enum EventsResultStatusEnum { - - SENT("sent", false), - - IN_PROGRESS("in_progress", false), - - OK("ok", true), - - PAUSED("paused", false), - - REJECTED("rejected", true), - - FAILED("failed", true), - - CANCELED("canceled", true), - - TIMEOUT("timeout", true), - - PARTIALLY_DONE("partially_done", true), - - UNKNOWN("unknown", false); - - String desc; - - Boolean end; - - EventsResultStatusEnum(String desc, Boolean end) { - this.desc = desc; - this.end = end; - } - - public static EventsResultStatusEnum find(String desc) { - return Arrays.stream(EventsResultStatusEnum.values()) - .filter(status -> status.desc.equals(desc)) - .findFirst().orElse(UNKNOWN); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/MapKeyConst.java b/src/main/java/com/dji/sample/component/mqtt/model/MapKeyConst.java index 0e4f498..632152e 100644 --- a/src/main/java/com/dji/sample/component/mqtt/model/MapKeyConst.java +++ b/src/main/java/com/dji/sample/component/mqtt/model/MapKeyConst.java @@ -11,28 +11,6 @@ public final class MapKeyConst { } - public static final String ORGANIZATION_NAME = "organization_name"; - - public static final String DEVICES = "devices"; - - public static final String SN = "sn"; - - public static final String BIND_DEVICES = "bind_devices"; - - public static final String ERR_INFOS = "err_infos"; - - public static final String TINY_FINGERPRINTS = "tiny_fingerprints"; - - public static final String BIND_STATUS = "bind_status"; - - public static final String LIST = "list"; - - public static final String MODULE_LIST = "module_list"; - - public static final String FLIGHT_ID = "flight_id"; - - public static final String FLIGHT_IDS = "flight_ids"; - public static final String ACL = "acl"; } diff --git a/src/main/java/com/dji/sample/component/mqtt/model/MqttProtocolEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/MqttProtocolEnum.java index ac54b1f..49bce90 100644 --- a/src/main/java/com/dji/sample/component/mqtt/model/MqttProtocolEnum.java +++ b/src/main/java/com/dji/sample/component/mqtt/model/MqttProtocolEnum.java @@ -12,7 +12,7 @@ public enum MqttProtocolEnum { MQTT("tcp"), - MQTTS("tcp"), + MQTTS("ssl"), WS("ws"), diff --git a/src/main/java/com/dji/sample/component/mqtt/model/OutputProgressReceiver.java b/src/main/java/com/dji/sample/component/mqtt/model/OutputProgressReceiver.java deleted file mode 100644 index 33e9db1..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/OutputProgressReceiver.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import lombok.Data; - -/** - * @author sean - * @version 1.2 - * @date 2022/7/29 - */ -@Data -public class OutputProgressReceiver { - - private Integer percent; - - private String stepKey; - - private Integer stepResult; -} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/RequestsMethodEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/RequestsMethodEnum.java deleted file mode 100644 index 8d04ceb..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/RequestsMethodEnum.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import lombok.Getter; - -import java.util.Arrays; - -/** - * @author sean - * @version 1.0 - * @date 2022/5/25 - */ -@Getter -public enum RequestsMethodEnum { - - STORAGE_CONFIG_GET("storage_config_get", ChannelName.INBOUND_REQUESTS_STORAGE_CONFIG_GET), - - AIRPORT_BIND_STATUS("airport_bind_status", ChannelName.INBOUND_REQUESTS_AIRPORT_BIND_STATUS), - - AIRPORT_ORGANIZATION_BIND("airport_organization_bind", ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_BIND), - - AIRPORT_ORGANIZATION_GET("airport_organization_get", ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET), - - FLIGHT_TASK_RESOURCE_GET("flighttask_resource_get", ChannelName.INBOUND_REQUESTS_FLIGHT_TASK_RESOURCE_GET), - - CONFIG("config", ChannelName.INBOUND_REQUESTS_CONFIG), - - UNKNOWN("Unknown", ChannelName.DEFAULT); - - private String method; - - private String channelName; - - RequestsMethodEnum(String method, String channelName) { - this.method = method; - this.channelName = channelName; - } - - public static RequestsMethodEnum find(String method) { - return Arrays.stream(RequestsMethodEnum.values()) - .filter(methodEnum -> methodEnum.method.equals(method)) - .findAny() - .orElse(UNKNOWN); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/RequestsReply.java b/src/main/java/com/dji/sample/component/mqtt/model/RequestsReply.java deleted file mode 100644 index e788466..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/RequestsReply.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import com.dji.sample.common.error.IErrorInfo; -import com.dji.sample.common.model.ResponseResult; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 1.1 - * @date 2022/6/13 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class RequestsReply { - - private Integer result; - - private T output; - - - public static RequestsReply error(IErrorInfo errorInfo) { - return RequestsReply.builder() - .result(errorInfo.getErrorCode()) - .output(errorInfo.getErrorMsg()) - .build(); - } - - public static RequestsReply success(T data) { - return RequestsReply.builder() - .result(ResponseResult.CODE_SUCCESS) - .output(data) - .build(); - } - public static RequestsReply success() { - return RequestsReply.builder() - .result(ResponseResult.CODE_SUCCESS) - .build(); - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/ServiceReply.java b/src/main/java/com/dji/sample/component/mqtt/model/ServiceReply.java deleted file mode 100644 index d0b1562..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/ServiceReply.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Data; - -/** - * @author sean.zhou - * @version 0.1 - * @date 2021/11/22 - */ -@Data -@JsonIgnoreProperties(ignoreUnknown = true) -public class ServiceReply { - - private Integer result; - - private T info; - - private T output; -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/mqtt/model/SetReply.java b/src/main/java/com/dji/sample/component/mqtt/model/SetReply.java deleted file mode 100644 index 2c7f453..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/SetReply.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import lombok.Data; - -/** - * @author sean - * @version 1.3 - * @date 2022/10/28 - */ -@Data -public class SetReply { - - private Integer result; -} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/SetReplyStatusResultEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/SetReplyStatusResultEnum.java deleted file mode 100644 index 5a127e4..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/SetReplyStatusResultEnum.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -import lombok.Getter; - -/** - * @author sean - * @version 1.3 - * @date 2022/10/28 - */ -@Getter -public enum SetReplyStatusResultEnum { - - SUCCESS(0, "success"), - - FAILED(1, "failed"), - - TIMEOUT(2, "timeout"), - - UNKNOWN(-1, "unknown"); - - int val; - - String desc; - - SetReplyStatusResultEnum(int val, String desc) { - this.val = val; - this.desc = desc; - } - -} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/StateDataEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/StateDataEnum.java deleted file mode 100644 index 82bed19..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/model/StateDataEnum.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.component.mqtt.model; - -/** - * - * @author sean.zhou - * @date 2021/11/18 - * @version 0.1 - */ -public enum StateDataEnum { - - FIRMWARE_VERSION("firmware_version"), - - LIVE_CAPACITY("live_capacity"), - - PAYLOADS("payloads"); - - private String desc; - - StateDataEnum(String desc) { - this.desc = desc; - } - - public String getDesc() { - return this.desc; - } -} diff --git a/src/main/java/com/dji/sample/component/mqtt/service/IMessageSenderService.java b/src/main/java/com/dji/sample/component/mqtt/service/IMessageSenderService.java deleted file mode 100644 index e21816c..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/service/IMessageSenderService.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.dji.sample.component.mqtt.service; - -import com.dji.sample.component.mqtt.model.CommonTopicResponse; -import com.dji.sample.component.mqtt.model.ServiceReply; -import com.fasterxml.jackson.core.type.TypeReference; - -/** - * @author sean.zhou - * @version 0.1 - * @date 2021/11/25 - */ -public interface IMessageSenderService { - - /** - * Publish a message to a specific topic. - * @param topic target - * @param response message - */ - void publish(String topic, CommonTopicResponse response); - - /** - * Use a specific qos to push messages to a specific topic. - * @param topic target - * @param qos qos - * @param response message - */ - void publish(String topic, int qos, CommonTopicResponse response); - - /** - * Send message and receive a response at the same time. - * @param clazz - * @param topic - * @param response notification of whether the start is successful. - * @return - */ - T publishWithReply(Class clazz, String topic, CommonTopicResponse response); - - /** - * Send message and receive a response at the same time. - * @param clazz - * @param topic - * @param response - * @param retryTime - * @param - * @return - */ - T publishWithReply(Class clazz, String topic, CommonTopicResponse response, int retryTime); - - /** - * Used exclusively for sending messages for services. - * @param clazz The generic class for ServiceReply. - * @param sn - * @param method - * @param data - * @param bid - * @param - * @return - */ - ServiceReply publishServicesTopic(TypeReference clazz, String sn, String method, Object data, String bid); - - /** - * Used exclusively for sending messages for services, and does not set the received subtype. - * @param sn - * @param method - * @param data - * @param bid - * @return - */ - ServiceReply publishServicesTopic(String sn, String method, Object data, String bid); - - /** - * Used exclusively for sending messages for services. - * @param clazz The generic class for ServiceReply. - * @param sn - * @param method - * @param data - * @param - * @return - */ - ServiceReply publishServicesTopic(TypeReference clazz, String sn, String method, Object data); - - /** - * Used exclusively for sending messages for services, and does not set the received subtype. - * @param sn - * @param method - * @param data - * @return - */ - ServiceReply publishServicesTopic(String sn, String method, Object data); -} diff --git a/src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java b/src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java deleted file mode 100644 index fdaf62c..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.dji.sample.component.mqtt.service.impl; - -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.IMessageSenderService; -import com.dji.sample.component.mqtt.service.IMqttMessageGateway; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.TypeMismatchException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; - -import java.util.Objects; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author sean.zhou - * @date 2021/11/16 - * @version 0.1 - */ -@Service -@Slf4j -public class MessageSenderServiceImpl implements IMessageSenderService { - - @Autowired - private IMqttMessageGateway messageGateway; - - @Autowired - private ObjectMapper mapper; - - public void publish(String topic, CommonTopicResponse response) { - this.publish(topic, 1, response); - } - - public void publish(String topic, int qos, CommonTopicResponse response) { - try { - log.info("send topic: {}, payload: {}", topic, response.toString()); - messageGateway.publish(topic, mapper.writeValueAsBytes(response), qos); - } catch (JsonProcessingException e) { - log.info("Failed to publish the message. {}", response.toString()); - e.printStackTrace(); - } - } - - public T publishWithReply(Class clazz, String topic, CommonTopicResponse response) { - return this.publishWithReply(clazz, topic, response, 2); - } - - public T publishWithReply(Class clazz, String topic, CommonTopicResponse response, int retryTime) { - AtomicInteger time = new AtomicInteger(0); - // Retry three times - while (time.getAndIncrement() <= retryTime) { - this.publish(topic, response); - - Chan> chan = Chan.getInstance(); - // If the message is not received in 0.5 seconds then resend it again. - CommonTopicReceiver receiver = chan.get(response.getTid()); - - // Need to match tid and bid. - if (Objects.nonNull(receiver) && receiver.getTid().equals(response.getTid()) && - receiver.getBid().equals(response.getBid())) { - if (clazz.isAssignableFrom(receiver.getData().getClass())) { - return receiver.getData(); - } - throw new TypeMismatchException(receiver.getData(), clazz); - } - // It must be guaranteed that the tid and bid of each message are different. - response.setBid(UUID.randomUUID().toString()); - response.setTid(UUID.randomUUID().toString()); - } - throw new RuntimeException("No message reply received."); - } - - @Override - public ServiceReply publishServicesTopic(TypeReference clazz, String sn, String method, Object data, String bid) { - String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + sn + TopicConst.SERVICES_SUF; - ServiceReply reply = this.publishWithReply(ServiceReply.class, topic, - CommonTopicResponse.builder() - .tid(UUID.randomUUID().toString()) - .bid(StringUtils.hasText(bid) ? bid : UUID.randomUUID().toString()) - .timestamp(System.currentTimeMillis()) - .method(method) - .data(Objects.requireNonNullElse(data, "")) - .build()); - if (Objects.isNull(clazz)) { - return reply; - } - // put together in "output" - if (Objects.nonNull(reply.getInfo())) { - reply.setOutput(mapper.convertValue(reply.getInfo(), clazz)); - } - if (Objects.nonNull(reply.getOutput())) { - reply.setOutput(mapper.convertValue(reply.getOutput(), clazz)); - } - return reply; - } - - @Override - public ServiceReply publishServicesTopic(String sn, String method, Object data, String bid) { - return this.publishServicesTopic(null, sn, method, data, bid); - } - - @Override - public ServiceReply publishServicesTopic(TypeReference clazz, String sn, String method, Object data) { - return this.publishServicesTopic(clazz, sn, method, data, null); - } - - @Override - public ServiceReply publishServicesTopic(String sn, String method, Object data) { - return this.publishServicesTopic(null, sn, method, data, null); - } - -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/mqtt/service/impl/MqttTopicServiceImpl.java b/src/main/java/com/dji/sample/component/mqtt/service/impl/MqttTopicServiceImpl.java deleted file mode 100644 index 6880ecf..0000000 --- a/src/main/java/com/dji/sample/component/mqtt/service/impl/MqttTopicServiceImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.dji.sample.component.mqtt.service.impl; - -import com.dji.sample.component.mqtt.service.IMqttTopicService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter; -import org.springframework.stereotype.Component; - -import javax.annotation.Resource; - -/** - * - * @author sean.zhou - * @date 2021/11/10 - * @version 0.1 - */ -@Component -@Slf4j -public class MqttTopicServiceImpl implements IMqttTopicService { - - @Resource - private MqttPahoMessageDrivenChannelAdapter adapter; - - @Override - public void subscribe(String topic) { - log.debug("subscribe topic: {}", topic); - adapter.addTopic(topic); - } - - @Override - public void subscribe(String topic, int qos) { - log.debug("subscribe topic: {}", topic); - adapter.addTopic(topic, qos); - } - - @Override - public void unsubscribe(String topic) { - log.debug("unsubscribe topic: {}", topic); - adapter.removeTopic(topic); - } - - public String[] getSubscribedTopic() { - return adapter.getTopic(); - } -} diff --git a/src/main/java/com/dji/sample/component/oss/model/OssConfiguration.java b/src/main/java/com/dji/sample/component/oss/model/OssConfiguration.java index da668c9..496c16a 100644 --- a/src/main/java/com/dji/sample/component/oss/model/OssConfiguration.java +++ b/src/main/java/com/dji/sample/component/oss/model/OssConfiguration.java @@ -1,5 +1,6 @@ package com.dji.sample.component.oss.model; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -13,9 +14,9 @@ import org.springframework.stereotype.Component; public class OssConfiguration { /** - * @see com.dji.sample.component.oss.model.enums.OssTypeEnum + * @see OssTypeEnum */ - public static String provider; + public static OssTypeEnum provider; /** * Whether to use the object storage service. @@ -43,7 +44,7 @@ public class OssConfiguration { public static String objectDirPrefix; - public void setProvider(String provider) { + public void setProvider(OssTypeEnum provider) { OssConfiguration.provider = provider; } diff --git a/src/main/java/com/dji/sample/component/oss/service/IOssService.java b/src/main/java/com/dji/sample/component/oss/service/IOssService.java index 5d8e415..3b26050 100644 --- a/src/main/java/com/dji/sample/component/oss/service/IOssService.java +++ b/src/main/java/com/dji/sample/component/oss/service/IOssService.java @@ -1,6 +1,7 @@ package com.dji.sample.component.oss.service; -import com.dji.sample.media.model.CredentialsDTO; +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; import java.io.InputStream; import java.net.URL; @@ -12,13 +13,13 @@ import java.net.URL; */ public interface IOssService { - String getOssType(); + OssTypeEnum getOssType(); /** * Get temporary credentials. * @return */ - CredentialsDTO getCredentials(); + CredentialsToken getCredentials(); /** * Get the address of the object based on the bucket name and the object name. diff --git a/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java b/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java index 6717849..cf78637 100644 --- a/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java +++ b/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java @@ -13,9 +13,9 @@ import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest; import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse; import com.dji.sample.component.oss.model.OssConfiguration; -import com.dji.sample.component.oss.model.enums.OssTypeEnum; import com.dji.sample.component.oss.service.IOssService; -import com.dji.sample.media.model.CredentialsDTO; +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -36,12 +36,12 @@ public class AliyunOssServiceImpl implements IOssService { private OSS ossClient; @Override - public String getOssType() { - return OssTypeEnum.ALIYUN.getType(); + public OssTypeEnum getOssType() { + return OssTypeEnum.ALIYUN; } @Override - public CredentialsDTO getCredentials() { + public CredentialsToken getCredentials() { try { DefaultProfile profile = DefaultProfile.getProfile( @@ -54,7 +54,7 @@ public class AliyunOssServiceImpl implements IOssService { request.setRoleSessionName(OssConfiguration.roleSessionName); AssumeRoleResponse response = client.getAcsResponse(request); - return new CredentialsDTO(response.getCredentials(), OssConfiguration.expire); + return new CredentialsToken(response.getCredentials(), OssConfiguration.expire); } catch (ClientException e) { log.debug("Failed to obtain sts."); @@ -95,7 +95,7 @@ public class AliyunOssServiceImpl implements IOssService { throw new RuntimeException("The filename already exists."); } PutObjectResult objectResult = ossClient.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata())); - log.info("Upload File: {}", objectResult.getETag()); + log.info("Upload FlighttaskCreateFile: {}", objectResult.getETag()); } public void createClient() { diff --git a/src/main/java/com/dji/sample/component/oss/service/impl/AmazonS3ServiceImpl.java b/src/main/java/com/dji/sample/component/oss/service/impl/AmazonS3ServiceImpl.java index fa896b6..10e109a 100644 --- a/src/main/java/com/dji/sample/component/oss/service/impl/AmazonS3ServiceImpl.java +++ b/src/main/java/com/dji/sample/component/oss/service/impl/AmazonS3ServiceImpl.java @@ -13,9 +13,9 @@ import com.amazonaws.services.securitytoken.model.AssumeRoleResult; import com.amazonaws.services.securitytoken.model.Credentials; import com.dji.sample.component.AuthInterceptor; import com.dji.sample.component.oss.model.OssConfiguration; -import com.dji.sample.component.oss.model.enums.OssTypeEnum; import com.dji.sample.component.oss.service.IOssService; -import com.dji.sample.media.model.CredentialsDTO; +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -39,12 +39,12 @@ public class AmazonS3ServiceImpl implements IOssService { private AmazonS3 client; @Override - public String getOssType() { - return OssTypeEnum.AWS.getType(); + public OssTypeEnum getOssType() { + return OssTypeEnum.AWS; } @Override - public CredentialsDTO getCredentials() { + public CredentialsToken getCredentials() { AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider( new BasicAWSCredentials(OssConfiguration.accessKey, OssConfiguration.secretKey))) @@ -56,7 +56,7 @@ public class AmazonS3ServiceImpl implements IOssService { .withDurationSeconds(Math.toIntExact(OssConfiguration.expire)); AssumeRoleResult result = stsClient.assumeRole(request); Credentials credentials = result.getCredentials(); - return new CredentialsDTO(credentials); + return new CredentialsToken(credentials); } @Override @@ -84,7 +84,7 @@ public class AmazonS3ServiceImpl implements IOssService { throw new RuntimeException("The filename already exists."); } PutObjectResult objectResult = client.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata())); - log.info("Upload File: {}", objectResult.toString()); + log.info("Upload FlighttaskCreateFile: {}", objectResult.toString()); } public void createClient() { diff --git a/src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java b/src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java index cafeb66..5039094 100644 --- a/src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java +++ b/src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java @@ -1,9 +1,9 @@ package com.dji.sample.component.oss.service.impl; import com.dji.sample.component.oss.model.OssConfiguration; -import com.dji.sample.component.oss.model.enums.OssTypeEnum; import com.dji.sample.component.oss.service.IOssService; -import com.dji.sample.media.model.CredentialsDTO; +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; import io.minio.*; import io.minio.credentials.AssumeRoleProvider; import io.minio.errors.*; @@ -31,17 +31,17 @@ public class MinIOServiceImpl implements IOssService { private MinioClient client; @Override - public String getOssType() { - return OssTypeEnum.MINIO.getType(); + public OssTypeEnum getOssType() { + return OssTypeEnum.MINIO; } @Override - public CredentialsDTO getCredentials() { + public CredentialsToken getCredentials() { try { AssumeRoleProvider provider = new AssumeRoleProvider(OssConfiguration.endpoint, OssConfiguration.accessKey, OssConfiguration.secretKey, Math.toIntExact(OssConfiguration.expire), null, OssConfiguration.region, null, null, null, null); - return new CredentialsDTO(provider.fetch(), OssConfiguration.expire); + return new CredentialsToken(provider.fetch(), OssConfiguration.expire); } catch (NoSuchAlgorithmException e) { log.debug("Failed to obtain sts."); e.printStackTrace(); @@ -100,9 +100,9 @@ public class MinIOServiceImpl implements IOssService { try { ObjectWriteResponse response = client.putObject( PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(input, input.available(), 0).build()); - log.info("Upload File: {}", response.etag()); + log.info("Upload FlighttaskCreateFile: {}", response.etag()); } catch (MinioException | IOException | InvalidKeyException | NoSuchAlgorithmException ex) { - log.error("Failed to upload File {}.", objectKey); + log.error("Failed to upload FlighttaskCreateFile {}.", objectKey); ex.printStackTrace(); } } diff --git a/src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java b/src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java index 28333ca..c46fad8 100644 --- a/src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java +++ b/src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java @@ -1,9 +1,9 @@ package com.dji.sample.component.oss.service.impl; import com.dji.sample.component.oss.model.OssConfiguration; -import com.dji.sample.component.oss.model.enums.OssTypeEnum; import com.dji.sample.component.oss.service.IOssService; -import com.dji.sample.media.model.CredentialsDTO; +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @@ -29,7 +29,7 @@ public class OssServiceContext { return; } this.ossService = ossServices.stream() - .filter(ossService -> ossService.getOssType().equals(OssConfiguration.provider)) + .filter(ossService -> ossService.getOssType() == OssConfiguration.provider) .findFirst() .orElseThrow(() -> new IllegalArgumentException("Oss provider is illegal. Optional: " + Arrays.toString(Arrays.stream(OssTypeEnum.values()).map(OssTypeEnum::getType).toArray()))); @@ -39,7 +39,7 @@ public class OssServiceContext { return this.ossService; } - public CredentialsDTO getCredentials() { + public CredentialsToken getCredentials() { return this.ossService.getCredentials(); } diff --git a/src/main/java/com/dji/sample/component/redis/RedisConst.java b/src/main/java/com/dji/sample/component/redis/RedisConst.java index 574ae62..023eabd 100644 --- a/src/main/java/com/dji/sample/component/redis/RedisConst.java +++ b/src/main/java/com/dji/sample/component/redis/RedisConst.java @@ -1,7 +1,5 @@ package com.dji.sample.component.redis; -import com.dji.sample.manage.model.enums.DeviceDomainEnum; - /** * @author sean * @version 1.0 @@ -21,9 +19,7 @@ public final class RedisConst { public static final Integer WEBSOCKET_ALIVE_SECOND = 60 * 60 * 24; - public static final String ONLINE_PREFIX = "online" + DELIMITER; - - public static final String DEVICE_ONLINE_PREFIX = ONLINE_PREFIX + DeviceDomainEnum.SUB_DEVICE + DELIMITER; + public static final String DEVICE_ONLINE_PREFIX = "online" + DELIMITER; public static final String WEBSOCKET_PREFIX = "webSocket" + DELIMITER; @@ -37,9 +33,11 @@ public final class RedisConst { public static final String LOGS_FILE_PREFIX = "logs_file" + DELIMITER; - public static final String WAYLINE_JOB_PREPARED = "wayline_job_prepared"; + public static final String WAYLINE_JOB_TIMED_EXECUTE = "wayline_job_timed_execute"; + + public static final String WAYLINE_JOB_CONDITION_PREPARE = "wayline_job_condition_prepare"; - public static final String WAYLINE_JOB_CONDITION_PREFIX = "wayline_job_condition" + DELIMITER; + public static final String WAYLINE_JOB_CONDITION_PREFIX = WAYLINE_JOB_CONDITION_PREPARE + DELIMITER; public static final String WAYLINE_JOB_BLOCK_PREFIX = "wayline_job_block" + DELIMITER; diff --git a/src/main/java/com/dji/sample/component/websocket/config/MyConcurrentWebSocketSession.java b/src/main/java/com/dji/sample/component/websocket/config/MyConcurrentWebSocketSession.java new file mode 100644 index 0000000..6941064 --- /dev/null +++ b/src/main/java/com/dji/sample/component/websocket/config/MyConcurrentWebSocketSession.java @@ -0,0 +1,25 @@ +package com.dji.sample.component.websocket.config; + +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/24 + */ +public class MyConcurrentWebSocketSession extends ConcurrentWebSocketSessionDecorator { + + private static final int SEND_BUFFER_SIZE_LIMIT = 1024 * 1024; + + private static final int SEND_TIME_LIMIT = 1000; + + private MyConcurrentWebSocketSession(WebSocketSession delegate, int sendTimeLimit, int bufferSizeLimit) { + super(delegate, sendTimeLimit, bufferSizeLimit); + } + + MyConcurrentWebSocketSession(WebSocketSession delegate) { + this(delegate, SEND_TIME_LIMIT, SEND_BUFFER_SIZE_LIMIT); + } + +} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/websocket/config/WebSocketDefaultFactory.java b/src/main/java/com/dji/sample/component/websocket/config/MyWebSocketFactory.java similarity index 67% rename from src/main/java/com/dji/sample/component/websocket/config/WebSocketDefaultFactory.java rename to src/main/java/com/dji/sample/component/websocket/config/MyWebSocketFactory.java index f6ad8fb..22fb995 100644 --- a/src/main/java/com/dji/sample/component/websocket/config/WebSocketDefaultFactory.java +++ b/src/main/java/com/dji/sample/component/websocket/config/MyWebSocketFactory.java @@ -1,10 +1,11 @@ package com.dji.sample.component.websocket.config; import com.dji.sample.component.websocket.service.IWebSocketManageService; +import com.dji.sdk.websocket.WebSocketDefaultFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; import org.springframework.web.socket.WebSocketHandler; -import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory; /** * @@ -13,13 +14,14 @@ import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory; * @version 0.1 */ @Component -public class WebSocketDefaultFactory implements WebSocketHandlerDecoratorFactory { +@Primary +public class MyWebSocketFactory extends WebSocketDefaultFactory { @Autowired private IWebSocketManageService webSocketManageService; @Override public WebSocketHandler decorate(WebSocketHandler handler) { - return new WebSocketDefaultHandler(handler, webSocketManageService); + return new MyWebSocketHandler(handler, webSocketManageService); } } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/websocket/config/WebSocketDefaultHandler.java b/src/main/java/com/dji/sample/component/websocket/config/MyWebSocketHandler.java similarity index 86% rename from src/main/java/com/dji/sample/component/websocket/config/WebSocketDefaultHandler.java rename to src/main/java/com/dji/sample/component/websocket/config/MyWebSocketHandler.java index 11ee861..d6016b0 100644 --- a/src/main/java/com/dji/sample/component/websocket/config/WebSocketDefaultHandler.java +++ b/src/main/java/com/dji/sample/component/websocket/config/MyWebSocketHandler.java @@ -1,13 +1,13 @@ package com.dji.sample.component.websocket.config; import com.dji.sample.component.websocket.service.IWebSocketManageService; +import com.dji.sdk.websocket.WebSocketDefaultHandler; import lombok.extern.slf4j.Slf4j; import org.springframework.util.StringUtils; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketMessage; import org.springframework.web.socket.WebSocketSession; -import org.springframework.web.socket.handler.WebSocketHandlerDecorator; import java.security.Principal; @@ -18,11 +18,11 @@ import java.security.Principal; * @version 0.1 */ @Slf4j -public class WebSocketDefaultHandler extends WebSocketHandlerDecorator { +public class MyWebSocketHandler extends WebSocketDefaultHandler { private IWebSocketManageService webSocketManageService; - WebSocketDefaultHandler(WebSocketHandler delegate, IWebSocketManageService webSocketManageService) { + MyWebSocketHandler(WebSocketHandler delegate, IWebSocketManageService webSocketManageService) { super(delegate); this.webSocketManageService = webSocketManageService; } @@ -31,7 +31,7 @@ public class WebSocketDefaultHandler extends WebSocketHandlerDecorator { public void afterConnectionEstablished(WebSocketSession session) throws Exception { Principal principal = session.getPrincipal(); if (StringUtils.hasText(principal.getName())) { - webSocketManageService.put(principal.getName(), new ConcurrentWebSocketSession(session)); + webSocketManageService.put(principal.getName(), new MyConcurrentWebSocketSession(session)); log.debug("{} is connected. ID: {}. WebSocketSession[current count: {}]", principal.getName(), session.getId(), webSocketManageService.getConnectedCount()); return; diff --git a/src/main/java/com/dji/sample/component/websocket/model/BizCodeEnum.java b/src/main/java/com/dji/sample/component/websocket/model/BizCodeEnum.java index 2094d48..cecbf57 100644 --- a/src/main/java/com/dji/sample/component/websocket/model/BizCodeEnum.java +++ b/src/main/java/com/dji/sample/component/websocket/model/BizCodeEnum.java @@ -15,7 +15,7 @@ public enum BizCodeEnum { DEVICE_OSD("device_osd"), - GATEWAY_OSD("gateway_osd"), + RC_OSD("gateway_osd"), DOCK_OSD("dock_osd"), diff --git a/src/main/java/com/dji/sample/component/websocket/model/CustomWebSocketMessage.java b/src/main/java/com/dji/sample/component/websocket/model/CustomWebSocketMessage.java deleted file mode 100644 index c1d162d..0000000 --- a/src/main/java/com/dji/sample/component/websocket/model/CustomWebSocketMessage.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.dji.sample.component.websocket.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Builder; -import lombok.Data; - -/** - * The format of WebSocket messages that the pilot can receive. - * @author sean.zhou - * @date 2021/11/17 - * @version 0.1 - */ -@Data -@Builder -public class CustomWebSocketMessage { - - /** - * @see BizCodeEnum - * specific value - */ - @JsonProperty("biz_code") - private String bizCode; - - @Builder.Default - private String version = "1.0"; - - private Long timestamp; - - private T data; -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/websocket/service/IWebSocketManageService.java b/src/main/java/com/dji/sample/component/websocket/service/IWebSocketManageService.java index f09a6e2..21d3009 100644 --- a/src/main/java/com/dji/sample/component/websocket/service/IWebSocketManageService.java +++ b/src/main/java/com/dji/sample/component/websocket/service/IWebSocketManageService.java @@ -1,6 +1,6 @@ package com.dji.sample.component.websocket.service; -import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession; +import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession; import java.util.Collection; @@ -11,13 +11,13 @@ import java.util.Collection; */ public interface IWebSocketManageService { - void put(String key, ConcurrentWebSocketSession val); + void put(String key, MyConcurrentWebSocketSession val); void remove(String key, String sessionId); - Collection getValueWithWorkspace(String workspaceId); + Collection getValueWithWorkspace(String workspaceId); - Collection getValueWithWorkspaceAndUserType(String workspaceId, Integer userType); + Collection getValueWithWorkspaceAndUserType(String workspaceId, Integer userType); Long getConnectedCount(); } diff --git a/src/main/java/com/dji/sample/component/websocket/service/ISendMessageService.java b/src/main/java/com/dji/sample/component/websocket/service/IWebSocketMessageService.java similarity index 62% rename from src/main/java/com/dji/sample/component/websocket/service/ISendMessageService.java rename to src/main/java/com/dji/sample/component/websocket/service/IWebSocketMessageService.java index a9b3d8f..ee51adb 100644 --- a/src/main/java/com/dji/sample/component/websocket/service/ISendMessageService.java +++ b/src/main/java/com/dji/sample/component/websocket/service/IWebSocketMessageService.java @@ -1,7 +1,7 @@ package com.dji.sample.component.websocket.service; -import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession; -import com.dji.sample.component.websocket.model.CustomWebSocketMessage; +import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession; +import com.dji.sdk.websocket.WebSocketMessageResponse; import java.util.Collection; @@ -10,21 +10,21 @@ import java.util.Collection; * @date 2021/11/24 * @version 0.1 */ -public interface ISendMessageService { +public interface IWebSocketMessageService { /** * Send a message to the specific connection. * @param session A WebSocket connection object * @param message message */ - void sendMessage(ConcurrentWebSocketSession session, CustomWebSocketMessage message); + void sendMessage(MyConcurrentWebSocketSession session, WebSocketMessageResponse message); /** * Send the same message to specific connection. * @param sessions A collection of WebSocket connection objects. * @param message message */ - void sendBatch(Collection sessions, CustomWebSocketMessage message); + void sendBatch(Collection sessions, WebSocketMessageResponse message); void sendBatch(String workspaceId, Integer userType, String bizCode, Object data); diff --git a/src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketManageServiceImpl.java b/src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketManageServiceImpl.java index a0070d4..755e78d 100644 --- a/src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketManageServiceImpl.java +++ b/src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketManageServiceImpl.java @@ -2,7 +2,7 @@ package com.dji.sample.component.websocket.service.impl; 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.config.MyConcurrentWebSocketSession; import com.dji.sample.component.websocket.service.IWebSocketManageService; import com.dji.sample.manage.model.enums.UserTypeEnum; import lombok.extern.slf4j.Slf4j; @@ -24,10 +24,10 @@ import java.util.stream.Collectors; @Service public class WebSocketManageServiceImpl implements IWebSocketManageService { - private static final ConcurrentHashMap SESSIONS = new ConcurrentHashMap<>(16); - + private static final ConcurrentHashMap SESSIONS = new ConcurrentHashMap<>(16); + @Override - public void put(String key, ConcurrentWebSocketSession val) { + public void put(String key, MyConcurrentWebSocketSession val) { String[] name = key.split("/"); if (name.length != 3) { log.debug("The key is out of format. [{workspaceId}/{userType}/{userId}]"); @@ -56,7 +56,7 @@ public class WebSocketManageServiceImpl implements IWebSocketManageService { } @Override - public Collection getValueWithWorkspace(String workspaceId) { + public Collection getValueWithWorkspace(String workspaceId) { if (!StringUtils.hasText(workspaceId)) { return Collections.emptySet(); } @@ -70,12 +70,12 @@ public class WebSocketManageServiceImpl implements IWebSocketManageService { } @Override - public Collection getValueWithWorkspaceAndUserType(String workspaceId, Integer userType) { + public Collection getValueWithWorkspaceAndUserType(String workspaceId, Integer userType) { String key = RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(userType).getDesc(); return RedisOpsUtils.hashKeys(key) .stream() .map(SESSIONS::get) - .filter(this.getValueWithWorkspace(workspaceId)::contains) + .filter(getValueWithWorkspace(workspaceId)::contains) .collect(Collectors.toSet()); } diff --git a/src/main/java/com/dji/sample/component/websocket/service/impl/SendMessageServiceImpl.java b/src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketMessageServiceImpl.java similarity index 72% rename from src/main/java/com/dji/sample/component/websocket/service/impl/SendMessageServiceImpl.java rename to src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketMessageServiceImpl.java index b605cf9..adfd6ee 100644 --- a/src/main/java/com/dji/sample/component/websocket/service/impl/SendMessageServiceImpl.java +++ b/src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketMessageServiceImpl.java @@ -1,9 +1,9 @@ package com.dji.sample.component.websocket.service.impl; -import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession; -import com.dji.sample.component.websocket.model.CustomWebSocketMessage; -import com.dji.sample.component.websocket.service.ISendMessageService; +import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession; import com.dji.sample.component.websocket.service.IWebSocketManageService; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sdk.websocket.WebSocketMessageResponse; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -22,7 +22,7 @@ import java.util.Objects; */ @Service @Slf4j -public class SendMessageServiceImpl implements ISendMessageService { +public class WebSocketMessageServiceImpl implements IWebSocketMessageService { @Autowired private ObjectMapper mapper; @@ -31,7 +31,7 @@ public class SendMessageServiceImpl implements ISendMessageService { private IWebSocketManageService webSocketManageService; @Override - public void sendMessage(ConcurrentWebSocketSession session, CustomWebSocketMessage message) { + public void sendMessage(MyConcurrentWebSocketSession session, WebSocketMessageResponse message) { if (session == null) { return; } @@ -52,7 +52,7 @@ public class SendMessageServiceImpl implements ISendMessageService { } @Override - public void sendBatch(Collection sessions, CustomWebSocketMessage message) { + public void sendBatch(Collection sessions, WebSocketMessageResponse message) { if (sessions.isEmpty()) { return; } @@ -61,7 +61,7 @@ public class SendMessageServiceImpl implements ISendMessageService { TextMessage data = new TextMessage(mapper.writeValueAsBytes(message)); - for (ConcurrentWebSocketSession session : sessions) { + for (MyConcurrentWebSocketSession session : sessions) { if (!session.isOpen()) { session.close(); log.debug("This session is closed."); @@ -82,15 +82,14 @@ public class SendMessageServiceImpl implements ISendMessageService { if (!StringUtils.hasText(workspaceId)) { throw new RuntimeException("Workspace ID does not exist."); } - Collection sessions = Objects.isNull(userType) ? + Collection sessions = Objects.isNull(userType) ? webSocketManageService.getValueWithWorkspace(workspaceId) : webSocketManageService.getValueWithWorkspaceAndUserType(workspaceId, userType); - this.sendBatch(sessions, CustomWebSocketMessage.builder() - .data(data) - .timestamp(System.currentTimeMillis()) - .bizCode(bizCode) - .build()); + this.sendBatch(sessions, new WebSocketMessageResponse() + .setData(Objects.requireNonNullElse(data, "")) + .setTimestamp(System.currentTimeMillis()) + .setBizCode(bizCode)); } @Override diff --git a/src/main/java/com/dji/sample/configuration/SpringBeanConfiguration.java b/src/main/java/com/dji/sample/configuration/SpringBeanConfiguration.java index eee6f48..9bfd8ce 100644 --- a/src/main/java/com/dji/sample/configuration/SpringBeanConfiguration.java +++ b/src/main/java/com/dji/sample/configuration/SpringBeanConfiguration.java @@ -23,7 +23,6 @@ public class SpringBeanConfiguration { public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); - objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); JavaTimeModule timeModule = new JavaTimeModule(); diff --git a/src/main/java/com/dji/sample/configuration/mvc/GetSnakeDataBinder.java b/src/main/java/com/dji/sample/configuration/mvc/GetSnakeDataBinder.java deleted file mode 100644 index 8a7ca6a..0000000 --- a/src/main/java/com/dji/sample/configuration/mvc/GetSnakeDataBinder.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.dji.sample.configuration.mvc; - -import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.PropertyValue; -import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder; - -import javax.servlet.ServletRequest; -import java.util.ArrayList; -import java.util.List; - -/** - * @author sean - * @version 1.2 - * @date 2022/9/9 - */ -public class GetSnakeDataBinder extends ExtendedServletRequestDataBinder { - - public GetSnakeDataBinder(Object target, String objectName) { - super(target, objectName); - } - - @Override - protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) { - List propertyValueList = mpvs.getPropertyValueList(); - List values = new ArrayList<>(propertyValueList); - for (PropertyValue property : values) { - String name = convertSnake(property.getName()); - if (!property.getName().equals(name)) { - mpvs.addPropertyValue(new PropertyValue(name, property.getValue())); - propertyValueList.remove(property); - } - } - super.addBindValues(mpvs, request); - } - - private String convertSnake(String key) { - StringBuilder sb = new StringBuilder(); - boolean isChange = false; - for (char c : key.toCharArray()) { - if (c == '_') { - isChange = true; - continue; - } - if (isChange) { - sb.append((char) (c - 32)); - isChange = false; - continue; - } - sb.append(c); - } - return sb.toString(); - } -} diff --git a/src/main/java/com/dji/sample/configuration/mvc/GlobalMVCConfigurer.java b/src/main/java/com/dji/sample/configuration/mvc/GlobalMVCConfigurer.java index c28e6c4..bb03a1d 100644 --- a/src/main/java/com/dji/sample/configuration/mvc/GlobalMVCConfigurer.java +++ b/src/main/java/com/dji/sample/configuration/mvc/GlobalMVCConfigurer.java @@ -4,7 +4,6 @@ import com.dji.sample.component.AuthInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -29,14 +28,13 @@ public class GlobalMVCConfigurer implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // Exclude the login interface. - excludePaths.add(managePrefix + manageVersion + "/login"); - excludePaths.add(managePrefix + manageVersion + "/token/refresh"); + excludePaths.add("/" + managePrefix + manageVersion + "/login"); + excludePaths.add("/" + managePrefix + manageVersion + "/token/refresh"); + excludePaths.add("/swagger-ui.html"); + excludePaths.add("/swagger-ui/**"); + excludePaths.add("/v3/**"); + excludePaths.add("/ui/**"); // Intercept for all request interfaces. registry.addInterceptor(authInterceptor).addPathPatterns("/**").excludePathPatterns(excludePaths); } - - @Override - public void addArgumentResolvers(List resolvers) { - resolvers.add(new GetSnakeArgumentProcessor(true)); - } } diff --git a/src/main/java/com/dji/sample/control/controller/DockController.java b/src/main/java/com/dji/sample/control/controller/DockController.java index 53d07f5..3146d9d 100644 --- a/src/main/java/com/dji/sample/control/controller/DockController.java +++ b/src/main/java/com/dji/sample/control/controller/DockController.java @@ -1,9 +1,10 @@ package com.dji.sample.control.controller; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.control.model.enums.DroneAuthorityEnum; +import com.dji.sample.control.model.enums.RemoteDebugMethodEnum; import com.dji.sample.control.model.param.*; import com.dji.sample.control.service.IControlService; +import com.dji.sdk.common.HttpResultResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -24,39 +25,39 @@ public class DockController { private IControlService controlService; @PostMapping("/{sn}/jobs/{service_identifier}") - public ResponseResult createControlJob(@PathVariable String sn, - @PathVariable("service_identifier") String serviceIdentifier, - @RequestBody(required = false) RemoteDebugParam param) { - return controlService.controlDockDebug(sn, serviceIdentifier, param); + public HttpResultResponse createControlJob(@PathVariable String sn, + @PathVariable("service_identifier") String serviceIdentifier, + @Valid @RequestBody(required = false) RemoteDebugParam param) { + return controlService.controlDockDebug(sn, RemoteDebugMethodEnum.find(serviceIdentifier), param); } @PostMapping("/{sn}/jobs/fly-to-point") - public ResponseResult flyToPoint(@PathVariable String sn, @Valid @RequestBody FlyToPointParam param) { + public HttpResultResponse flyToPoint(@PathVariable String sn, @Valid @RequestBody FlyToPointParam param) { return controlService.flyToPoint(sn, param); } @DeleteMapping("/{sn}/jobs/fly-to-point") - public ResponseResult flyToPointStop(@PathVariable String sn) { + public HttpResultResponse flyToPointStop(@PathVariable String sn) { return controlService.flyToPointStop(sn); } @PostMapping("/{sn}/jobs/takeoff-to-point") - public ResponseResult takeoffToPoint(@PathVariable String sn, @Valid @RequestBody TakeoffToPointParam param) { + public HttpResultResponse takeoffToPoint(@PathVariable String sn, @Valid @RequestBody TakeoffToPointParam param) { return controlService.takeoffToPoint(sn, param); } @PostMapping("/{sn}/authority/flight") - public ResponseResult seizeFlightAuthority(@PathVariable String sn) { + public HttpResultResponse seizeFlightAuthority(@PathVariable String sn) { return controlService.seizeAuthority(sn, DroneAuthorityEnum.FLIGHT, null); } @PostMapping("/{sn}/authority/payload") - public ResponseResult seizePayloadAuthority(@PathVariable String sn, @Valid @RequestBody DronePayloadParam param) { + public HttpResultResponse seizePayloadAuthority(@PathVariable String sn, @Valid @RequestBody DronePayloadParam param) { return controlService.seizeAuthority(sn, DroneAuthorityEnum.PAYLOAD, param); } @PostMapping("/{sn}/payload/commands") - public ResponseResult payloadCommands(@PathVariable String sn, @Valid @RequestBody PayloadCommandsParam param) throws Exception { + public HttpResultResponse payloadCommands(@PathVariable String sn, @Valid @RequestBody PayloadCommandsParam param) throws Exception { param.setSn(sn); return controlService.payloadCommands(param); } diff --git a/src/main/java/com/dji/sample/control/controller/DrcController.java b/src/main/java/com/dji/sample/control/controller/DrcController.java index 6b66089..f40670c 100644 --- a/src/main/java/com/dji/sample/control/controller/DrcController.java +++ b/src/main/java/com/dji/sample/control/controller/DrcController.java @@ -1,12 +1,12 @@ package com.dji.sample.control.controller; import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.control.model.dto.JwtAclDTO; -import com.dji.sample.control.model.dto.MqttBrokerDTO; import com.dji.sample.control.model.param.DrcConnectParam; import com.dji.sample.control.model.param.DrcModeParam; import com.dji.sample.control.service.IDrcService; +import com.dji.sdk.cloudapi.control.DrcModeMqttBroker; +import com.dji.sdk.common.HttpResultResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -30,25 +30,25 @@ public class DrcController { private IDrcService drcService; @PostMapping("/workspaces/{workspace_id}/drc/connect") - public ResponseResult drcConnect(@PathVariable("workspace_id") String workspaceId, HttpServletRequest request, @Valid @RequestBody DrcConnectParam param) { + public HttpResultResponse drcConnect(@PathVariable("workspace_id") String workspaceId, HttpServletRequest request, @Valid @RequestBody DrcConnectParam param) { CustomClaim claims = (CustomClaim) request.getAttribute(TOKEN_CLAIM); - MqttBrokerDTO brokerDTO = drcService.userDrcAuth(workspaceId, claims.getId(), claims.getUsername(), param); - return ResponseResult.success(brokerDTO); + DrcModeMqttBroker brokerDTO = drcService.userDrcAuth(workspaceId, claims.getId(), claims.getUsername(), param); + return HttpResultResponse.success(brokerDTO); } @PostMapping("/workspaces/{workspace_id}/drc/enter") - public ResponseResult drcEnter(@PathVariable("workspace_id") String workspaceId, @Valid @RequestBody DrcModeParam param) { + public HttpResultResponse drcEnter(@PathVariable("workspace_id") String workspaceId, @Valid @RequestBody DrcModeParam param) { JwtAclDTO acl = drcService.deviceDrcEnter(workspaceId, param); - return ResponseResult.success(acl); + return HttpResultResponse.success(acl); } @PostMapping("/workspaces/{workspace_id}/drc/exit") - public ResponseResult drcExit(@PathVariable("workspace_id") String workspaceId, @Valid @RequestBody DrcModeParam param) { + public HttpResultResponse drcExit(@PathVariable("workspace_id") String workspaceId, @Valid @RequestBody DrcModeParam param) { drcService.deviceDrcExit(workspaceId, param); - return ResponseResult.success(); + return HttpResultResponse.success(); } diff --git a/src/main/java/com/dji/sample/control/model/dto/AirConditionerMode.java b/src/main/java/com/dji/sample/control/model/dto/AirConditionerMode.java new file mode 100644 index 0000000..901cccd --- /dev/null +++ b/src/main/java/com/dji/sample/control/model/dto/AirConditionerMode.java @@ -0,0 +1,22 @@ +package com.dji.sample.control.model.dto; + +import com.dji.sample.control.service.impl.RemoteDebugHandler; +import com.dji.sdk.cloudapi.device.AirConditionerStateEnum; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AirConditionerMode extends RemoteDebugHandler { + + private AirConditionerStateEnum action; +} diff --git a/src/main/java/com/dji/sample/control/model/dto/AlarmState.java b/src/main/java/com/dji/sample/control/model/dto/AlarmState.java index 1fb590b..62cf797 100644 --- a/src/main/java/com/dji/sample/control/model/dto/AlarmState.java +++ b/src/main/java/com/dji/sample/control/model/dto/AlarmState.java @@ -1,14 +1,12 @@ package com.dji.sample.control.model.dto; import com.dji.sample.control.service.impl.RemoteDebugHandler; -import com.dji.sample.manage.model.enums.StateSwitchEnum; +import com.dji.sdk.cloudapi.device.SwitchActionEnum; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import java.util.Objects; - /** * @author sean * @version 1.3 @@ -20,10 +18,6 @@ import java.util.Objects; @NoArgsConstructor public class AlarmState extends RemoteDebugHandler { - private Integer action; + private SwitchActionEnum action; - @Override - public boolean valid() { - return Objects.nonNull(action) && StateSwitchEnum.find(action).isPresent(); - } } diff --git a/src/main/java/com/dji/sample/control/model/dto/BatteryStoreMode.java b/src/main/java/com/dji/sample/control/model/dto/BatteryStoreMode.java index 9656a9e..871d29c 100644 --- a/src/main/java/com/dji/sample/control/model/dto/BatteryStoreMode.java +++ b/src/main/java/com/dji/sample/control/model/dto/BatteryStoreMode.java @@ -1,14 +1,12 @@ package com.dji.sample.control.model.dto; -import com.dji.sample.control.model.enums.BatteryStoreModeEnum; import com.dji.sample.control.service.impl.RemoteDebugHandler; +import com.dji.sdk.cloudapi.device.BatteryStoreModeEnum; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import java.util.Objects; - /** * @author sean * @version 1.3 @@ -20,10 +18,5 @@ import java.util.Objects; @NoArgsConstructor public class BatteryStoreMode extends RemoteDebugHandler { - private Integer action; - - @Override - public boolean valid() { - return Objects.nonNull(action) && BatteryStoreModeEnum.find(action).isPresent(); - } + private BatteryStoreModeEnum action; } diff --git a/src/main/java/com/dji/sample/control/model/dto/DrcModeDTO.java b/src/main/java/com/dji/sample/control/model/dto/DrcModeDTO.java deleted file mode 100644 index 771e85a..0000000 --- a/src/main/java/com/dji/sample/control/model/dto/DrcModeDTO.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.dji.sample.control.model.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 1.3 - * @date 2023/1/12 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class DrcModeDTO { - - private MqttBrokerDTO mqttBroker; - - /** - * range: 1 - 30 - */ - @Builder.Default - private Integer osdFrequency = 10; - - /** - * range: 1 - 30 - */ - @Builder.Default - private Integer hsiFrequency = 1; -} diff --git a/src/main/java/com/dji/sample/control/model/dto/DrcModeReasonReceiver.java b/src/main/java/com/dji/sample/control/model/dto/DrcModeReasonReceiver.java deleted file mode 100644 index 26429a9..0000000 --- a/src/main/java/com/dji/sample/control/model/dto/DrcModeReasonReceiver.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.dji.sample.control.model.dto; - -import com.dji.sample.control.model.enums.DrcModeReasonEnum; -import lombok.Data; - -/** - * @author sean - * @version 1.4 - * @date 2023/3/14 - */ -@Data -public class DrcModeReasonReceiver { - - private DrcModeReasonEnum reason; -} diff --git a/src/main/java/com/dji/sample/control/model/dto/DrcStatusNotifyReceiver.java b/src/main/java/com/dji/sample/control/model/dto/DrcStatusNotifyReceiver.java deleted file mode 100644 index 1ef8c04..0000000 --- a/src/main/java/com/dji/sample/control/model/dto/DrcStatusNotifyReceiver.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.dji.sample.control.model.dto; - -import com.dji.sample.control.model.enums.DrcStatusErrorEnum; -import com.dji.sample.manage.model.enums.DockDrcStateEnum; -import lombok.Data; - -/** - * @author sean - * @version 1.4 - * @date 2023/3/17 - */ -@Data -public class DrcStatusNotifyReceiver { - - private DrcStatusErrorEnum result; - - private DockDrcStateEnum drcState; -} diff --git a/src/main/java/com/dji/sample/control/model/dto/FlyToProgressReceiver.java b/src/main/java/com/dji/sample/control/model/dto/FlyToProgressReceiver.java deleted file mode 100644 index f51fbf6..0000000 --- a/src/main/java/com/dji/sample/control/model/dto/FlyToProgressReceiver.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.dji.sample.control.model.dto; - -import com.dji.sample.control.model.enums.FlyToStatusEnum; -import com.dji.sample.wayline.model.enums.WaylineErrorCodeEnum; -import lombok.Data; - -/** - * @author sean - * @version 1.4 - * @date 2023/3/14 - */ -@Data -public class FlyToProgressReceiver { - - private WaylineErrorCodeEnum result; - - private FlyToStatusEnum status; - - private String flyToId; - - private Integer wayPointIndex; -} diff --git a/src/main/java/com/dji/sample/control/model/dto/LinkWorkMode.java b/src/main/java/com/dji/sample/control/model/dto/LinkWorkMode.java index 884330d..599e5d6 100644 --- a/src/main/java/com/dji/sample/control/model/dto/LinkWorkMode.java +++ b/src/main/java/com/dji/sample/control/model/dto/LinkWorkMode.java @@ -1,14 +1,15 @@ package com.dji.sample.control.model.dto; -import com.dji.sample.control.model.enums.LinkWorkModeEnum; import com.dji.sample.control.service.impl.RemoteDebugHandler; +import com.dji.sdk.cloudapi.device.LinkWorkModeEnum; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; +import com.fasterxml.jackson.annotation.JsonValue; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import java.util.Objects; +import java.util.Map; /** * @author sean @@ -17,15 +18,18 @@ import java.util.Objects; */ @EqualsAndHashCode(callSuper = true) @Data -@AllArgsConstructor @NoArgsConstructor public class LinkWorkMode extends RemoteDebugHandler { - @JsonProperty("link_workmode") - private Integer linkWorkMode; + private LinkWorkModeEnum linkWorkMode; - @Override - public boolean valid() { - return Objects.nonNull(linkWorkMode) && LinkWorkModeEnum.find(linkWorkMode).isPresent(); + @JsonCreator + public LinkWorkMode(@JsonProperty("action") Integer linkWorkMode) { + this.linkWorkMode = LinkWorkModeEnum.find(linkWorkMode); + } + + @JsonValue + public Map toMap() { + return Map.of("link_workmode", linkWorkMode.getMode()); } } diff --git a/src/main/java/com/dji/sample/control/model/dto/MqttBrokerDTO.java b/src/main/java/com/dji/sample/control/model/dto/MqttBrokerDTO.java deleted file mode 100644 index af19dba..0000000 --- a/src/main/java/com/dji/sample/control/model/dto/MqttBrokerDTO.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.dji.sample.control.model.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 1.3 - * @date 2023/1/11 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class MqttBrokerDTO { - - private String address; - - private String username; - - private String password; - - private String clientId; - - private Long expireTime; - - @Builder.Default - private Boolean enableTls = false; -} diff --git a/src/main/java/com/dji/sample/control/model/dto/PointDTO.java b/src/main/java/com/dji/sample/control/model/dto/PointDTO.java deleted file mode 100644 index 8c6acaf..0000000 --- a/src/main/java/com/dji/sample/control/model/dto/PointDTO.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.dji.sample.control.model.dto; - -import lombok.Data; -import org.hibernate.validator.constraints.Range; - -import javax.validation.constraints.NotNull; - -/** - * @author sean - * @version 1.3 - * @date 2023/2/14 - */ -@Data -public class PointDTO { - - @Range(min = -90, max = 90) - @NotNull - private Double latitude; - - @NotNull - @Range(min = -180, max = 180) - private Double longitude; - - /** - * WGS84 - * The M30 series are ellipsoidal heights. - */ - @NotNull - @Range(min = 2, max = 1500) - private Double height; -} diff --git a/src/main/java/com/dji/sample/control/model/dto/RemoteDebugOpenState.java b/src/main/java/com/dji/sample/control/model/dto/RemoteDebugOpenState.java index 069307d..3e67a3e 100644 --- a/src/main/java/com/dji/sample/control/model/dto/RemoteDebugOpenState.java +++ b/src/main/java/com/dji/sample/control/model/dto/RemoteDebugOpenState.java @@ -1,9 +1,9 @@ package com.dji.sample.control.model.dto; -import com.dji.sample.common.util.SpringBeanUtils; +import com.dji.sample.common.util.SpringBeanUtilsTest; import com.dji.sample.control.service.impl.RemoteDebugHandler; -import com.dji.sample.manage.model.enums.DockModeCodeEnum; import com.dji.sample.manage.service.IDeviceService; +import com.dji.sdk.cloudapi.device.DockModeCodeEnum; import lombok.Data; import lombok.EqualsAndHashCode; @@ -18,7 +18,7 @@ public class RemoteDebugOpenState extends RemoteDebugHandler { @Override public boolean canPublish(String sn) { - IDeviceService deviceService = SpringBeanUtils.getBean(IDeviceService.class); + IDeviceService deviceService = SpringBeanUtilsTest.getBean(IDeviceService.class); DockModeCodeEnum dockMode = deviceService.getDockMode(sn); return DockModeCodeEnum.IDLE == dockMode; } diff --git a/src/main/java/com/dji/sample/control/model/dto/ReturnHomeCancelState.java b/src/main/java/com/dji/sample/control/model/dto/ReturnHomeCancelState.java new file mode 100644 index 0000000..73b203f --- /dev/null +++ b/src/main/java/com/dji/sample/control/model/dto/ReturnHomeCancelState.java @@ -0,0 +1,28 @@ +package com.dji.sample.control.model.dto; + +import com.dji.sample.common.util.SpringBeanUtilsTest; +import com.dji.sample.control.service.impl.RemoteDebugHandler; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.device.DroneModeCodeEnum; +import com.dji.sdk.cloudapi.device.OsdDockDrone; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/19 + */ + +public class ReturnHomeCancelState extends RemoteDebugHandler { + + @Override + public boolean canPublish(String sn) { + IDeviceRedisService deviceRedisService = SpringBeanUtilsTest.getBean(IDeviceRedisService.class); + return deviceRedisService.getDeviceOnline(sn) + .map(DeviceDTO::getChildDeviceSn) + .flatMap(deviceSn -> deviceRedisService.getDeviceOsd(deviceSn, OsdDockDrone.class)) + .map(osd -> DroneModeCodeEnum.RETURN_AUTO == osd.getModeCode()) + .orElse(false); + } + +} diff --git a/src/main/java/com/dji/sample/control/model/dto/ReturnHomeState.java b/src/main/java/com/dji/sample/control/model/dto/ReturnHomeState.java index 66957ab..a30f125 100644 --- a/src/main/java/com/dji/sample/control/model/dto/ReturnHomeState.java +++ b/src/main/java/com/dji/sample/control/model/dto/ReturnHomeState.java @@ -1,10 +1,11 @@ package com.dji.sample.control.model.dto; -import com.dji.sample.common.util.SpringBeanUtils; +import com.dji.sample.common.util.SpringBeanUtilsTest; import com.dji.sample.control.service.impl.RemoteDebugHandler; import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.receiver.OsdSubDeviceReceiver; import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.device.DroneModeCodeEnum; +import com.dji.sdk.cloudapi.device.OsdDockDrone; /** * @author sean @@ -16,12 +17,18 @@ public class ReturnHomeState extends RemoteDebugHandler { @Override public boolean canPublish(String sn) { - IDeviceRedisService deviceRedisService = SpringBeanUtils.getBean(IDeviceRedisService.class); + IDeviceRedisService deviceRedisService = SpringBeanUtilsTest.getBean(IDeviceRedisService.class); return deviceRedisService.getDeviceOnline(sn) .map(DeviceDTO::getChildDeviceSn) - .flatMap(deviceSn -> deviceRedisService.getDeviceOsd(deviceSn, OsdSubDeviceReceiver.class)) - .map(OsdSubDeviceReceiver::getElevation) - .map(elevation -> elevation > 0) + .flatMap(deviceSn -> deviceRedisService.getDeviceOsd(deviceSn, OsdDockDrone.class)) + .map(osd -> osd.getElevation() > 0 && modeCodeCanReturnHome(osd.getModeCode())) .orElse(false); } + + private boolean modeCodeCanReturnHome(DroneModeCodeEnum modeCode) { + return DroneModeCodeEnum.TAKEOFF_FINISHED == modeCode || DroneModeCodeEnum.TAKEOFF_AUTO == modeCode + || DroneModeCodeEnum.WAYLINE == modeCode || DroneModeCodeEnum.PANORAMIC_SHOT == modeCode + || DroneModeCodeEnum.ACTIVE_TRACK == modeCode || DroneModeCodeEnum.APAS == modeCode + || DroneModeCodeEnum.VIRTUAL_JOYSTICK == modeCode || DroneModeCodeEnum.MANUAL == modeCode; + } } diff --git a/src/main/java/com/dji/sample/control/model/dto/TakeoffProgressReceiver.java b/src/main/java/com/dji/sample/control/model/dto/TakeoffProgressReceiver.java deleted file mode 100644 index e4f5a83..0000000 --- a/src/main/java/com/dji/sample/control/model/dto/TakeoffProgressReceiver.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.dji.sample.control.model.dto; - -import com.dji.sample.control.model.enums.TakeoffStatusEnum; -import com.dji.sample.wayline.model.enums.WaylineErrorCodeEnum; -import lombok.Data; - -/** - * @author sean - * @version 1.4 - * @date 2023/3/14 - */ -@Data -public class TakeoffProgressReceiver { - - private WaylineErrorCodeEnum result; - - private TakeoffStatusEnum status; - - private String flightId; - - private String trackId; - - private Integer wayPointIndex; - -} diff --git a/src/main/java/com/dji/sample/control/model/enums/BatteryStoreModeEnum.java b/src/main/java/com/dji/sample/control/model/enums/BatteryStoreModeEnum.java deleted file mode 100644 index 9b3d0a8..0000000 --- a/src/main/java/com/dji/sample/control/model/enums/BatteryStoreModeEnum.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.dji.sample.control.model.enums; - -import lombok.Getter; - -import java.util.Arrays; -import java.util.Optional; - -/** - * @author sean - * @version 1.3 - * @date 2022/11/14 - */ -@Getter -public enum BatteryStoreModeEnum { - - PLAN(1), - - EMERGENCY(2); - - Integer mode; - - BatteryStoreModeEnum(Integer mode) { - this.mode = mode; - } - - public static Optional find(int mode) { - return Arrays.stream(BatteryStoreModeEnum.values()).filter(modeEnum -> modeEnum.mode == mode).findAny(); - } -} diff --git a/src/main/java/com/dji/sample/control/model/enums/CameraStateEnum.java b/src/main/java/com/dji/sample/control/model/enums/CameraStateEnum.java deleted file mode 100644 index fbe9f1a..0000000 --- a/src/main/java/com/dji/sample/control/model/enums/CameraStateEnum.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.control.model.enums; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -import java.util.Arrays; - -/** - * @author sean - * @version 1.4 - * @date 2023/4/23 - */ -public enum CameraStateEnum { - - IDLE, WORKING; - - @JsonValue - public int getVal() { - return ordinal(); - } - - @JsonCreator - public static CameraStateEnum find(int val) { - return Arrays.stream(values()).filter(stateEnum -> stateEnum.ordinal() == val).findAny().get(); - } -} diff --git a/src/main/java/com/dji/sample/control/model/enums/LinkWorkModeEnum.java b/src/main/java/com/dji/sample/control/model/enums/LinkWorkModeEnum.java deleted file mode 100644 index b54b0c3..0000000 --- a/src/main/java/com/dji/sample/control/model/enums/LinkWorkModeEnum.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.dji.sample.control.model.enums; - -import lombok.Getter; - -import java.util.Arrays; -import java.util.Optional; - -/** - * @author sean - * @version 1.3 - * @date 2022/11/25 - */ -@Getter -public enum LinkWorkModeEnum { - - SDR_ONLY(0), - - SDR_WITH_4G(1); - - int mode; - - LinkWorkModeEnum(Integer mode) { - this.mode = mode; - } - - public static Optional find(int mode) { - return Arrays.stream(LinkWorkModeEnum.values()).filter(modeEnum -> modeEnum.mode == mode).findAny(); - } -} diff --git a/src/main/java/com/dji/sample/control/model/enums/PayloadCommandsEnum.java b/src/main/java/com/dji/sample/control/model/enums/PayloadCommandsEnum.java index 1f1241f..6629f8c 100644 --- a/src/main/java/com/dji/sample/control/model/enums/PayloadCommandsEnum.java +++ b/src/main/java/com/dji/sample/control/model/enums/PayloadCommandsEnum.java @@ -1,6 +1,7 @@ package com.dji.sample.control.model.enums; import com.dji.sample.control.service.impl.*; +import com.dji.sdk.cloudapi.control.PayloadControlMethodEnum; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; @@ -13,40 +14,45 @@ import java.util.Arrays; */ public enum PayloadCommandsEnum { - CAMERA_MODE_SWitCH("camera_mode_switch", CameraModeSwitchImpl.class), + CAMERA_MODE_SWitCH(PayloadControlMethodEnum.CAMERA_MODE_SWITCH, CameraModeSwitchImpl.class), - CAMERA_PHOTO_TAKE("camera_photo_take", CameraPhotoTakeImpl.class), + CAMERA_PHOTO_TAKE(PayloadControlMethodEnum.CAMERA_PHOTO_TAKE, CameraPhotoTakeImpl.class), - CAMERA_RECORDING_START("camera_recording_start", CameraRecordingStartImpl.class), + CAMERA_RECORDING_START(PayloadControlMethodEnum.CAMERA_RECORDING_START, CameraRecordingStartImpl.class), - CAMERA_RECORDING_STOP("camera_recording_stop", CameraRecordingStopImpl.class), + CAMERA_RECORDING_STOP(PayloadControlMethodEnum.CAMERA_RECORDING_STOP, CameraRecordingStopImpl.class), - CAMERA_AIM("camera_aim", CameraAimImpl.class), + CAMERA_AIM(PayloadControlMethodEnum.CAMERA_AIM, CameraAimImpl.class), - CAMERA_FOCAL_LENGTH_SET("camera_focal_length_set", CameraFocalLengthSetImpl.class), + CAMERA_FOCAL_LENGTH_SET(PayloadControlMethodEnum.CAMERA_FOCAL_LENGTH_SET, CameraFocalLengthSetImpl.class), - GIMBAL_RESET("gimbal_reset", GimbalResetImpl.class); + GIMBAL_RESET(PayloadControlMethodEnum.GIMBAL_RESET, GimbalResetImpl.class); - String cmd; + PayloadControlMethodEnum cmd; Class clazz; - PayloadCommandsEnum(String cmd, Class clazz) { + PayloadCommandsEnum(PayloadControlMethodEnum cmd, Class clazz) { this.cmd = cmd; this.clazz = clazz; } @JsonValue - public String getCmd() { - return cmd; + public String getMethod() { + return cmd.getPayloadMethod().getMethod(); } public Class getClazz() { return clazz; } + public PayloadControlMethodEnum getCmd() { + return cmd; + } + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) - public static PayloadCommandsEnum find(String cmd) { - return Arrays.stream(values()).filter(cmdEnum -> cmdEnum.cmd.equals(cmd)).findAny().get(); + public static PayloadCommandsEnum find(String method) { + return Arrays.stream(values()).filter(methodEnum -> methodEnum.cmd.getPayloadMethod().getMethod().equals(method)).findAny() + .orElseThrow(); } } diff --git a/src/main/java/com/dji/sample/control/model/enums/RemoteDebugMethodEnum.java b/src/main/java/com/dji/sample/control/model/enums/RemoteDebugMethodEnum.java index 3bfed6e..b4b63f1 100644 --- a/src/main/java/com/dji/sample/control/model/enums/RemoteDebugMethodEnum.java +++ b/src/main/java/com/dji/sample/control/model/enums/RemoteDebugMethodEnum.java @@ -2,9 +2,12 @@ package com.dji.sample.control.model.enums; import com.dji.sample.control.model.dto.*; import com.dji.sample.control.service.impl.RemoteDebugHandler; +import com.dji.sdk.cloudapi.debug.DebugMethodEnum; +import com.fasterxml.jackson.annotation.JsonCreator; import lombok.Getter; import java.util.Arrays; +import java.util.Objects; /** * @author sean @@ -14,67 +17,80 @@ import java.util.Arrays; @Getter public enum RemoteDebugMethodEnum { - DEBUG_MODE_OPEN("debug_mode_open", false, RemoteDebugOpenState.class), + DEBUG_MODE_OPEN(DebugMethodEnum.DEBUG_MODE_OPEN, false, RemoteDebugOpenState.class), - DEBUG_MODE_CLOSE("debug_mode_close", false, null), + DEBUG_MODE_CLOSE(DebugMethodEnum.DEBUG_MODE_CLOSE, false, null), - SUPPLEMENT_LIGHT_OPEN("supplement_light_open", false, null), + SUPPLEMENT_LIGHT_OPEN(DebugMethodEnum.SUPPLEMENT_LIGHT_OPEN, false, null), - SUPPLEMENT_LIGHT_CLOSE("supplement_light_close", false, null), + SUPPLEMENT_LIGHT_CLOSE(DebugMethodEnum.SUPPLEMENT_LIGHT_CLOSE, false, null), RETURN_HOME("return_home", false, ReturnHomeState.class), - DEVICE_REBOOT("device_reboot", true, null), + RETURN_HOME_CANCEL("return_home_cancel", false, ReturnHomeCancelState.class), - DRONE_OPEN("drone_open", true, null), + DEVICE_REBOOT(DebugMethodEnum.DEVICE_REBOOT, true, null), - DRONE_CLOSE("drone_close", true, null), + DRONE_OPEN(DebugMethodEnum.DRONE_OPEN, true, null), - DEVICE_CHECK("device_check", true, null), + DRONE_CLOSE(DebugMethodEnum.DRONE_CLOSE, true, null), - DRONE_FORMAT("drone_format", true, null), + DRONE_FORMAT(DebugMethodEnum.DRONE_FORMAT, true, null), - DEVICE_FORMAT("device_format", true, null), + DEVICE_FORMAT(DebugMethodEnum.DEVICE_FORMAT, true, null), - COVER_OPEN("cover_open", true, null), + COVER_OPEN(DebugMethodEnum.COVER_OPEN, true, null), - COVER_CLOSE("cover_close", true, null), + COVER_CLOSE(DebugMethodEnum.COVER_CLOSE, true, null), - PUTTER_OPEN("putter_open", true, null), + PUTTER_OPEN(DebugMethodEnum.PUTTER_OPEN, true, null), - PUTTER_CLOSE("putter_close", true, null), + PUTTER_CLOSE(DebugMethodEnum.PUTTER_CLOSE, true, null), - CHARGE_OPEN("charge_open", true, null), + CHARGE_OPEN(DebugMethodEnum.CHARGE_OPEN, true, null), - CHARGE_CLOSE("charge_close", true, null), + CHARGE_CLOSE(DebugMethodEnum.CHARGE_CLOSE, true, null), - BATTERY_MAINTENANCE_SWITCH("battery_maintenance_switch", true, AlarmState.class), - - ALARM_STATE_SWITCH("alarm_state_switch", true, AlarmState.class), - - BATTERY_STORE_MODE_SWITCH("battery_store_mode_switch", true, BatteryStoreMode.class), + BATTERY_MAINTENANCE_SWITCH(DebugMethodEnum.BATTERY_MAINTENANCE_SWITCH, false, AlarmState.class), - SDR_WORK_MODE_SWITCH("sdr_workmode_switch", false, LinkWorkMode.class), + ALARM_STATE_SWITCH(DebugMethodEnum.ALARM_STATE_SWITCH, false, AlarmState.class), - UNKNOWN("unknown", false, null); + BATTERY_STORE_MODE_SWITCH(DebugMethodEnum.BATTERY_STORE_MODE_SWITCH, false, BatteryStoreMode.class), + + SDR_WORK_MODE_SWITCH(DebugMethodEnum.SDR_WORKMODE_SWITCH, false, LinkWorkMode.class), + + AIR_CONDITIONER_MODE_SWITCH(DebugMethodEnum.AIR_CONDITIONER_MODE_SWITCH, false, AirConditionerMode.class); + + private DebugMethodEnum debugMethodEnum; private String method; - private Boolean progress; + private boolean progress; private Class clazz; - RemoteDebugMethodEnum(String method, Boolean progress, Class clazz) { - this.method = method; + RemoteDebugMethodEnum(DebugMethodEnum debugMethodEnum, boolean progress, Class clazz) { + this.debugMethodEnum = debugMethodEnum; this.progress = progress; this.clazz = clazz; + this.method = debugMethodEnum.getMethod(); + } + + RemoteDebugMethodEnum(String method, boolean progress, Class clazz) { + this.debugMethodEnum = null; + this.progress = progress; + this.clazz = clazz; + this.method = method; } + @JsonCreator public static RemoteDebugMethodEnum find(String method) { - return Arrays.stream(RemoteDebugMethodEnum.values()) - .filter(methodEnum -> methodEnum.method.equals(method)) + return Arrays.stream(values()) + .filter(methodEnum -> methodEnum.method.equals(method) + || (Objects.nonNull(methodEnum.debugMethodEnum) + && methodEnum.debugMethodEnum.getMethod().equals(method))) .findAny() - .orElse(UNKNOWN); + .orElseThrow(); } } diff --git a/src/main/java/com/dji/sample/control/model/param/DrcModeParam.java b/src/main/java/com/dji/sample/control/model/param/DrcModeParam.java index a750dc5..d483da1 100644 --- a/src/main/java/com/dji/sample/control/model/param/DrcModeParam.java +++ b/src/main/java/com/dji/sample/control/model/param/DrcModeParam.java @@ -28,8 +28,10 @@ public class DrcModeParam { private String dockSn; @Range(min = 1800, max = 86400) + @Builder.Default private long expireSec = RedisConst.DRC_MODE_ALIVE_SECOND; @Valid + @Builder.Default private DeviceDrcInfoParam deviceInfo = new DeviceDrcInfoParam(); } diff --git a/src/main/java/com/dji/sample/control/model/param/DronePayloadParam.java b/src/main/java/com/dji/sample/control/model/param/DronePayloadParam.java index 97d156e..de9aa21 100644 --- a/src/main/java/com/dji/sample/control/model/param/DronePayloadParam.java +++ b/src/main/java/com/dji/sample/control/model/param/DronePayloadParam.java @@ -1,8 +1,8 @@ package com.dji.sample.control.model.param; -import com.dji.sample.control.model.enums.CameraModeEnum; -import com.dji.sample.control.model.enums.CameraTypeEnum; -import com.dji.sample.control.model.enums.GimbalResetModeEnum; +import com.dji.sdk.cloudapi.control.CameraTypeEnum; +import com.dji.sdk.cloudapi.control.GimbalResetModeEnum; +import com.dji.sdk.cloudapi.device.CameraModeEnum; import lombok.Data; import org.hibernate.validator.constraints.Range; diff --git a/src/main/java/com/dji/sample/control/model/param/FlyToPointParam.java b/src/main/java/com/dji/sample/control/model/param/FlyToPointParam.java index 98b03e1..d003c67 100644 --- a/src/main/java/com/dji/sample/control/model/param/FlyToPointParam.java +++ b/src/main/java/com/dji/sample/control/model/param/FlyToPointParam.java @@ -1,6 +1,6 @@ package com.dji.sample.control.model.param; -import com.dji.sample.control.model.dto.PointDTO; +import com.dji.sdk.cloudapi.control.Point; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -33,5 +33,5 @@ public class FlyToPointParam { @Size(min = 1) @Valid @NotNull - private List points; + private List points; } diff --git a/src/main/java/com/dji/sample/control/model/param/RemoteDebugParam.java b/src/main/java/com/dji/sample/control/model/param/RemoteDebugParam.java index 4d48659..8678d3a 100644 --- a/src/main/java/com/dji/sample/control/model/param/RemoteDebugParam.java +++ b/src/main/java/com/dji/sample/control/model/param/RemoteDebugParam.java @@ -2,6 +2,8 @@ package com.dji.sample.control.model.param; import lombok.Data; +import javax.validation.constraints.NotNull; + /** * @author sean * @version 1.3 @@ -10,6 +12,7 @@ import lombok.Data; @Data public class RemoteDebugParam { + @NotNull private Integer action; } diff --git a/src/main/java/com/dji/sample/control/model/param/TakeoffToPointParam.java b/src/main/java/com/dji/sample/control/model/param/TakeoffToPointParam.java index 4de1273..d2e79fc 100644 --- a/src/main/java/com/dji/sample/control/model/param/TakeoffToPointParam.java +++ b/src/main/java/com/dji/sample/control/model/param/TakeoffToPointParam.java @@ -1,10 +1,15 @@ package com.dji.sample.control.model.param; -import com.dji.sample.manage.model.enums.DroneRcLostActionEnum; -import com.dji.sample.manage.model.enums.WaylineRcLostActionEnum; +import com.dji.sdk.cloudapi.control.CommanderFlightModeEnum; +import com.dji.sdk.cloudapi.control.CommanderModeLostActionEnum; +import com.dji.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum; +import com.dji.sdk.cloudapi.device.RcLostActionEnum; +import com.dji.sdk.cloudapi.wayline.RthModeEnum; import lombok.Data; import org.hibernate.validator.constraints.Range; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; /** @@ -25,7 +30,7 @@ public class TakeoffToPointParam { @NotNull private Double targetLatitude; - @Range(min = 2, max = 1500) + @Range(min = 2, max = 10000) @NotNull private Double targetHeight; @@ -38,12 +43,22 @@ public class TakeoffToPointParam { private Double rthAltitude; @NotNull - private DroneRcLostActionEnum rcLostAction; + private RcLostActionEnum rcLostAction; @NotNull - private WaylineRcLostActionEnum exitWaylineWhenRcLost; + private ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost; @Range(min = 1, max = 15) @NotNull private Double maxSpeed; + + private RthModeEnum rthMode; + + private CommanderModeLostActionEnum commanderModeLostAction; + + private CommanderFlightModeEnum commanderFlightMode; + + @Min(2) + @Max(3000) + private Float commanderFlightHeight; } diff --git a/src/main/java/com/dji/sample/control/service/IControlService.java b/src/main/java/com/dji/sample/control/service/IControlService.java index f9e122b..d0a34ce 100644 --- a/src/main/java/com/dji/sample/control/service/IControlService.java +++ b/src/main/java/com/dji/sample/control/service/IControlService.java @@ -1,10 +1,9 @@ package com.dji.sample.control.service; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; import com.dji.sample.control.model.enums.DroneAuthorityEnum; +import com.dji.sample.control.model.enums.RemoteDebugMethodEnum; import com.dji.sample.control.model.param.*; -import org.springframework.messaging.MessageHeaders; +import com.dji.sdk.common.HttpResultResponse; /** * @author sean @@ -20,7 +19,7 @@ public interface IControlService { * @param param * @return */ - ResponseResult controlDockDebug(String sn, String serviceIdentifier, RemoteDebugParam param); + HttpResultResponse controlDockDebug(String sn, RemoteDebugMethodEnum serviceIdentifier, RemoteDebugParam param); /** * Make the drone fly to the target point. @@ -28,14 +27,14 @@ public interface IControlService { * @param param * @return */ - ResponseResult flyToPoint(String sn, FlyToPointParam param); + HttpResultResponse flyToPoint(String sn, FlyToPointParam param); /** * End the mission of flying the drone to the target point. * @param sn * @return */ - ResponseResult flyToPointStop(String sn); + HttpResultResponse flyToPointStop(String sn); /** * Handle progress result notifications for fly to target point. @@ -43,7 +42,7 @@ public interface IControlService { * @param headers * @return */ - CommonTopicReceiver handleFlyToPointProgress(CommonTopicReceiver receiver, MessageHeaders headers); +// CommonTopicReceiver handleFlyToPointProgress(CommonTopicReceiver receiver, MessageHeaders headers); /** * Control the drone to take off. @@ -51,15 +50,7 @@ public interface IControlService { * @param param * @return */ - ResponseResult takeoffToPoint(String sn, TakeoffToPointParam param); - - /** - * Handle progress result notifications for takeoff to target point. - * @param receiver - * @param headers - * @return - */ - CommonTopicReceiver handleTakeoffToPointProgress(CommonTopicReceiver receiver, MessageHeaders headers); + HttpResultResponse takeoffToPoint(String sn, TakeoffToPointParam param); /** * Seize the control authority of the drone or the payload control authority. @@ -68,12 +59,12 @@ public interface IControlService { * @param param * @return */ - ResponseResult seizeAuthority(String sn, DroneAuthorityEnum authority, DronePayloadParam param); + HttpResultResponse seizeAuthority(String sn, DroneAuthorityEnum authority, DronePayloadParam param); /** * Control the payload of the drone. * @param param * @return */ - ResponseResult payloadCommands(PayloadCommandsParam param) throws Exception; + HttpResultResponse payloadCommands(PayloadCommandsParam param) throws Exception; } diff --git a/src/main/java/com/dji/sample/control/service/IDrcService.java b/src/main/java/com/dji/sample/control/service/IDrcService.java index 505f526..55d0b75 100644 --- a/src/main/java/com/dji/sample/control/service/IDrcService.java +++ b/src/main/java/com/dji/sample/control/service/IDrcService.java @@ -1,9 +1,9 @@ package com.dji.sample.control.service; import com.dji.sample.control.model.dto.JwtAclDTO; -import com.dji.sample.control.model.dto.MqttBrokerDTO; import com.dji.sample.control.model.param.DrcConnectParam; import com.dji.sample.control.model.param.DrcModeParam; +import com.dji.sdk.cloudapi.control.DrcModeMqttBroker; /** * @author sean @@ -41,7 +41,7 @@ public interface IDrcService { * @param param * @return */ - MqttBrokerDTO userDrcAuth(String workspaceId, String userId, String username, DrcConnectParam param); + DrcModeMqttBroker userDrcAuth(String workspaceId, String userId, String username, DrcConnectParam param); /** * Make the dock enter drc mode. And grant relevant permissions. diff --git a/src/main/java/com/dji/sample/control/service/impl/CameraFocalLengthSetImpl.java b/src/main/java/com/dji/sample/control/service/impl/CameraFocalLengthSetImpl.java index d8b1450..e37f8a3 100644 --- a/src/main/java/com/dji/sample/control/service/impl/CameraFocalLengthSetImpl.java +++ b/src/main/java/com/dji/sample/control/service/impl/CameraFocalLengthSetImpl.java @@ -1,8 +1,8 @@ package com.dji.sample.control.service.impl; -import com.dji.sample.control.model.enums.CameraStateEnum; -import com.dji.sample.control.model.enums.CameraTypeEnum; import com.dji.sample.control.model.param.DronePayloadParam; +import com.dji.sdk.cloudapi.control.CameraTypeEnum; +import com.dji.sdk.cloudapi.device.CameraStateEnum; import java.util.Objects; @@ -32,7 +32,8 @@ public class CameraFocalLengthSetImpl extends PayloadCommandsHandler { } switch (param.getCameraType()) { case IR: - return param.getZoomFactor().intValue() != osdCamera.getIrZoomFactor(); + return Objects.nonNull(osdCamera.getIrZoomFactor()) + && param.getZoomFactor().intValue() != osdCamera.getIrZoomFactor(); case ZOOM: return param.getZoomFactor().intValue() != osdCamera.getZoomFactor(); } diff --git a/src/main/java/com/dji/sample/control/service/impl/CameraModeSwitchImpl.java b/src/main/java/com/dji/sample/control/service/impl/CameraModeSwitchImpl.java index b20dbf0..9d2db66 100644 --- a/src/main/java/com/dji/sample/control/service/impl/CameraModeSwitchImpl.java +++ b/src/main/java/com/dji/sample/control/service/impl/CameraModeSwitchImpl.java @@ -1,7 +1,7 @@ package com.dji.sample.control.service.impl; -import com.dji.sample.control.model.enums.CameraStateEnum; import com.dji.sample.control.model.param.DronePayloadParam; +import com.dji.sdk.cloudapi.device.CameraStateEnum; import java.util.Objects; diff --git a/src/main/java/com/dji/sample/control/service/impl/CameraPhotoTakeImpl.java b/src/main/java/com/dji/sample/control/service/impl/CameraPhotoTakeImpl.java index 79034b3..d9f6bcc 100644 --- a/src/main/java/com/dji/sample/control/service/impl/CameraPhotoTakeImpl.java +++ b/src/main/java/com/dji/sample/control/service/impl/CameraPhotoTakeImpl.java @@ -1,7 +1,7 @@ package com.dji.sample.control.service.impl; -import com.dji.sample.control.model.enums.CameraStateEnum; import com.dji.sample.control.model.param.DronePayloadParam; +import com.dji.sdk.cloudapi.device.CameraStateEnum; /** * @author sean diff --git a/src/main/java/com/dji/sample/control/service/impl/CameraRecordingStartImpl.java b/src/main/java/com/dji/sample/control/service/impl/CameraRecordingStartImpl.java index afe7f79..0a9960b 100644 --- a/src/main/java/com/dji/sample/control/service/impl/CameraRecordingStartImpl.java +++ b/src/main/java/com/dji/sample/control/service/impl/CameraRecordingStartImpl.java @@ -1,8 +1,8 @@ package com.dji.sample.control.service.impl; -import com.dji.sample.control.model.enums.CameraModeEnum; -import com.dji.sample.control.model.enums.CameraStateEnum; import com.dji.sample.control.model.param.DronePayloadParam; +import com.dji.sdk.cloudapi.device.CameraModeEnum; +import com.dji.sdk.cloudapi.device.CameraStateEnum; /** * @author sean diff --git a/src/main/java/com/dji/sample/control/service/impl/CameraRecordingStopImpl.java b/src/main/java/com/dji/sample/control/service/impl/CameraRecordingStopImpl.java index 929816b..22e59af 100644 --- a/src/main/java/com/dji/sample/control/service/impl/CameraRecordingStopImpl.java +++ b/src/main/java/com/dji/sample/control/service/impl/CameraRecordingStopImpl.java @@ -1,7 +1,7 @@ package com.dji.sample.control.service.impl; -import com.dji.sample.control.model.enums.CameraStateEnum; import com.dji.sample.control.model.param.DronePayloadParam; +import com.dji.sdk.cloudapi.device.CameraStateEnum; /** * @author sean diff --git a/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java b/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java index d9d43a7..530729e 100644 --- a/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java +++ b/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java @@ -1,35 +1,33 @@ package com.dji.sample.control.service.impl; -import com.dji.sample.common.error.CommonErrorEnum; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.IMessageSenderService; -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.dto.FlyToProgressReceiver; -import com.dji.sample.control.model.dto.ResultNotifyDTO; -import com.dji.sample.control.model.dto.TakeoffProgressReceiver; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; import com.dji.sample.control.model.enums.DroneAuthorityEnum; -import com.dji.sample.control.model.enums.DroneControlMethodEnum; import com.dji.sample.control.model.enums.RemoteDebugMethodEnum; import com.dji.sample.control.model.param.*; import com.dji.sample.control.service.IControlService; import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.enums.DeviceModeCodeEnum; -import com.dji.sample.manage.model.enums.DockModeCodeEnum; -import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.service.IDevicePayloadService; import com.dji.sample.manage.service.IDeviceRedisService; import com.dji.sample.manage.service.IDeviceService; -import com.dji.sample.wayline.model.enums.WaylineErrorCodeEnum; -import com.fasterxml.jackson.core.type.TypeReference; +import com.dji.sdk.cloudapi.control.FlyToPointRequest; +import com.dji.sdk.cloudapi.control.PayloadAuthorityGrabRequest; +import com.dji.sdk.cloudapi.control.TakeoffToPointRequest; +import com.dji.sdk.cloudapi.control.api.AbstractControlService; +import com.dji.sdk.cloudapi.debug.DebugMethodEnum; +import com.dji.sdk.cloudapi.debug.api.AbstractDebugService; +import com.dji.sdk.cloudapi.device.DockModeCodeEnum; +import com.dji.sdk.cloudapi.device.DroneModeCodeEnum; +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.cloudapi.wayline.api.AbstractWaylineService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; import com.fasterxml.jackson.databind.ObjectMapper; 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.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import java.util.Objects; @@ -46,10 +44,7 @@ import java.util.UUID; public class ControlServiceImpl implements IControlService { @Autowired - private IMessageSenderService messageSenderService; - - @Autowired - private ISendMessageService webSocketMessageService; + private IWebSocketMessageService webSocketMessageService; @Autowired private IDeviceService deviceService; @@ -63,6 +58,16 @@ public class ControlServiceImpl implements IControlService { @Autowired private IDevicePayloadService devicePayloadService; + @Autowired + private AbstractControlService abstractControlService; + + @Autowired + private AbstractDebugService abstractDebugService; + + @Autowired + @Qualifier("SDKWaylineService") + private AbstractWaylineService abstractWaylineService; + private RemoteDebugHandler checkDebugCondition(String sn, RemoteDebugParam param, RemoteDebugMethodEnum controlMethodEnum) { RemoteDebugHandler handler = Objects.nonNull(controlMethodEnum.getClazz()) ? mapper.convertValue(Objects.nonNull(param) ? param : new Object(), controlMethodEnum.getClazz()) @@ -70,81 +75,35 @@ public class ControlServiceImpl implements IControlService { if (!handler.canPublish(sn)) { throw new RuntimeException("The current state of the dock does not support this function."); } - if (Objects.nonNull(param) && !handler.valid()) { - throw new RuntimeException(CommonErrorEnum.ILLEGAL_ARGUMENT.getErrorMsg()); - } return handler; } @Override - public ResponseResult controlDockDebug(String sn, String serviceIdentifier, RemoteDebugParam param) { - RemoteDebugMethodEnum controlMethodEnum = RemoteDebugMethodEnum.find(serviceIdentifier); - if (RemoteDebugMethodEnum.UNKNOWN == controlMethodEnum) { - return ResponseResult.error("The " + serviceIdentifier + " method does not exist."); - } - + public HttpResultResponse controlDockDebug(String sn, RemoteDebugMethodEnum controlMethodEnum, RemoteDebugParam param) { + DebugMethodEnum methodEnum = controlMethodEnum.getDebugMethodEnum(); RemoteDebugHandler data = checkDebugCondition(sn, param, controlMethodEnum); boolean isExist = deviceRedisService.checkDeviceOnline(sn); if (!isExist) { - return ResponseResult.error("The dock is offline."); + return HttpResultResponse.error("The dock is offline."); } - String bid = UUID.randomUUID().toString(); - ServiceReply serviceReply = messageSenderService.publishServicesTopic(sn, serviceIdentifier, data, bid); - - if (ResponseResult.CODE_SUCCESS != serviceReply.getResult()) { - return ResponseResult.error(serviceReply.getResult(), - "error: " + serviceIdentifier + serviceReply.getResult()); - } - if (controlMethodEnum.getProgress()) { - RedisOpsUtils.setWithExpire(serviceIdentifier + RedisConst.DELIMITER + bid, sn, - RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND); - } - return ResponseResult.success(); - } - - /** - * Handles multi-state command progress information. - * @param receiver - * @param headers - * @return - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) - public CommonTopicReceiver handleControlProgress(CommonTopicReceiver receiver, MessageHeaders headers) { - String key = receiver.getMethod() + RedisConst.DELIMITER + receiver.getBid(); - if (RedisOpsUtils.getExpire(key) <= 0) { - return receiver; - } - String sn = RedisOpsUtils.get(key).toString(); - - EventsReceiver eventsReceiver = mapper.convertValue(receiver.getData(), - new TypeReference>(){}); - eventsReceiver.setBid(receiver.getBid()); - eventsReceiver.setSn(sn); - - log.info("SN: {}, {} ===> Control progress: {}", - sn, receiver.getMethod(), eventsReceiver.getOutput().getProgress().toString()); - - if (eventsReceiver.getResult() != ResponseResult.CODE_SUCCESS) { - log.error("SN: {}, {} ===> Error code: {}", sn, receiver.getMethod(), eventsReceiver.getResult()); - } - - if (eventsReceiver.getOutput().getProgress().getPercent() == 100 || - EventsResultStatusEnum.find(eventsReceiver.getOutput().getStatus()).getEnd()) { - RedisOpsUtils.del(key); + TopicServicesResponse response; + switch (controlMethodEnum) { + case RETURN_HOME: + response = abstractWaylineService.returnHome(SDKManager.getDeviceSDK(sn)); + break; + case RETURN_HOME_CANCEL: + response = abstractWaylineService.returnHomeCancel(SDKManager.getDeviceSDK(sn)); + break; + default: + response = abstractDebugService.remoteDebug(SDKManager.getDeviceSDK(sn), methodEnum, + Objects.nonNull(methodEnum.getClazz()) ? mapper.convertValue(data, methodEnum.getClazz()) : null); } - - Optional deviceOpt = deviceRedisService.getDeviceOnline(sn); - - if (deviceOpt.isEmpty()) { - throw new RuntimeException("The device is offline."); + ServicesReplyData serviceReply = (ServicesReplyData) response.getData(); + if (!serviceReply.getResult().isSuccess()) { + return HttpResultResponse.error(serviceReply.getResult()); } - - DeviceDTO device = deviceOpt.get(); - webSocketMessageService.sendBatch(device.getWorkspaceId(), UserTypeEnum.WEB.getVal(), - receiver.getMethod(), eventsReceiver); - - return receiver; + return HttpResultResponse.success(); } private void checkFlyToCondition(String dockSn) { @@ -154,55 +113,38 @@ public class ControlServiceImpl implements IControlService { throw new RuntimeException("The dock is offline, please restart the dock."); } - DeviceModeCodeEnum deviceMode = deviceService.getDeviceMode(dockOpt.get().getChildDeviceSn()); - if (DeviceModeCodeEnum.MANUAL != deviceMode) { + DroneModeCodeEnum deviceMode = deviceService.getDeviceMode(dockOpt.get().getChildDeviceSn()); + if (DroneModeCodeEnum.MANUAL != deviceMode) { throw new RuntimeException("The current state of the drone does not support this function, please try again later."); } - ResponseResult result = seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null); - if (ResponseResult.CODE_SUCCESS != result.getCode()) { + HttpResultResponse result = seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null); + if (HttpResultResponse.CODE_SUCCESS != result.getCode()) { throw new IllegalArgumentException(result.getMessage()); } } @Override - public ResponseResult flyToPoint(String sn, FlyToPointParam param) { + public HttpResultResponse flyToPoint(String sn, FlyToPointParam param) { checkFlyToCondition(sn); param.setFlyToId(UUID.randomUUID().toString()); - ServiceReply reply = messageSenderService.publishServicesTopic(sn, DroneControlMethodEnum.FLY_TO_POINT.getMethod(), param, param.getFlyToId()); - return ResponseResult.CODE_SUCCESS != reply.getResult() ? - ResponseResult.error("Flying to the target point failed." + reply.getResult()) - : ResponseResult.success(); + TopicServicesResponse response = abstractControlService.flyToPoint( + SDKManager.getDeviceSDK(sn), mapper.convertValue(param, FlyToPointRequest.class)); + ServicesReplyData reply = response.getData(); + return reply.getResult().isSuccess() ? + HttpResultResponse.success() + : HttpResultResponse.error("Flying to the target point failed. " + reply.getResult()); } @Override - public ResponseResult flyToPointStop(String sn) { - ServiceReply reply = messageSenderService.publishServicesTopic(sn, DroneControlMethodEnum.FLY_TO_POINT_STOP.getMethod(), null); - return ResponseResult.CODE_SUCCESS != reply.getResult() ? - ResponseResult.error("The drone flying to the target point failed to stop. " + reply.getResult()) - : ResponseResult.success(); - } - - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLY_TO_POINT_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) - public CommonTopicReceiver handleFlyToPointProgress(CommonTopicReceiver receiver, MessageHeaders headers) { - String dockSn = receiver.getGateway(); - - Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); - if (deviceOpt.isEmpty()) { - log.error("The dock is offline."); - return null; - } + public HttpResultResponse flyToPointStop(String sn) { + TopicServicesResponse response = abstractControlService.flyToPointStop(SDKManager.getDeviceSDK(sn)); + ServicesReplyData reply = response.getData(); - FlyToProgressReceiver eventsReceiver = mapper.convertValue(receiver.getData(), new TypeReference(){}); - webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), - BizCodeEnum.FLY_TO_POINT_PROGRESS.getCode(), - ResultNotifyDTO.builder().sn(dockSn) - .message(WaylineErrorCodeEnum.SUCCESS == eventsReceiver.getResult() ? - eventsReceiver.getStatus().getMessage() : eventsReceiver.getResult().getErrorMsg()) - .result(eventsReceiver.getResult().getErrorCode()) - .build()); - return receiver; + return reply.getResult().isSuccess() ? + HttpResultResponse.success() + : HttpResultResponse.error("The drone flying to the target point failed to stop. " + reply.getResult()); } private void checkTakeoffCondition(String dockSn) { @@ -211,69 +153,51 @@ public class ControlServiceImpl implements IControlService { throw new RuntimeException("The current state does not support takeoff."); } - ResponseResult result = seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null); - if (ResponseResult.CODE_SUCCESS != result.getCode()) { + HttpResultResponse result = seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null); + if (HttpResultResponse.CODE_SUCCESS != result.getCode()) { throw new IllegalArgumentException(result.getMessage()); } } @Override - public ResponseResult takeoffToPoint(String sn, TakeoffToPointParam param) { + public HttpResultResponse takeoffToPoint(String sn, TakeoffToPointParam param) { checkTakeoffCondition(sn); param.setFlightId(UUID.randomUUID().toString()); - ServiceReply reply = messageSenderService.publishServicesTopic(sn, DroneControlMethodEnum.TAKE_OFF_TO_POINT.getMethod(), param, param.getFlightId()); - return ResponseResult.CODE_SUCCESS != reply.getResult() ? - ResponseResult.error("The drone failed to take off. " + reply.getResult()) - : ResponseResult.success(); - } - - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_TAKE_OFF_TO_POINT_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) - public CommonTopicReceiver handleTakeoffToPointProgress(CommonTopicReceiver receiver, MessageHeaders headers) { - String dockSn = receiver.getGateway(); - - Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); - if (deviceOpt.isEmpty()) { - log.error("The dock is offline."); - return null; - } - TakeoffProgressReceiver eventsReceiver = mapper.convertValue(receiver.getData(), new TypeReference(){}); - - webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), - BizCodeEnum.TAKE_OFF_TO_POINT_PROGRESS.getCode(), - ResultNotifyDTO.builder().sn(dockSn) - .message(WaylineErrorCodeEnum.SUCCESS == eventsReceiver.getResult() ? - eventsReceiver.getStatus().getMessage() : eventsReceiver.getResult().getErrorMsg()) - .result(eventsReceiver.getResult().getErrorCode()) - .build()); - - return receiver; + TopicServicesResponse response = abstractControlService.takeoffToPoint( + SDKManager.getDeviceSDK(sn), mapper.convertValue(param, TakeoffToPointRequest.class)); + ServicesReplyData reply = response.getData(); + return reply.getResult().isSuccess() ? + HttpResultResponse.success() + : HttpResultResponse.error("The drone failed to take off. " + reply.getResult()); } @Override - public ResponseResult seizeAuthority(String sn, DroneAuthorityEnum authority, DronePayloadParam param) { - String method; + public HttpResultResponse seizeAuthority(String sn, DroneAuthorityEnum authority, DronePayloadParam param) { + TopicServicesResponse response; switch (authority) { case FLIGHT: if (deviceService.checkAuthorityFlight(sn)) { - return ResponseResult.success(); + return HttpResultResponse.success(); } - method = DroneControlMethodEnum.FLIGHT_AUTHORITY_GRAB.getMethod(); + response = abstractControlService.flightAuthorityGrab(SDKManager.getDeviceSDK(sn)); break; case PAYLOAD: if (checkPayloadAuthority(sn, param.getPayloadIndex())) { - return ResponseResult.success(); + return HttpResultResponse.success(); } - method = DroneControlMethodEnum.PAYLOAD_AUTHORITY_GRAB.getMethod(); + response = abstractControlService.payloadAuthorityGrab(SDKManager.getDeviceSDK(sn), + new PayloadAuthorityGrabRequest().setPayloadIndex(new PayloadIndex(param.getPayloadIndex()))); break; default: - return ResponseResult.error(CommonErrorEnum.ILLEGAL_ARGUMENT); + return HttpResultResponse.error(CloudSDKErrorEnum.INVALID_PARAMETER); } - ServiceReply serviceReply = messageSenderService.publishServicesTopic(sn, method, param); - return ResponseResult.CODE_SUCCESS != serviceReply.getResult() ? - ResponseResult.error(serviceReply.getResult(), "Method: " + method + " Error Code:" + serviceReply.getResult()) - : ResponseResult.success(); + + ServicesReplyData serviceReply = response.getData(); + return serviceReply.getResult().isSuccess() ? + HttpResultResponse.success() + : HttpResultResponse.error(serviceReply.getResult()); } private Boolean checkPayloadAuthority(String sn, String payloadIndex) { @@ -284,18 +208,20 @@ public class ControlServiceImpl implements IControlService { return devicePayloadService.checkAuthorityPayload(dockOpt.get().getChildDeviceSn(), payloadIndex); } - @Override - public ResponseResult payloadCommands(PayloadCommandsParam param) throws Exception { + public HttpResultResponse payloadCommands(PayloadCommandsParam param) throws Exception { param.getCmd().getClazz() .getDeclaredConstructor(DronePayloadParam.class) .newInstance(param.getData()) .checkCondition(param.getSn()); - ServiceReply serviceReply = messageSenderService.publishServicesTopic(param.getSn(), param.getCmd().getCmd(), param.getData()); - return ResponseResult.CODE_SUCCESS != serviceReply.getResult() ? - ResponseResult.error(serviceReply.getResult(), " Error Code:" + serviceReply.getResult()) - : ResponseResult.success(); - } + TopicServicesResponse response = abstractControlService.payloadControl( + SDKManager.getDeviceSDK(param.getSn()), param.getCmd().getCmd(), + mapper.convertValue(param.getData(), param.getCmd().getCmd().getClazz())); + ServicesReplyData serviceReply = response.getData(); + return serviceReply.getResult().isSuccess() ? + HttpResultResponse.success() + : HttpResultResponse.error(serviceReply.getResult()); + } } diff --git a/src/main/java/com/dji/sample/control/service/impl/DrcServiceImpl.java b/src/main/java/com/dji/sample/control/service/impl/DrcServiceImpl.java index 7e089cc..7aa86f3 100644 --- a/src/main/java/com/dji/sample/control/service/impl/DrcServiceImpl.java +++ b/src/main/java/com/dji/sample/control/service/impl/DrcServiceImpl.java @@ -1,16 +1,12 @@ package com.dji.sample.control.service.impl; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.config.MqttConfiguration; -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.IMessageSenderService; +import com.dji.sample.component.mqtt.config.MqttPropertyConfiguration; +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.mqtt.model.MapKeyConst; 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.dto.*; -import com.dji.sample.control.model.enums.DrcMethodEnum; -import com.dji.sample.control.model.enums.DrcStatusErrorEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.control.model.dto.JwtAclDTO; import com.dji.sample.control.model.enums.DroneAuthorityEnum; import com.dji.sample.control.model.enums.MqttAclAccessEnum; import com.dji.sample.control.model.param.DrcConnectParam; @@ -18,23 +14,29 @@ import com.dji.sample.control.model.param.DrcModeParam; import com.dji.sample.control.service.IControlService; import com.dji.sample.control.service.IDrcService; import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.enums.DockModeCodeEnum; -import com.dji.sample.manage.model.enums.UserTypeEnum; -import com.dji.sample.manage.model.receiver.OsdSubDeviceReceiver; import com.dji.sample.manage.service.IDeviceRedisService; import com.dji.sample.manage.service.IDeviceService; -import com.dji.sample.wayline.model.dto.WaylineTaskProgressReceiver; import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum; import com.dji.sample.wayline.model.enums.WaylineTaskStatusEnum; import com.dji.sample.wayline.model.param.UpdateJobParam; +import com.dji.sample.wayline.service.IFlightTaskService; import com.dji.sample.wayline.service.IWaylineJobService; import com.dji.sample.wayline.service.IWaylineRedisService; +import com.dji.sdk.cloudapi.control.DrcModeEnterRequest; +import com.dji.sdk.cloudapi.control.DrcModeMqttBroker; +import com.dji.sdk.cloudapi.control.api.AbstractControlService; +import com.dji.sdk.cloudapi.device.DockModeCodeEnum; +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.wayline.FlighttaskProgress; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.TopicConst; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; 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.util.StringUtils; @@ -52,15 +54,15 @@ import java.util.Optional; @Slf4j public class DrcServiceImpl implements IDrcService { - @Autowired - private IMessageSenderService messageSenderService; - @Autowired private ObjectMapper objectMapper; @Autowired private IWaylineJobService waylineJobService; + @Autowired + private IFlightTaskService flighttaskService; + @Autowired private IDeviceService deviceService; @@ -68,7 +70,7 @@ public class DrcServiceImpl implements IDrcService { private ObjectMapper mapper; @Autowired - private ISendMessageService webSocketMessageService; + private IWebSocketMessageService webSocketMessageService; @Autowired private IControlService controlService; @@ -79,6 +81,9 @@ public class DrcServiceImpl implements IDrcService { @Autowired private IWaylineRedisService waylineRedisService; + @Autowired + private AbstractControlService abstractControlService; + @Override public void setDrcModeInRedis(String dockSn, String clientId) { RedisOpsUtils.setWithExpire(RedisConst.DRC_PREFIX + dockSn, clientId, RedisConst.DRC_MODE_ALIVE_SECOND); @@ -95,7 +100,7 @@ public class DrcServiceImpl implements IDrcService { } @Override - public MqttBrokerDTO userDrcAuth(String workspaceId, String userId, String username, DrcConnectParam param) { + public DrcModeMqttBroker userDrcAuth(String workspaceId, String userId, String username, DrcConnectParam param) { // refresh token String clientId = param.getClientId(); @@ -110,7 +115,7 @@ public class DrcServiceImpl implements IDrcService { try { RedisOpsUtils.expireKey(key, RedisConst.DRC_MODE_ALIVE_SECOND); - return MqttConfiguration.getMqttBrokerWithDrc( + return MqttPropertyConfiguration.getMqttBrokerWithDrc( clientId, username, param.getExpireSec(), Collections.emptyMap()); } catch (RuntimeException e) { RedisOpsUtils.del(key); @@ -119,16 +124,16 @@ public class DrcServiceImpl implements IDrcService { } private void checkDrcModeCondition(String workspaceId, String dockSn) { - Optional> runningOpt = waylineRedisService.getRunningWaylineJob(dockSn); + Optional> runningOpt = waylineRedisService.getRunningWaylineJob(dockSn); if (runningOpt.isPresent() && WaylineJobStatusEnum.IN_PROGRESS == waylineJobService.getWaylineState(dockSn)) { - waylineJobService.updateJobStatus(workspaceId, runningOpt.get().getBid(), + flighttaskService.updateJobStatus(workspaceId, runningOpt.get().getBid(), UpdateJobParam.builder().status(WaylineTaskStatusEnum.PAUSE).build()); } DockModeCodeEnum dockMode = deviceService.getDockMode(dockSn); Optional dockOpt = deviceRedisService.getDeviceOnline(dockSn); if (dockOpt.isPresent() && (DockModeCodeEnum.IDLE == dockMode || DockModeCodeEnum.WORKING == dockMode)) { - Optional deviceOsd = deviceRedisService.getDeviceOsd(dockOpt.get().getChildDeviceSn(), OsdSubDeviceReceiver.class); + Optional deviceOsd = deviceRedisService.getDeviceOsd(dockOpt.get().getChildDeviceSn(), OsdDockDrone.class); if (deviceOsd.isEmpty() || deviceOsd.get().getElevation() <= 0) { throw new RuntimeException("The drone is not in the sky and cannot enter command flight mode."); } @@ -136,8 +141,8 @@ public class DrcServiceImpl implements IDrcService { throw new RuntimeException("The current state of the dock does not support entering command flight mode."); } - ResponseResult result = controlService.seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null); - if (ResponseResult.CODE_SUCCESS != result.getCode()) { + HttpResultResponse result = controlService.seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null); + if (HttpResultResponse.CODE_SUCCESS != result.getCode()) { throw new IllegalArgumentException(result.getMessage()); } @@ -158,19 +163,20 @@ public class DrcServiceImpl implements IDrcService { checkDrcModeCondition(workspaceId, param.getDockSn()); - ServiceReply reply = messageSenderService.publishServicesTopic( - param.getDockSn(), DrcMethodEnum.DRC_MODE_ENTER.getMethod(), - DrcModeDTO.builder() - .mqttBroker(MqttConfiguration.getMqttBrokerWithDrc(param.getDockSn() + "-" + System.currentTimeMillis(), param.getDockSn(), - RedisConst.DRC_MODE_ALIVE_SECOND.longValue(), - Map.of(MapKeyConst.ACL, objectMapper.convertValue(JwtAclDTO.builder() - .pub(List.of(subTopic)) - .sub(List.of(pubTopic)) - .build(), new TypeReference>() {})))) - .build()); - - if (ResponseResult.CODE_SUCCESS != reply.getResult()) { - throw new RuntimeException("SN: " + param.getDockSn() + "; Error Code:" + reply.getResult() + "; Failed to enter command flight control mode, please try again later!"); + TopicServicesResponse reply = abstractControlService.drcModeEnter( + SDKManager.getDeviceSDK(param.getDockSn()), + new DrcModeEnterRequest() + .setMqttBroker(MqttPropertyConfiguration.getMqttBrokerWithDrc(param.getDockSn() + "-" + System.currentTimeMillis(), param.getDockSn(), + RedisConst.DRC_MODE_ALIVE_SECOND.longValue(), + Map.of(MapKeyConst.ACL, objectMapper.convertValue(JwtAclDTO.builder() + .pub(List.of(subTopic)) + .sub(List.of(pubTopic)) + .build(), new TypeReference>() {})))) + .setHsiFrequency(1).setOsdFrequency(10)); + + if (!reply.getData().getResult().isSuccess()) { + throw new RuntimeException("SN: " + param.getDockSn() + "; Error:" + reply.getData().getResult() + + "; Failed to enter command flight control mode, please try again later!"); } refreshAcl(param.getDockSn(), param.getClientId(), pubTopic, subTopic); @@ -185,6 +191,7 @@ public class DrcServiceImpl implements IDrcService { String key = RedisConst.MQTT_ACL_PREFIX + clientId; RedisOpsUtils.hashSet(key, pubTopic, MqttAclAccessEnum.PUB.getValue()); RedisOpsUtils.hashSet(key, subTopic, MqttAclAccessEnum.SUB.getValue()); + RedisOpsUtils.expireKey(key, RedisConst.DRC_MODE_ALIVE_SECOND); } @Override @@ -192,58 +199,20 @@ public class DrcServiceImpl implements IDrcService { if (!deviceService.checkDockDrcMode(param.getDockSn())) { throw new RuntimeException("The dock is not in flight control mode."); } - ServiceReply reply = messageSenderService.publishServicesTopic( - param.getDockSn(), DrcMethodEnum.DRC_MODE_EXIT.getMethod(), ""); - if (ResponseResult.CODE_SUCCESS != reply.getResult()) { - throw new RuntimeException("SN: " + param.getDockSn() + "; Error Code:" + - reply.getResult() + "; Failed to exit command flight control mode, please try again later!"); + TopicServicesResponse reply = + abstractControlService.drcModeExit(SDKManager.getDeviceSDK(param.getDockSn())); + if (!reply.getData().getResult().isSuccess()) { + throw new RuntimeException("SN: " + param.getDockSn() + "; Error:" + + reply.getData().getResult() + "; Failed to exit command flight control mode, please try again later!"); } String jobId = waylineRedisService.getPausedWaylineJobId(param.getDockSn()); if (StringUtils.hasText(jobId)) { - waylineJobService.updateJobStatus(workspaceId, jobId, UpdateJobParam.builder().status(WaylineTaskStatusEnum.RESUME).build()); + flighttaskService.updateJobStatus(workspaceId, jobId, UpdateJobParam.builder().status(WaylineTaskStatusEnum.RESUME).build()); } this.delDrcModeInRedis(param.getDockSn()); RedisOpsUtils.del(RedisConst.MQTT_ACL_PREFIX + param.getClientId()); } - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_DRC_STATUS_NOTIFY, outputChannel = ChannelName.OUTBOUND_EVENTS) - public CommonTopicReceiver handleDrcStatusNotify(CommonTopicReceiver receiver, MessageHeaders headers) { - String dockSn = receiver.getGateway(); - - Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); - if (deviceOpt.isEmpty()) { - return null; - } - - DrcStatusNotifyReceiver eventsReceiver = mapper.convertValue(receiver.getData(), new TypeReference(){}); - if (DrcStatusErrorEnum.SUCCESS != eventsReceiver.getResult()) { - webSocketMessageService.sendBatch( - deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), BizCodeEnum.DRC_STATUS_NOTIFY.getCode(), - ResultNotifyDTO.builder().sn(dockSn) - .message(eventsReceiver.getResult().getErrorMsg()) - .result(eventsReceiver.getResult().getErrorCode()).build()); - } - return receiver; - } - - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_DRC_MODE_EXIT_NOTIFY, outputChannel = ChannelName.OUTBOUND_EVENTS) - public CommonTopicReceiver handleDrcModeExitNotify(CommonTopicReceiver receiver, MessageHeaders headers) { - String dockSn = receiver.getGateway(); - - Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); - if (deviceOpt.isEmpty()) { - return null; - } - - DrcModeReasonReceiver eventsReceiver = mapper.convertValue(receiver.getData(), new TypeReference(){}); - webSocketMessageService.sendBatch( - deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), BizCodeEnum.JOYSTICK_INVALID_NOTIFY.getCode(), - ResultNotifyDTO.builder().sn(dockSn) - .message(eventsReceiver.getReason().getMessage()) - .result(eventsReceiver.getReason().getVal()).build()); - return receiver; - } - } diff --git a/src/main/java/com/dji/sample/control/service/impl/PayloadCommandsHandler.java b/src/main/java/com/dji/sample/control/service/impl/PayloadCommandsHandler.java index c0eeee6..46d8bd9 100644 --- a/src/main/java/com/dji/sample/control/service/impl/PayloadCommandsHandler.java +++ b/src/main/java/com/dji/sample/control/service/impl/PayloadCommandsHandler.java @@ -1,12 +1,12 @@ package com.dji.sample.control.service.impl; -import com.dji.sample.common.util.SpringBeanUtils; +import com.dji.sample.common.util.SpringBeanUtilsTest; import com.dji.sample.control.model.param.DronePayloadParam; import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.receiver.OsdCameraReceiver; -import com.dji.sample.manage.model.receiver.OsdSubDeviceReceiver; import com.dji.sample.manage.service.IDevicePayloadService; import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.device.OsdCamera; +import com.dji.sdk.cloudapi.device.OsdDockDrone; import java.util.Optional; @@ -19,7 +19,7 @@ public abstract class PayloadCommandsHandler { DronePayloadParam param; - OsdCameraReceiver osdCamera; + OsdCamera osdCamera; PayloadCommandsHandler(DronePayloadParam param) { this.param = param; @@ -30,20 +30,20 @@ public abstract class PayloadCommandsHandler { } public boolean canPublish(String deviceSn) { - Optional deviceOpt = SpringBeanUtils.getBean(IDeviceRedisService.class) - .getDeviceOsd(deviceSn, OsdSubDeviceReceiver.class); + Optional deviceOpt = SpringBeanUtilsTest.getBean(IDeviceRedisService.class) + .getDeviceOsd(deviceSn, OsdDockDrone.class); if (deviceOpt.isEmpty()) { throw new RuntimeException("The device is offline."); } osdCamera = deviceOpt.get().getCameras().stream() - .filter(osdCamera -> param.getPayloadIndex().equals(osdCamera.getPayloadIndex())) + .filter(osdCamera -> param.getPayloadIndex().equals(osdCamera.getPayloadIndex().toString())) .findAny() .orElseThrow(() -> new RuntimeException("Did not receive osd information about the camera, please check the cache data.")); return true; } private String checkDockOnline(String dockSn) { - Optional deviceOpt = SpringBeanUtils.getBean(IDeviceRedisService.class).getDeviceOnline(dockSn); + Optional deviceOpt = SpringBeanUtilsTest.getBean(IDeviceRedisService.class).getDeviceOnline(dockSn); if (deviceOpt.isEmpty()) { throw new RuntimeException("The dock is offline."); } @@ -51,14 +51,14 @@ public abstract class PayloadCommandsHandler { } private void checkDeviceOnline(String deviceSn) { - boolean isOnline = SpringBeanUtils.getBean(IDeviceRedisService.class).checkDeviceOnline(deviceSn); + boolean isOnline = SpringBeanUtilsTest.getBean(IDeviceRedisService.class).checkDeviceOnline(deviceSn); if (!isOnline) { throw new RuntimeException("The device is offline."); } } private void checkAuthority(String deviceSn) { - boolean hasAuthority = SpringBeanUtils.getBean(IDevicePayloadService.class) + boolean hasAuthority = SpringBeanUtilsTest.getBean(IDevicePayloadService.class) .checkAuthorityPayload(deviceSn, param.getPayloadIndex()); if (!hasAuthority) { throw new RuntimeException("The device does not have payload control authority."); diff --git a/src/main/java/com/dji/sample/control/service/impl/RemoteDebugHandler.java b/src/main/java/com/dji/sample/control/service/impl/RemoteDebugHandler.java index ed33e51..5da1688 100644 --- a/src/main/java/com/dji/sample/control/service/impl/RemoteDebugHandler.java +++ b/src/main/java/com/dji/sample/control/service/impl/RemoteDebugHandler.java @@ -1,8 +1,8 @@ package com.dji.sample.control.service.impl; -import com.dji.sample.common.util.SpringBeanUtils; -import com.dji.sample.manage.model.enums.DockModeCodeEnum; +import com.dji.sample.common.util.SpringBeanUtilsTest; import com.dji.sample.manage.service.IDeviceService; +import com.dji.sdk.cloudapi.device.DockModeCodeEnum; /** * @author sean @@ -12,11 +12,11 @@ import com.dji.sample.manage.service.IDeviceService; public class RemoteDebugHandler { public boolean valid() { - return false; + return true; } public boolean canPublish(String sn) { - IDeviceService deviceService = SpringBeanUtils.getBean(IDeviceService.class); + IDeviceService deviceService = SpringBeanUtilsTest.getBean(IDeviceService.class); DockModeCodeEnum dockMode = deviceService.getDockMode(sn); return DockModeCodeEnum.REMOTE_DEBUGGING == dockMode; } diff --git a/src/main/java/com/dji/sample/control/service/impl/SDKControlService.java b/src/main/java/com/dji/sample/control/service/impl/SDKControlService.java new file mode 100644 index 0000000..7878261 --- /dev/null +++ b/src/main/java/com/dji/sample/control/service/impl/SDKControlService.java @@ -0,0 +1,118 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.control.model.dto.ResultNotifyDTO; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.control.*; +import com.dji.sdk.cloudapi.control.api.AbstractControlService; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/4 + */ +@Service +@Slf4j +public class SDKControlService extends AbstractControlService { + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private ObjectMapper mapper; + + @Override + public TopicEventsResponse flyToPointProgress(TopicEventsRequest request, MessageHeaders headers) { + String dockSn = request.getGateway(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); + if (deviceOpt.isEmpty()) { + log.error("The dock is offline."); + return null; + } + + FlyToPointProgress eventsReceiver = request.getData(); + webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.FLY_TO_POINT_PROGRESS.getCode(), + ResultNotifyDTO.builder().sn(dockSn) + .message(eventsReceiver.getResult().toString()) + .result(eventsReceiver.getResult().getCode()) + .build()); + return new TopicEventsResponse().setData(MqttReply.success()); + } + + @Override + public TopicEventsResponse takeoffToPointProgress(TopicEventsRequest request, MessageHeaders headers) { + String dockSn = request.getGateway(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); + if (deviceOpt.isEmpty()) { + log.error("The dock is offline."); + return null; + } + + TakeoffToPointProgress eventsReceiver = request.getData(); + webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.TAKE_OFF_TO_POINT_PROGRESS.getCode(), + ResultNotifyDTO.builder().sn(dockSn) + .message(eventsReceiver.getResult().toString()) + .result(eventsReceiver.getResult().getCode()) + .build()); + + return new TopicEventsResponse().setData(MqttReply.success()); + } + + @Override + public TopicEventsResponse drcStatusNotify(TopicEventsRequest request, MessageHeaders headers) { + String dockSn = request.getGateway(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); + if (deviceOpt.isEmpty()) { + return null; + } + + DrcStatusNotify eventsReceiver = request.getData(); + if (DrcStatusErrorEnum.SUCCESS != eventsReceiver.getResult()) { + webSocketMessageService.sendBatch( + deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), BizCodeEnum.DRC_STATUS_NOTIFY.getCode(), + ResultNotifyDTO.builder().sn(dockSn) + .message(eventsReceiver.getResult().getMessage()) + .result(eventsReceiver.getResult().getCode()).build()); + } + return new TopicEventsResponse().setData(MqttReply.success()); + } + + @Override + public TopicEventsResponse joystickInvalidNotify(TopicEventsRequest request, MessageHeaders headers) { + String dockSn = request.getGateway(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); + if (deviceOpt.isEmpty()) { + return null; + } + + JoystickInvalidNotify eventsReceiver = request.getData(); + webSocketMessageService.sendBatch( + deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), BizCodeEnum.JOYSTICK_INVALID_NOTIFY.getCode(), + ResultNotifyDTO.builder().sn(dockSn) + .message(eventsReceiver.getReason().getMessage()) + .result(eventsReceiver.getReason().getVal()).build()); + return new TopicEventsResponse().setData(MqttReply.success()); + } +} diff --git a/src/main/java/com/dji/sample/control/service/impl/SDKRemoteDebug.java b/src/main/java/com/dji/sample/control/service/impl/SDKRemoteDebug.java new file mode 100644 index 0000000..41f5f94 --- /dev/null +++ b/src/main/java/com/dji/sample/control/service/impl/SDKRemoteDebug.java @@ -0,0 +1,63 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.debug.RemoteDebugProgress; +import com.dji.sdk.cloudapi.debug.api.AbstractDebugService; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/4 + */ +@Service +@Slf4j +public class SDKRemoteDebug extends AbstractDebugService { + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Override + public TopicEventsResponse remoteDebugProgress(TopicEventsRequest> request, MessageHeaders headers) { + String sn = request.getGateway(); + + EventsReceiver eventsReceiver = new EventsReceiver() + .setOutput(request.getData().getOutput()).setResult(request.getData().getResult()); + eventsReceiver.setBid(request.getBid()); + eventsReceiver.setSn(sn); + + log.info("SN: {}, {} ===> Control progress: {}", sn, request.getMethod(), eventsReceiver.getOutput().getProgress()); + + if (!eventsReceiver.getResult().isSuccess()) { + log.error("SN: {}, {} ===> Error: {}", sn, request.getMethod(), eventsReceiver.getResult()); + } + + Optional deviceOpt = deviceRedisService.getDeviceOnline(sn); + + if (deviceOpt.isEmpty()) { + throw new RuntimeException("The device is offline."); + } + + DeviceDTO device = deviceOpt.get(); + webSocketMessageService.sendBatch(device.getWorkspaceId(), UserTypeEnum.WEB.getVal(), + request.getMethod(), eventsReceiver); + + return new TopicEventsResponse().setData(MqttReply.success()); + } +} diff --git a/src/main/java/com/dji/sample/manage/controller/DeviceController.java b/src/main/java/com/dji/sample/manage/controller/DeviceController.java index 9fcc72d..7a0a7ed 100644 --- a/src/main/java/com/dji/sample/manage/controller/DeviceController.java +++ b/src/main/java/com/dji/sample/manage/controller/DeviceController.java @@ -1,20 +1,15 @@ package com.dji.sample.manage.controller; -import com.dji.sample.common.error.CommonErrorEnum; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.ChannelName; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.component.mqtt.model.CommonTopicResponse; import com.dji.sample.manage.model.dto.DeviceDTO; import com.dji.sample.manage.model.dto.DeviceFirmwareUpgradeDTO; -import com.dji.sample.manage.model.enums.DeviceSetPropertyEnum; -import com.dji.sample.manage.model.receiver.StatusGatewayReceiver; import com.dji.sample.manage.service.IDeviceService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.mqtt.property.PropertySetReplyResultEnum; import com.fasterxml.jackson.databind.JsonNode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -33,56 +28,16 @@ public class DeviceController { @Autowired private IDeviceService deviceService; - /** - * Handles the message that the drone goes online. - * @param receiver The drone information is not empty. - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_STATUS_ONLINE, outputChannel = ChannelName.OUTBOUND) - public void deviceOnline(CommonTopicReceiver receiver) { - boolean online = deviceService.deviceOnline(receiver.getData()); - if (online) { - // Notify pilot that the drone is online successfully. - deviceService.publishStatusReply(receiver.getData().getSn(), - CommonTopicResponse.builder() - .tid(receiver.getTid()) - .bid(receiver.getBid()) - .timestamp(System.currentTimeMillis()) - .method(receiver.getMethod()) - .build()); - } - } - - /** - * Handles the message that the drone goes offline. - * @param receiver The drone information is empty. - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_STATUS_OFFLINE, outputChannel = ChannelName.OUTBOUND) - public void deviceOffline(CommonTopicReceiver receiver) { - - boolean offline = deviceService.deviceOffline(receiver.getData()); - if (offline) { - // Notify pilot that the device is offline successfully. - deviceService.publishStatusReply(receiver.getData().getSn(), - CommonTopicResponse.builder() - .tid(receiver.getTid()) - .bid(receiver.getBid()) - .timestamp(System.currentTimeMillis()) - .method(receiver.getMethod()) - .build()); - - } - } - /** * Get the topology list of all online devices in one workspace. * @param workspaceId * @return */ @GetMapping("/{workspace_id}/devices") - public ResponseResult> getDevices(@PathVariable("workspace_id") String workspaceId) { + public HttpResultResponse> getDevices(@PathVariable("workspace_id") String workspaceId) { List devicesList = deviceService.getDevicesTopoForWeb(workspaceId); - return ResponseResult.success(devicesList); + return HttpResultResponse.success(devicesList); } /** @@ -92,10 +47,10 @@ public class DeviceController { * @return */ @PostMapping("/{device_sn}/binding") - public ResponseResult bindDevice(@RequestBody DeviceDTO device, @PathVariable("device_sn") String deviceSn) { + public HttpResultResponse bindDevice(@RequestBody DeviceDTO device, @PathVariable("device_sn") String deviceSn) { device.setDeviceSn(deviceSn); boolean isUpd = deviceService.bindDevice(device); - return isUpd ? ResponseResult.success() : ResponseResult.error(); + return isUpd ? HttpResultResponse.success() : HttpResultResponse.error(); } /** @@ -105,10 +60,10 @@ public class DeviceController { * @return */ @GetMapping("/{workspace_id}/devices/{device_sn}") - public ResponseResult getDevice(@PathVariable("workspace_id") String workspaceId, - @PathVariable("device_sn") String deviceSn) { + public HttpResultResponse getDevice(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn) { Optional deviceOpt = deviceService.getDeviceBySn(deviceSn); - return deviceOpt.isEmpty() ? ResponseResult.error("device not found.") : ResponseResult.success(deviceOpt.get()); + return deviceOpt.isEmpty() ? HttpResultResponse.error("device not found.") : HttpResultResponse.success(deviceOpt.get()); } /** @@ -119,13 +74,13 @@ public class DeviceController { * @return */ @GetMapping("/{workspace_id}/devices/bound") - public ResponseResult> getBoundDevicesWithDomain( + public HttpResultResponse> getBoundDevicesWithDomain( @PathVariable("workspace_id") String workspaceId, Integer domain, @RequestParam(defaultValue = "1") Long page, @RequestParam(value = "page_size", defaultValue = "50") Long pageSize) { PaginationData devices = deviceService.getBoundDevicesWithDomain(workspaceId, page, pageSize, domain); - return ResponseResult.success(devices); + return HttpResultResponse.success(devices); } /** @@ -134,9 +89,9 @@ public class DeviceController { * @return */ @DeleteMapping("/{device_sn}/unbinding") - public ResponseResult unbindingDevice(@PathVariable("device_sn") String deviceSn) { + public HttpResultResponse unbindingDevice(@PathVariable("device_sn") String deviceSn) { deviceService.unbindDevice(deviceSn); - return ResponseResult.success(); + return HttpResultResponse.success(); } /** @@ -147,12 +102,12 @@ public class DeviceController { * @return */ @PutMapping("/{workspace_id}/devices/{device_sn}") - public ResponseResult updateDevice(@RequestBody DeviceDTO device, - @PathVariable("workspace_id") String workspaceId, - @PathVariable("device_sn") String deviceSn) { + public HttpResultResponse updateDevice(@RequestBody DeviceDTO device, + @PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn) { device.setDeviceSn(deviceSn); boolean isUpd = deviceService.updateDevice(device); - return isUpd ? ResponseResult.success() : ResponseResult.error(); + return isUpd ? HttpResultResponse.success() : HttpResultResponse.error(); } /** @@ -162,8 +117,8 @@ public class DeviceController { * @return */ @PostMapping("/{workspace_id}/devices/ota") - public ResponseResult createOtaJob(@PathVariable("workspace_id") String workspaceId, - @RequestBody List upgradeDTOS) { + public HttpResultResponse createOtaJob(@PathVariable("workspace_id") String workspaceId, + @RequestBody List upgradeDTOS) { return deviceService.createDeviceOtaJob(workspaceId, upgradeDTOS); } @@ -175,18 +130,15 @@ public class DeviceController { * @return */ @PutMapping("/{workspace_id}/devices/{device_sn}/property") - public ResponseResult devicePropertySet(@PathVariable("workspace_id") String workspaceId, - @PathVariable("device_sn") String dockSn, - @RequestBody JsonNode param) { + public HttpResultResponse devicePropertySet(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String dockSn, + @RequestBody JsonNode param) { if (param.size() != 1) { - return ResponseResult.error(CommonErrorEnum.ILLEGAL_ARGUMENT); - } - String property = param.fieldNames().next(); - Optional propertyEnumOpt = DeviceSetPropertyEnum.find(property); - if (propertyEnumOpt.isEmpty()) { - return ResponseResult.error(CommonErrorEnum.ILLEGAL_ARGUMENT); + return HttpResultResponse.error(CloudSDKErrorEnum.INVALID_PARAMETER); } - deviceService.devicePropertySet(workspaceId, dockSn, propertyEnumOpt.get(), param.get(property)); - return ResponseResult.success(); + + int result = deviceService.devicePropertySet(workspaceId, dockSn, param); + return PropertySetReplyResultEnum.SUCCESS.getResult() == result ? + HttpResultResponse.success() : HttpResultResponse.error(result, String.valueOf(result)); } } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/controller/DeviceFirmwareController.java b/src/main/java/com/dji/sample/manage/controller/DeviceFirmwareController.java index 45a2770..6425bbb 100644 --- a/src/main/java/com/dji/sample/manage/controller/DeviceFirmwareController.java +++ b/src/main/java/com/dji/sample/manage/controller/DeviceFirmwareController.java @@ -1,8 +1,6 @@ package com.dji.sample.manage.controller; import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.manage.model.dto.DeviceFirmwareDTO; import com.dji.sample.manage.model.dto.DeviceFirmwareNoteDTO; import com.dji.sample.manage.model.dto.FirmwareFileProperties; @@ -10,6 +8,8 @@ import com.dji.sample.manage.model.param.DeviceFirmwareQueryParam; import com.dji.sample.manage.model.param.DeviceFirmwareUpdateParam; import com.dji.sample.manage.model.param.DeviceFirmwareUploadParam; import com.dji.sample.manage.service.IDeviceFirmwareService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -43,7 +43,7 @@ public class DeviceFirmwareController { * @return */ @GetMapping("/firmware-release-notes/latest") - public ResponseResult> getLatestFirmwareNote(@RequestParam("device_name") List deviceNames) { + public HttpResultResponse> getLatestFirmwareNote(@RequestParam("device_name") List deviceNames) { List releaseNotes = deviceNames.stream() .map(deviceName -> service.getLatestFirmwareReleaseNote(deviceName)) @@ -51,7 +51,7 @@ public class DeviceFirmwareController { .map(Optional::get) .collect(Collectors.toList()); - return ResponseResult.success(releaseNotes); + return HttpResultResponse.success(releaseNotes); } /** @@ -61,11 +61,11 @@ public class DeviceFirmwareController { * @return */ @GetMapping("/{workspace_id}/firmwares") - public ResponseResult> getAllFirmwarePagination( + public HttpResultResponse> getAllFirmwarePagination( @PathVariable("workspace_id") String workspaceId, @Valid DeviceFirmwareQueryParam param) { PaginationData data = service.getAllFirmwarePagination(workspaceId, param); - return ResponseResult.success(data); + return HttpResultResponse.success(data); } /** @@ -77,19 +77,19 @@ public class DeviceFirmwareController { * @return */ @PostMapping("/{workspace_id}/firmwares/file/upload") - public ResponseResult importFirmwareFile(HttpServletRequest request, @PathVariable("workspace_id") String workspaceId, - @NotNull(message = "No file received.") MultipartFile file, - @Valid DeviceFirmwareUploadParam param) { + public HttpResultResponse importFirmwareFile(HttpServletRequest request, @PathVariable("workspace_id") String workspaceId, + @NotNull(message = "No file received.") MultipartFile file, + @Valid DeviceFirmwareUploadParam param) { if (!file.getOriginalFilename().endsWith(FirmwareFileProperties.FIRMWARE_FILE_SUFFIX)) { - return ResponseResult.error("The file format is incorrect."); + return HttpResultResponse.error("The file format is incorrect."); } CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); String creator = customClaim.getUsername(); service.importFirmwareFile(workspaceId, creator, param, file); - return ResponseResult.success(); + return HttpResultResponse.success(); } /** @@ -100,13 +100,13 @@ public class DeviceFirmwareController { * @return */ @PutMapping("/{workspace_id}/firmwares/{firmware_id}") - public ResponseResult changeFirmwareStatus(@PathVariable("workspace_id") String workspaceId, - @PathVariable("firmware_id") String firmwareId, - @Valid @RequestBody DeviceFirmwareUpdateParam param) { + public HttpResultResponse changeFirmwareStatus(@PathVariable("workspace_id") String workspaceId, + @PathVariable("firmware_id") String firmwareId, + @Valid @RequestBody DeviceFirmwareUpdateParam param) { service.updateFirmwareInfo(DeviceFirmwareDTO.builder() .firmwareId(firmwareId).firmwareStatus(param.getStatus()).build()); - return ResponseResult.success(); + return HttpResultResponse.success(); } diff --git a/src/main/java/com/dji/sample/manage/controller/DeviceHmsController.java b/src/main/java/com/dji/sample/manage/controller/DeviceHmsController.java index 0035d5f..7ded209 100644 --- a/src/main/java/com/dji/sample/manage/controller/DeviceHmsController.java +++ b/src/main/java/com/dji/sample/manage/controller/DeviceHmsController.java @@ -1,10 +1,10 @@ package com.dji.sample.manage.controller; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.manage.model.dto.DeviceHmsDTO; import com.dji.sample.manage.model.param.DeviceHmsQueryParam; import com.dji.sample.manage.service.IDeviceHmsService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -34,11 +34,11 @@ public class DeviceHmsController { * @return */ @GetMapping("/{workspace_id}/devices/hms") - public ResponseResult> getHmsInformation(DeviceHmsQueryParam param, - @PathVariable("workspace_id") String workspaceId) { + public HttpResultResponse> getHmsInformation(DeviceHmsQueryParam param, + @PathVariable("workspace_id") String workspaceId) { PaginationData devices = deviceHmsService.getDeviceHmsByParam(param); - return ResponseResult.success(devices); + return HttpResultResponse.success(devices); } /** @@ -47,9 +47,9 @@ public class DeviceHmsController { * @return */ @PutMapping("/{workspace_id}/devices/hms/{device_sn}") - public ResponseResult updateReadHmsByDeviceSn(@PathVariable("device_sn") String deviceSn) { + public HttpResultResponse updateReadHmsByDeviceSn(@PathVariable("device_sn") String deviceSn) { deviceHmsService.updateUnreadHms(deviceSn); - return ResponseResult.success(); + return HttpResultResponse.success(); } /** @@ -58,12 +58,12 @@ public class DeviceHmsController { * @return */ @GetMapping("/{workspace_id}/devices/hms/{device_sn}") - public ResponseResult> getUnreadHmsByDeviceSn(@PathVariable("device_sn") String deviceSn) { + public HttpResultResponse> getUnreadHmsByDeviceSn(@PathVariable("device_sn") String deviceSn) { PaginationData paginationData = deviceHmsService.getDeviceHmsByParam( DeviceHmsQueryParam.builder() .deviceSn(new HashSet<>(Set.of(deviceSn))) .updateTime(0L) .build()); - return ResponseResult.success(paginationData.getList()); + return HttpResultResponse.success(paginationData.getList()); } } diff --git a/src/main/java/com/dji/sample/manage/controller/DeviceLogsController.java b/src/main/java/com/dji/sample/manage/controller/DeviceLogsController.java index 6f9b72f..3e08d53 100644 --- a/src/main/java/com/dji/sample/manage/controller/DeviceLogsController.java +++ b/src/main/java/com/dji/sample/manage/controller/DeviceLogsController.java @@ -1,13 +1,14 @@ package com.dji.sample.manage.controller; import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.manage.model.dto.DeviceLogsDTO; import com.dji.sample.manage.model.param.DeviceLogsCreateParam; +import com.dji.sample.manage.model.param.DeviceLogsGetParam; import com.dji.sample.manage.model.param.DeviceLogsQueryParam; -import com.dji.sample.manage.model.param.LogsFileUpdateParam; import com.dji.sample.manage.service.IDeviceLogsService; +import com.dji.sdk.cloudapi.log.FileUploadUpdateRequest; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -15,7 +16,6 @@ import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.net.URL; -import java.util.List; import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; @@ -40,24 +40,24 @@ public class DeviceLogsController { * @return */ @GetMapping("/{workspace_id}/devices/{device_sn}/logs-uploaded") - public ResponseResult getUploadedLogs(DeviceLogsQueryParam param, @PathVariable("workspace_id") String workspaceId, - @PathVariable("device_sn") String deviceSn) { + public HttpResultResponse getUploadedLogs(DeviceLogsQueryParam param, @PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn) { PaginationData data = deviceLogsService.getUploadedLogs(deviceSn, param); - return ResponseResult.success(data); + return HttpResultResponse.success(data); } /** * Get a list of log files that can be uploaded in real time. * @param workspaceId * @param deviceSn - * @param domainList + * @param param * @return */ @GetMapping("/{workspace_id}/devices/{device_sn}/logs") - public ResponseResult getLogsBySn(@PathVariable("workspace_id") String workspaceId, - @PathVariable("device_sn") String deviceSn, - @RequestParam("domain_list") List domainList) { - return deviceLogsService.getRealTimeLogs(deviceSn, domainList); + public HttpResultResponse getLogsBySn(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn, + DeviceLogsGetParam param) { + return deviceLogsService.getRealTimeLogs(deviceSn, param.getDomainList()); } /** @@ -65,9 +65,9 @@ public class DeviceLogsController { * @return */ @PostMapping("/{workspace_id}/devices/{device_sn}/logs") - public ResponseResult uploadLogs(@PathVariable("workspace_id") String workspaceId, - @PathVariable("device_sn") String deviceSn, - HttpServletRequest request, @RequestBody DeviceLogsCreateParam param) { + public HttpResultResponse uploadLogs(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn, + HttpServletRequest request, @RequestBody DeviceLogsCreateParam param) { CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); @@ -79,9 +79,9 @@ public class DeviceLogsController { * @return */ @DeleteMapping("/{workspace_id}/devices/{device_sn}/logs") - public ResponseResult cancelUploadedLogs(@PathVariable("workspace_id") String workspaceId, - @PathVariable("device_sn") String deviceSn, - @RequestBody LogsFileUpdateParam param) { + public HttpResultResponse cancelUploadedLogs(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn, + @RequestBody FileUploadUpdateRequest param) { return deviceLogsService.pushUpdateFile(deviceSn, param); } @@ -91,11 +91,11 @@ public class DeviceLogsController { * @return */ @DeleteMapping("/{workspace_id}/devices/{device_sn}/logs/{logs_id}") - public ResponseResult deleteUploadedLogs(@PathVariable("workspace_id") String workspaceId, - @PathVariable("device_sn") String deviceSn, - @PathVariable("logs_id") String logsId) { + public HttpResultResponse deleteUploadedLogs(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn, + @PathVariable("logs_id") String logsId) { deviceLogsService.deleteLogs(deviceSn, logsId); - return ResponseResult.success(); + return HttpResultResponse.success(); } /** * Query the download address of the file according to the wayline file id, @@ -106,17 +106,17 @@ public class DeviceLogsController { * @param response */ @GetMapping("/{workspace_id}/logs/{logs_id}/url/{file_id}") - public ResponseResult getFileUrl(@PathVariable(name = "workspace_id") String workspaceId, - @PathVariable(name = "file_id") String fileId, - @PathVariable(name = "logs_id") String logsId, HttpServletResponse response) { + public HttpResultResponse getFileUrl(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "file_id") String fileId, + @PathVariable(name = "logs_id") String logsId, HttpServletResponse response) { try { URL url = deviceLogsService.getLogsFileUrl(logsId, fileId); - return ResponseResult.success(url.toString()); + return HttpResultResponse.success(url.toString()); } catch (Exception e) { log.error("Failed to get the logs file download address."); e.printStackTrace(); } - return ResponseResult.error("Failed to get the logs file download address."); + return HttpResultResponse.error("Failed to get the logs file download address."); } } diff --git a/src/main/java/com/dji/sample/manage/controller/LiveStreamController.java b/src/main/java/com/dji/sample/manage/controller/LiveStreamController.java index c8bd144..27f1a64 100644 --- a/src/main/java/com/dji/sample/manage/controller/LiveStreamController.java +++ b/src/main/java/com/dji/sample/manage/controller/LiveStreamController.java @@ -1,17 +1,13 @@ package com.dji.sample.manage.controller; import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.ChannelName; import com.dji.sample.manage.model.dto.CapacityDeviceDTO; import com.dji.sample.manage.model.dto.LiveTypeDTO; -import com.dji.sample.manage.model.receiver.LiveCapacityReceiver; import com.dji.sample.manage.service.ILiveStreamService; +import com.dji.sdk.common.HttpResultResponse; import com.fasterxml.jackson.databind.ObjectMapper; 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.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; @@ -36,29 +32,19 @@ public class LiveStreamController { @Autowired private ObjectMapper mapper; - /** - * Analyze the live streaming capabilities of drones. - * This data is necessary if drones are required for live streaming. - * @param liveCapacity the capacity of drone and dock - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_CAPACITY) - public void stateCapacity(LiveCapacityReceiver liveCapacity, MessageHeaders headers) { - liveStreamService.saveLiveCapacity(liveCapacity, headers.getTimestamp()); - } - /** * Get live capability data of all drones in the current user's workspace from the database. * @param request * @return live capability */ @GetMapping("/capacity") - public ResponseResult> getLiveCapacity(HttpServletRequest request) { + public HttpResultResponse> getLiveCapacity(HttpServletRequest request) { // Get information about the current user. CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); List liveCapacity = liveStreamService.getLiveCapacity(customClaim.getWorkspaceId()); - return ResponseResult.success(liveCapacity); + return HttpResultResponse.success(liveCapacity); } /** @@ -67,7 +53,7 @@ public class LiveStreamController { * @return */ @PostMapping("/streams/start") - public ResponseResult liveStart(@RequestBody LiveTypeDTO liveParam) { + public HttpResultResponse liveStart(@RequestBody LiveTypeDTO liveParam) { return liveStreamService.liveStart(liveParam); } @@ -77,7 +63,7 @@ public class LiveStreamController { * @return */ @PostMapping("/streams/stop") - public ResponseResult liveStop(@RequestBody LiveTypeDTO liveParam) { + public HttpResultResponse liveStop(@RequestBody LiveTypeDTO liveParam) { return liveStreamService.liveStop(liveParam.getVideoId()); } @@ -87,12 +73,12 @@ public class LiveStreamController { * @return */ @PostMapping("/streams/update") - public ResponseResult liveSetQuality(@RequestBody LiveTypeDTO liveParam) { + public HttpResultResponse liveSetQuality(@RequestBody LiveTypeDTO liveParam) { return liveStreamService.liveSetQuality(liveParam); } @PostMapping("/streams/switch") - public ResponseResult liveLensChange(@RequestBody LiveTypeDTO liveParam) { + public HttpResultResponse liveLensChange(@RequestBody LiveTypeDTO liveParam) { return liveStreamService.liveLensChange(liveParam); } diff --git a/src/main/java/com/dji/sample/manage/controller/LoginController.java b/src/main/java/com/dji/sample/manage/controller/LoginController.java index 23c84d9..9572dbb 100644 --- a/src/main/java/com/dji/sample/manage/controller/LoginController.java +++ b/src/main/java/com/dji/sample/manage/controller/LoginController.java @@ -1,10 +1,10 @@ package com.dji.sample.manage.controller; import com.dji.sample.common.error.CommonErrorEnum; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.manage.model.dto.UserDTO; import com.dji.sample.manage.model.dto.UserLoginDTO; import com.dji.sample.manage.service.IUserService; +import com.dji.sdk.common.HttpResultResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.PostMapping; @@ -26,7 +26,7 @@ public class LoginController { private IUserService userService; @PostMapping("/login") - public ResponseResult login(@RequestBody UserLoginDTO loginDTO) { + public HttpResultResponse login(@RequestBody UserLoginDTO loginDTO) { String username = loginDTO.getUsername(); String password = loginDTO.getPassword(); @@ -34,15 +34,15 @@ public class LoginController { } @PostMapping("/token/refresh") - public ResponseResult refreshToken(HttpServletRequest request, HttpServletResponse response) { + public HttpResultResponse refreshToken(HttpServletRequest request, HttpServletResponse response) { String token = request.getHeader(PARAM_TOKEN); Optional user = userService.refreshToken(token); if (user.isEmpty()) { response.setStatus(HttpStatus.UNAUTHORIZED.value()); - return ResponseResult.error(CommonErrorEnum.NO_TOKEN.getErrorMsg()); + return HttpResultResponse.error(CommonErrorEnum.NO_TOKEN.getMessage()); } - return ResponseResult.success(user.get()); + return HttpResultResponse.success(user.get()); } } diff --git a/src/main/java/com/dji/sample/manage/controller/TopologyController.java b/src/main/java/com/dji/sample/manage/controller/TopologyController.java index 3f2b80d..10908d2 100644 --- a/src/main/java/com/dji/sample/manage/controller/TopologyController.java +++ b/src/main/java/com/dji/sample/manage/controller/TopologyController.java @@ -1,17 +1,16 @@ package com.dji.sample.manage.controller; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.manage.model.dto.TopologyDTO; import com.dji.sample.manage.service.ITopologyService; +import com.dji.sdk.cloudapi.tsa.TopologyList; +import com.dji.sdk.cloudapi.tsa.TopologyResponse; +import com.dji.sdk.cloudapi.tsa.api.IHttpTsaService; +import com.dji.sdk.common.HttpResultResponse; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * @author sean @@ -19,22 +18,20 @@ import java.util.concurrent.ConcurrentHashMap; * @date 2021/12/8 */ @RestController -@RequestMapping("${url.manage.prefix}${url.manage.version}/workspaces") -public class TopologyController { +public class TopologyController implements IHttpTsaService { @Autowired private ITopologyService topologyService; + /** * Get the topology list of all devices in the current user workspace for pilot display. * @param workspaceId * @return */ - @GetMapping("/{workspace_id}/devices/topologies") - public ResponseResult>> getDevicesTopologiesForPilot( - @PathVariable(name = "workspace_id") String workspaceId) { - List topologyList = topologyService.getDeviceTopology(workspaceId); - return ResponseResult.success(new ConcurrentHashMap<>(Map.of("list", topologyList))); + @Override + public HttpResultResponse obtainDeviceTopologyList(String workspaceId, HttpServletRequest req, HttpServletResponse rsp) { + List topologyList = topologyService.getDeviceTopology(workspaceId); + return HttpResultResponse.success(new TopologyResponse().setList(topologyList)); } - } diff --git a/src/main/java/com/dji/sample/manage/controller/UserController.java b/src/main/java/com/dji/sample/manage/controller/UserController.java index 91990e7..5536948 100644 --- a/src/main/java/com/dji/sample/manage/controller/UserController.java +++ b/src/main/java/com/dji/sample/manage/controller/UserController.java @@ -1,10 +1,10 @@ package com.dji.sample.manage.controller; import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.manage.model.dto.UserListDTO; import com.dji.sample.manage.service.IUserService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -26,7 +26,7 @@ public class UserController { * @return */ @GetMapping("/current") - public ResponseResult getCurrentUserInfo(HttpServletRequest request) { + public HttpResultResponse getCurrentUserInfo(HttpServletRequest request) { CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); return userService.getUserByUsername(customClaim.getUsername(), customClaim.getWorkspaceId()); } @@ -39,11 +39,11 @@ public class UserController { * @return */ @GetMapping("/{workspace_id}/users") - public ResponseResult> getUsers(@RequestParam(defaultValue = "1") Long page, - @RequestParam(value = "page_size", defaultValue = "50") Long pageSize, - @PathVariable("workspace_id") String workspaceId) { + public HttpResultResponse> getUsers(@RequestParam(defaultValue = "1") Long page, + @RequestParam(value = "page_size", defaultValue = "50") Long pageSize, + @PathVariable("workspace_id") String workspaceId) { PaginationData paginationData = userService.getUsersByWorkspaceId(page, pageSize, workspaceId); - return ResponseResult.success(paginationData); + return HttpResultResponse.success(paginationData); } /** @@ -54,11 +54,11 @@ public class UserController { * @return */ @PutMapping("/{workspace_id}/users/{user_id}") - public ResponseResult updateUser(@RequestBody UserListDTO user, - @PathVariable("workspace_id") String workspaceId, - @PathVariable("user_id") String userId) { + public HttpResultResponse updateUser(@RequestBody UserListDTO user, + @PathVariable("workspace_id") String workspaceId, + @PathVariable("user_id") String userId) { userService.updateUser(workspaceId, userId, user); - return ResponseResult.success(); + return HttpResultResponse.success(); } } diff --git a/src/main/java/com/dji/sample/manage/controller/WorkspaceController.java b/src/main/java/com/dji/sample/manage/controller/WorkspaceController.java index e2f5f43..80110ac 100644 --- a/src/main/java/com/dji/sample/manage/controller/WorkspaceController.java +++ b/src/main/java/com/dji/sample/manage/controller/WorkspaceController.java @@ -1,9 +1,9 @@ package com.dji.sample.manage.controller; import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.manage.model.dto.WorkspaceDTO; import com.dji.sample.manage.service.IWorkspaceService; +import com.dji.sdk.common.HttpResultResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -32,10 +32,10 @@ public class WorkspaceController { * @return */ @GetMapping("/current") - public ResponseResult getCurrentWorkspace(HttpServletRequest request) { + public HttpResultResponse getCurrentWorkspace(HttpServletRequest request) { CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); Optional workspaceOpt = workspaceService.getWorkspaceByWorkspaceId(customClaim.getWorkspaceId()); - return workspaceOpt.isEmpty() ? ResponseResult.error() : ResponseResult.success(workspaceOpt.get()); + return workspaceOpt.isEmpty() ? HttpResultResponse.error() : HttpResultResponse.success(workspaceOpt.get()); } } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/dto/DeviceAuthorityDTO.java b/src/main/java/com/dji/sample/manage/model/dto/DeviceAuthorityDTO.java index 72621e1..c72680f 100644 --- a/src/main/java/com/dji/sample/manage/model/dto/DeviceAuthorityDTO.java +++ b/src/main/java/com/dji/sample/manage/model/dto/DeviceAuthorityDTO.java @@ -1,6 +1,7 @@ package com.dji.sample.manage.model.dto; import com.dji.sample.control.model.enums.DroneAuthorityEnum; +import com.dji.sdk.cloudapi.device.ControlSourceEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -21,6 +22,6 @@ public class DeviceAuthorityDTO { private DroneAuthorityEnum type; - private String controlSource; + private ControlSourceEnum controlSource; } diff --git a/src/main/java/com/dji/sample/manage/model/dto/DeviceDTO.java b/src/main/java/com/dji/sample/manage/model/dto/DeviceDTO.java index d4c7399..3d89a92 100644 --- a/src/main/java/com/dji/sample/manage/model/dto/DeviceDTO.java +++ b/src/main/java/com/dji/sample/manage/model/dto/DeviceDTO.java @@ -1,5 +1,11 @@ package com.dji.sample.manage.model.dto; +import com.dji.sample.manage.model.enums.DeviceFirmwareStatusEnum; +import com.dji.sdk.cloudapi.device.ControlSourceEnum; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.device.DeviceSubTypeEnum; +import com.dji.sdk.cloudapi.device.DeviceTypeEnum; +import com.dji.sdk.cloudapi.tsa.DeviceIconUrl; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -25,21 +31,21 @@ public class DeviceDTO { private String workspaceId; - private String controlSource; + private ControlSourceEnum controlSource; private String deviceDesc; private String childDeviceSn; - private Integer domain; + private DeviceDomainEnum domain; - private Integer type; + private DeviceTypeEnum type; - private Integer subType; + private DeviceSubTypeEnum subType; private List payloadsList; - private IconUrlDTO iconUrl; + private DeviceIconUrl iconUrl; private Boolean status; @@ -59,9 +65,11 @@ public class DeviceDTO { private DeviceDTO children; - private Integer firmwareStatus; + private DeviceFirmwareStatusEnum firmwareStatus; private Integer firmwareProgress; private String parentSn; + + private String thingVersion; } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/dto/DeviceLogsDTO.java b/src/main/java/com/dji/sample/manage/model/dto/DeviceLogsDTO.java index b3d7b7f..0f5e210 100644 --- a/src/main/java/com/dji/sample/manage/model/dto/DeviceLogsDTO.java +++ b/src/main/java/com/dji/sample/manage/model/dto/DeviceLogsDTO.java @@ -1,6 +1,6 @@ package com.dji.sample.manage.model.dto; -import com.dji.sample.manage.model.receiver.LogsFileUploadList; +import com.dji.sdk.cloudapi.tsa.TopologyList; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -32,10 +32,10 @@ public class DeviceLogsDTO { private Integer status; - private TopologyDTO deviceTopo; + private TopologyList deviceTopo; private List logsProgress; - private LogsFileUploadList deviceLogs; + private LogsFileUploadListDTO deviceLogs; } diff --git a/src/main/java/com/dji/sample/manage/model/dto/DeviceModelDTO.java b/src/main/java/com/dji/sample/manage/model/dto/DeviceModelDTO.java deleted file mode 100644 index d7559ff..0000000 --- a/src/main/java/com/dji/sample/manage/model/dto/DeviceModelDTO.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.dji.sample.manage.model.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 0.2 - * @date 2021/12/8 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class DeviceModelDTO { - - private String key; - - private String domain; - - private String type; - - private String subType; - -} diff --git a/src/main/java/com/dji/sample/manage/model/dto/DevicePayloadDTO.java b/src/main/java/com/dji/sample/manage/model/dto/DevicePayloadDTO.java index 555eb90..abcfb45 100644 --- a/src/main/java/com/dji/sample/manage/model/dto/DevicePayloadDTO.java +++ b/src/main/java/com/dji/sample/manage/model/dto/DevicePayloadDTO.java @@ -1,7 +1,7 @@ package com.dji.sample.manage.model.dto; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.dji.sdk.cloudapi.device.ControlSourceEnum; +import com.dji.sdk.cloudapi.device.PayloadIndex; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -16,7 +16,6 @@ import lombok.NoArgsConstructor; @Builder @NoArgsConstructor @AllArgsConstructor -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class DevicePayloadDTO { private String payloadSn; @@ -27,7 +26,7 @@ public class DevicePayloadDTO { private String payloadDesc; - private String controlSource; + private ControlSourceEnum controlSource; - private String payloadIndex; + private PayloadIndex payloadIndex; } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/dto/DevicePayloadReceiver.java b/src/main/java/com/dji/sample/manage/model/dto/DevicePayloadReceiver.java new file mode 100644 index 0000000..85ecfd9 --- /dev/null +++ b/src/main/java/com/dji/sample/manage/model/dto/DevicePayloadReceiver.java @@ -0,0 +1,29 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sdk.cloudapi.device.ControlSourceEnum; +import com.dji.sdk.cloudapi.device.PayloadIndex; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DevicePayloadReceiver { + + private String deviceSn; + + private ControlSourceEnum controlSource; + + private PayloadIndex payloadIndex; + + private String sn; + +} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/dto/IconUrlDTO.java b/src/main/java/com/dji/sample/manage/model/dto/IconUrlDTO.java deleted file mode 100644 index effbf1c..0000000 --- a/src/main/java/com/dji/sample/manage/model/dto/IconUrlDTO.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.dji.sample.manage.model.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 0.3 - * @date 2022/1/5 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class IconUrlDTO { - - @JsonProperty("normal_icon_url") - private String normalUrl; - - @JsonProperty("selected_icon_url") - private String selectUrl; -} diff --git a/src/main/java/com/dji/sample/manage/model/dto/LiveTypeDTO.java b/src/main/java/com/dji/sample/manage/model/dto/LiveTypeDTO.java index 4a385ec..ebd932c 100644 --- a/src/main/java/com/dji/sample/manage/model/dto/LiveTypeDTO.java +++ b/src/main/java/com/dji/sample/manage/model/dto/LiveTypeDTO.java @@ -1,5 +1,8 @@ package com.dji.sample.manage.model.dto; +import com.dji.sdk.cloudapi.livestream.LensChangeVideoTypeEnum; +import com.dji.sdk.cloudapi.livestream.UrlTypeEnum; +import com.dji.sdk.cloudapi.livestream.VideoQualityEnum; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @@ -13,7 +16,7 @@ import lombok.Data; public class LiveTypeDTO { @JsonProperty("url_type") - private Integer urlType; + private UrlTypeEnum urlType; private String url; @@ -21,8 +24,8 @@ public class LiveTypeDTO { private String videoId; @JsonProperty("video_quality") - private Integer videoQuality; + private VideoQualityEnum videoQuality; - private String videoType; + private LensChangeVideoTypeEnum videoType; } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/receiver/LogsFileUpload.java b/src/main/java/com/dji/sample/manage/model/dto/LogsFileUploadDTO.java similarity index 64% rename from src/main/java/com/dji/sample/manage/model/receiver/LogsFileUpload.java rename to src/main/java/com/dji/sample/manage/model/dto/LogsFileUploadDTO.java index 034fcc9..1780b7f 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/LogsFileUpload.java +++ b/src/main/java/com/dji/sample/manage/model/dto/LogsFileUploadDTO.java @@ -1,5 +1,7 @@ -package com.dji.sample.manage.model.receiver; +package com.dji.sample.manage.model.dto; +import com.dji.sdk.cloudapi.log.LogFileIndex; +import com.dji.sdk.cloudapi.log.LogModuleEnum; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; @@ -17,14 +19,14 @@ import java.util.List; @AllArgsConstructor @NoArgsConstructor @Builder -public class LogsFileUpload { +public class LogsFileUploadDTO { private String deviceSn; - private List list; + private List list; @JsonProperty("module") - private String deviceModelDomain; + private LogModuleEnum deviceModelDomain; private String objectKey; diff --git a/src/main/java/com/dji/sample/manage/model/receiver/LogsFileUploadList.java b/src/main/java/com/dji/sample/manage/model/dto/LogsFileUploadListDTO.java similarity index 69% rename from src/main/java/com/dji/sample/manage/model/receiver/LogsFileUploadList.java rename to src/main/java/com/dji/sample/manage/model/dto/LogsFileUploadListDTO.java index 0d0c616..be470f8 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/LogsFileUploadList.java +++ b/src/main/java/com/dji/sample/manage/model/dto/LogsFileUploadListDTO.java @@ -1,4 +1,4 @@ -package com.dji.sample.manage.model.receiver; +package com.dji.sample.manage.model.dto; import lombok.AllArgsConstructor; import lombok.Builder; @@ -16,9 +16,9 @@ import java.util.List; @Builder @AllArgsConstructor @NoArgsConstructor -public class LogsFileUploadList { +public class LogsFileUploadListDTO { - private List files; + private List files; private Integer result; } diff --git a/src/main/java/com/dji/sample/manage/model/dto/LogsOutputProgressDTO.java b/src/main/java/com/dji/sample/manage/model/dto/LogsOutputProgressDTO.java index 057c5da..e0b1ad8 100644 --- a/src/main/java/com/dji/sample/manage/model/dto/LogsOutputProgressDTO.java +++ b/src/main/java/com/dji/sample/manage/model/dto/LogsOutputProgressDTO.java @@ -1,5 +1,6 @@ package com.dji.sample.manage.model.dto; +import com.dji.sdk.cloudapi.log.FileUploadStatusEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -20,7 +21,7 @@ public class LogsOutputProgressDTO { private String logsId; - private String status; + private FileUploadStatusEnum status; private List files; } diff --git a/src/main/java/com/dji/sample/manage/model/dto/LogsUploadCredentialsDTO.java b/src/main/java/com/dji/sample/manage/model/dto/LogsUploadCredentialsDTO.java index 970fc12..a58041e 100644 --- a/src/main/java/com/dji/sample/manage/model/dto/LogsUploadCredentialsDTO.java +++ b/src/main/java/com/dji/sample/manage/model/dto/LogsUploadCredentialsDTO.java @@ -1,8 +1,9 @@ package com.dji.sample.manage.model.dto; -import com.dji.sample.manage.model.receiver.LogsFileUploadList; -import com.dji.sample.media.model.CredentialsDTO; -import com.dji.sample.media.model.StsCredentialsDTO; +import com.dji.sdk.cloudapi.log.FileUploadStartParam; +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; @@ -22,22 +23,23 @@ public class LogsUploadCredentialsDTO { private String bucket; - private CredentialsDTO credentials; + private CredentialsToken credentials; private String endpoint; @JsonProperty("file_store_dir") private String objectKeyPrefix; - private String provider; + private OssTypeEnum provider; + @Builder.Default private String fileType = "text_log"; - private LogsFileUploadList params; + private FileUploadStartParam params; private String region; - public LogsUploadCredentialsDTO(StsCredentialsDTO sts) { + public LogsUploadCredentialsDTO(StsCredentialsResponse sts) { this.bucket = sts.getBucket(); long expire = sts.getCredentials().getExpire(); sts.getCredentials().setExpire(System.currentTimeMillis() + (expire - 60) * 1000); diff --git a/src/main/java/com/dji/sample/manage/model/dto/TelemetryDeviceDTO.java b/src/main/java/com/dji/sample/manage/model/dto/TelemetryDeviceDTO.java deleted file mode 100644 index 1905804..0000000 --- a/src/main/java/com/dji/sample/manage/model/dto/TelemetryDeviceDTO.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.dji.sample.manage.model.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 0.2 - * @date 2021/12/8 - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class TelemetryDeviceDTO { - - private Double latitude; - - private Double longitude; - - private Double altitude; - - private Float attitudeHead; - - private Double elevation; - - private Float horizontalSpeed; - - private Float verticalSpeed; -} diff --git a/src/main/java/com/dji/sample/manage/model/dto/TopologyDTO.java b/src/main/java/com/dji/sample/manage/model/dto/TopologyDTO.java deleted file mode 100644 index d91cd3a..0000000 --- a/src/main/java/com/dji/sample/manage/model/dto/TopologyDTO.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.dji.sample.manage.model.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -/** - * @author sean - * @version 0.2 - * @date 2021/12/8 - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class TopologyDTO { - - private List hosts; - - private List parents; -} diff --git a/src/main/java/com/dji/sample/manage/model/dto/TopologyDeviceDTO.java b/src/main/java/com/dji/sample/manage/model/dto/TopologyDeviceDTO.java index ea709cc..627615d 100644 --- a/src/main/java/com/dji/sample/manage/model/dto/TopologyDeviceDTO.java +++ b/src/main/java/com/dji/sample/manage/model/dto/TopologyDeviceDTO.java @@ -1,42 +1,148 @@ package com.dji.sample.manage.model.dto; -import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.tsa.DeviceIconUrl; +import com.dji.sdk.cloudapi.tsa.DeviceTopology; +import com.dji.sdk.cloudapi.tsa.TopologyDeviceModel; /** * @author sean * @version 0.2 * @date 2021/12/8 */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -public class TopologyDeviceDTO { +public class TopologyDeviceDTO extends DeviceTopology { - private String sn; + private String model; - private DeviceModelDTO deviceModel; + private Boolean boundStatus; - private Boolean onlineStatus; + private String gatewaySn; - private String deviceCallsign; + private DeviceDomainEnum domain; - private String userId; + public TopologyDeviceDTO() { + } - private String userCallsign; + @Override + public String toString() { + return "TopologyDeviceDTO{" + + "model='" + model + '\'' + + ", boundStatus=" + boundStatus + + ", gatewaySn='" + gatewaySn + '\'' + + ", domain=" + domain + + '}'; + } - private IconUrlDTO iconUrls; + @Override + public String getSn() { + return super.getSn(); + } - private String model; + @Override + public TopologyDeviceDTO setSn(String sn) { + super.setSn(sn); + return this; + } - private Boolean boundStatus; + @Override + public String getDeviceCallsign() { + return super.getDeviceCallsign(); + } - private String gatewaySn; + @Override + public TopologyDeviceDTO setDeviceCallsign(String deviceCallsign) { + super.setDeviceCallsign(deviceCallsign); + return this; + } + + @Override + public TopologyDeviceModel getDeviceModel() { + return super.getDeviceModel(); + } + + @Override + public TopologyDeviceDTO setDeviceModel(TopologyDeviceModel deviceModel) { + super.setDeviceModel(deviceModel); + return this; + } + + @Override + public Boolean getOnlineStatus() { + return super.getOnlineStatus(); + } + + @Override + public TopologyDeviceDTO setOnlineStatus(Boolean onlineStatus) { + super.setOnlineStatus(onlineStatus); + return this; + } + + @Override + public String getUserId() { + return super.getUserId(); + } + + @Override + public TopologyDeviceDTO setUserId(String userId) { + super.setUserId(userId); + return this; + } + + @Override + public String getUserCallsign() { + return super.getUserCallsign(); + } + + @Override + public TopologyDeviceDTO setUserCallsign(String userCallsign) { + super.setUserCallsign(userCallsign); + return this; + } + + @Override + public DeviceIconUrl getIconUrls() { + return super.getIconUrls(); + } + + @Override + public TopologyDeviceDTO setIconUrls(DeviceIconUrl iconUrls) { + super.setIconUrls(iconUrls); + return this; + } + + public String getModel() { + return model; + } + + public TopologyDeviceDTO setModel(String model) { + this.model = model; + return this; + } + + public Boolean getBoundStatus() { + return boundStatus; + } + + public TopologyDeviceDTO setBoundStatus(Boolean boundStatus) { + this.boundStatus = boundStatus; + return this; + } + + public String getGatewaySn() { + return gatewaySn; + } + + public TopologyDeviceDTO setGatewaySn(String gatewaySn) { + this.gatewaySn = gatewaySn; + return this; + } + + public DeviceDomainEnum getDomain() { + return domain; + } - private Integer domain; + public TopologyDeviceDTO setDomain(DeviceDomainEnum domain) { + this.domain = domain; + return this; + } } diff --git a/src/main/java/com/dji/sample/manage/model/dto/WorkspaceDTO.java b/src/main/java/com/dji/sample/manage/model/dto/WorkspaceDTO.java index 3714974..de9083b 100644 --- a/src/main/java/com/dji/sample/manage/model/dto/WorkspaceDTO.java +++ b/src/main/java/com/dji/sample/manage/model/dto/WorkspaceDTO.java @@ -1,7 +1,5 @@ package com.dji.sample.manage.model.dto; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -16,7 +14,6 @@ import lombok.NoArgsConstructor; @AllArgsConstructor @NoArgsConstructor @Builder -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class WorkspaceDTO { private Integer id; diff --git a/src/main/java/com/dji/sample/manage/model/entity/DeviceEntity.java b/src/main/java/com/dji/sample/manage/model/entity/DeviceEntity.java index 57ace0d..ae26ed1 100644 --- a/src/main/java/com/dji/sample/manage/model/entity/DeviceEntity.java +++ b/src/main/java/com/dji/sample/manage/model/entity/DeviceEntity.java @@ -44,7 +44,7 @@ public class DeviceEntity implements Serializable { private Integer domain; @TableField(value = "version") - private Integer version; + private String version; @TableField(value = "device_index") private String deviceIndex; diff --git a/src/main/java/com/dji/sample/manage/model/enums/ControlSourceEnum.java b/src/main/java/com/dji/sample/manage/model/enums/ControlSourceEnum.java deleted file mode 100644 index 764bc3c..0000000 --- a/src/main/java/com/dji/sample/manage/model/enums/ControlSourceEnum.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.manage.model.enums; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -import java.util.Arrays; - -/** - * @author sean - * @version 1.4 - * @date 2023/3/16 - */ -public enum ControlSourceEnum { - - A, B; - - @JsonValue - public String getControlSource() { - return name(); - } - - @JsonCreator - public static ControlSourceEnum find(String controlSource) { - return Arrays.stream(values()).filter(controlSourceEnum -> controlSourceEnum.name().equals(controlSource)).findAny().get(); - } -} diff --git a/src/main/java/com/dji/sample/manage/model/enums/CustomizeConfigScopeEnum.java b/src/main/java/com/dji/sample/manage/model/enums/CustomizeConfigScopeEnum.java new file mode 100644 index 0000000..4634264 --- /dev/null +++ b/src/main/java/com/dji/sample/manage/model/enums/CustomizeConfigScopeEnum.java @@ -0,0 +1,33 @@ +package com.dji.sample.manage.model.enums; + +import com.dji.sample.manage.service.IRequestsConfigService; +import com.dji.sample.manage.service.impl.ConfigProductServiceImpl; +import com.dji.sdk.cloudapi.config.ConfigScopeEnum; +import lombok.Getter; + +import java.util.Arrays; +import java.util.Optional; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +@Getter +public enum CustomizeConfigScopeEnum { + + PRODUCT(ConfigScopeEnum.PRODUCT, ConfigProductServiceImpl.class); + + ConfigScopeEnum scope; + + Class clazz; + + CustomizeConfigScopeEnum(ConfigScopeEnum scope, Class clazz) { + this.scope = scope; + this.clazz = clazz; + } + + public static Optional find(String scope) { + return Arrays.stream(CustomizeConfigScopeEnum.values()).filter(scopeEnum -> scopeEnum.scope.getScope().equals(scope)).findAny(); + } +} diff --git a/src/main/java/com/dji/sample/manage/model/enums/DeviceDomainEnum.java b/src/main/java/com/dji/sample/manage/model/enums/DeviceDomainEnum.java deleted file mode 100644 index 2ce85a2..0000000 --- a/src/main/java/com/dji/sample/manage/model/enums/DeviceDomainEnum.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.dji.sample.manage.model.enums; - -import lombok.Getter; - -import java.util.Arrays; - -/** - * - * @author sean.zhou - * @date 2021/11/15 - * @version 0.1 - */ -@Getter -public enum DeviceDomainEnum { - - SUB_DEVICE(0), - - GATEWAY(2), - - PAYLOAD(1), - - DOCK (3), - - UNKNOWN(-1); - - int val; - - DeviceDomainEnum(int val) { - this.val = val; - } - - public static DeviceDomainEnum find(int val) { - return Arrays.stream(values()).filter(domainEnum -> domainEnum.val == val).findAny().orElse(UNKNOWN); - } -} diff --git a/src/main/java/com/dji/sample/manage/model/enums/DeviceFirmwareStatusEnum.java b/src/main/java/com/dji/sample/manage/model/enums/DeviceFirmwareStatusEnum.java index bccbba7..01beda2 100644 --- a/src/main/java/com/dji/sample/manage/model/enums/DeviceFirmwareStatusEnum.java +++ b/src/main/java/com/dji/sample/manage/model/enums/DeviceFirmwareStatusEnum.java @@ -1,5 +1,7 @@ package com.dji.sample.manage.model.enums; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; import lombok.Getter; import java.util.Arrays; @@ -9,7 +11,6 @@ import java.util.Arrays; * @version 1.2 * @date 2022/8/15 */ -@Getter public enum DeviceFirmwareStatusEnum { /** @@ -36,10 +37,16 @@ public enum DeviceFirmwareStatusEnum { int val; + @JsonValue + public int getVal() { + return val; + } + DeviceFirmwareStatusEnum(int val) { this.val = val; } + @JsonCreator public static DeviceFirmwareStatusEnum find(int val) { return Arrays.stream(DeviceFirmwareStatusEnum.values()) .filter(firmwareStatus -> firmwareStatus.val == val) diff --git a/src/main/java/com/dji/sample/manage/model/enums/DeviceLogsStatusEnum.java b/src/main/java/com/dji/sample/manage/model/enums/DeviceLogsStatusEnum.java index 53d1bfb..0fcbdd8 100644 --- a/src/main/java/com/dji/sample/manage/model/enums/DeviceLogsStatusEnum.java +++ b/src/main/java/com/dji/sample/manage/model/enums/DeviceLogsStatusEnum.java @@ -1,6 +1,6 @@ package com.dji.sample.manage.model.enums; -import com.dji.sample.component.mqtt.model.EventsResultStatusEnum; +import com.dji.sdk.cloudapi.log.FileUploadStatusEnum; import lombok.Getter; import java.util.Arrays; @@ -15,27 +15,28 @@ import java.util.HashSet; @Getter public enum DeviceLogsStatusEnum { - UPLOADING(1, EventsResultStatusEnum.IN_PROGRESS), + UPLOADING(1, FileUploadStatusEnum.FILE_PULL, FileUploadStatusEnum.FILE_ZIP, + FileUploadStatusEnum.FILE_UPLOADING, FileUploadStatusEnum.IN_PROGRESS, FileUploadStatusEnum.PAUSED), - DONE(2, EventsResultStatusEnum.OK), + DONE(2, FileUploadStatusEnum.OK), - CANCELED(3, EventsResultStatusEnum.CANCELED), + CANCELED(3, FileUploadStatusEnum.CANCELED), - FAILED(4, EventsResultStatusEnum.FAILED, EventsResultStatusEnum.REJECTED, EventsResultStatusEnum.TIMEOUT), + FAILED(4, FileUploadStatusEnum.FAILED, FileUploadStatusEnum.REJECTED, FileUploadStatusEnum.TIMEOUT), UNKNOWN(-1); int val; - HashSet status; + HashSet status; - DeviceLogsStatusEnum(int val, EventsResultStatusEnum... status) { + DeviceLogsStatusEnum(int val, FileUploadStatusEnum... status) { this.status = new HashSet<>(); Collections.addAll(this.status, status); this.val = val; } - public static DeviceLogsStatusEnum find(EventsResultStatusEnum status) { + public static DeviceLogsStatusEnum find(FileUploadStatusEnum status) { return Arrays.stream(DeviceLogsStatusEnum.values()).filter(element -> element.status.contains(status)).findAny().orElse(UNKNOWN); } } diff --git a/src/main/java/com/dji/sample/manage/model/enums/DeviceSetPropertyEnum.java b/src/main/java/com/dji/sample/manage/model/enums/DeviceSetPropertyEnum.java deleted file mode 100644 index 07c6658..0000000 --- a/src/main/java/com/dji/sample/manage/model/enums/DeviceSetPropertyEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.dji.sample.manage.model.enums; - -import com.dji.sample.manage.model.receiver.*; -import lombok.Getter; - -import java.util.Arrays; -import java.util.Optional; - -/** - * @author sean - * @version 1.3 - * @date 2022/10/27 - */ -@Getter -public enum DeviceSetPropertyEnum { - - NIGHT_LIGHTS_STATE("night_lights_state", NightLightsStateReceiver.class), - - HEIGHT_LIMIT("height_limit", HeightLimitReceiver.class), - - DISTANCE_LIMIT_STATUS("distance_limit_status", DistanceLimitStatusReceiver.class), - - OBSTACLE_AVOIDANCE("obstacle_avoidance", ObstacleAvoidanceReceiver.class), - - RTH_ALTITUDE("rth_altitude", RthAltitudeReceiver.class), - - OUT_OF_CONTROL_ACTION("out_of_control_action", OutOfControlActionReceiver.class); - - String property; - - Class clazz; - - DeviceSetPropertyEnum(String property, Class clazz) { - this.property = property; - this.clazz = clazz; - } - - public static Optional find(String property) { - return Arrays.stream(DeviceSetPropertyEnum.values()).filter(propertyEnum -> propertyEnum.property.equals(property)).findAny(); - } -} diff --git a/src/main/java/com/dji/sample/manage/model/enums/DockDrcStateEnum.java b/src/main/java/com/dji/sample/manage/model/enums/DockDrcStateEnum.java deleted file mode 100644 index 9683f1f..0000000 --- a/src/main/java/com/dji/sample/manage/model/enums/DockDrcStateEnum.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.dji.sample.manage.model.enums; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -import java.util.Arrays; - -/** - * @author sean - * @version 1.4 - * @date 2023/2/28 - */ -public enum DockDrcStateEnum { - - DISCONNECTED(0), - - CONNECTING(1), - - CONNECTED(2); - - int val; - - DockDrcStateEnum(int val) { - this.val = val; - } - - @JsonValue - public int getVal() { - return val; - } - - @JsonCreator - public static DockDrcStateEnum find(int val) { - return Arrays.stream(values()).filter(drcState -> drcState.getVal() == val).findAny().orElse(DISCONNECTED); - } -} diff --git a/src/main/java/com/dji/sample/manage/model/enums/DroneRcLostActionEnum.java b/src/main/java/com/dji/sample/manage/model/enums/DroneRcLostActionEnum.java deleted file mode 100644 index 116847e..0000000 --- a/src/main/java/com/dji/sample/manage/model/enums/DroneRcLostActionEnum.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.manage.model.enums; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -import java.util.Arrays; - -/** - * @author sean - * @version 1.4 - * @date 2023/3/1 - */ -public enum DroneRcLostActionEnum { - - HOVER, LAND, RETURN_HOME; - - @JsonValue - public int getVal() { - return ordinal(); - } - - @JsonCreator - public static DroneRcLostActionEnum find(int val) { - return Arrays.stream(values()).filter(controlActionEnum -> controlActionEnum.ordinal() == val).findAny().get(); - } -} diff --git a/src/main/java/com/dji/sample/manage/model/enums/WaylineRcLostActionEnum.java b/src/main/java/com/dji/sample/manage/model/enums/ExitWaylineWhenRcLostActionEnum.java similarity index 59% rename from src/main/java/com/dji/sample/manage/model/enums/WaylineRcLostActionEnum.java rename to src/main/java/com/dji/sample/manage/model/enums/ExitWaylineWhenRcLostActionEnum.java index 3632452..aff6504 100644 --- a/src/main/java/com/dji/sample/manage/model/enums/WaylineRcLostActionEnum.java +++ b/src/main/java/com/dji/sample/manage/model/enums/ExitWaylineWhenRcLostActionEnum.java @@ -1,5 +1,6 @@ package com.dji.sample.manage.model.enums; +import com.dji.sdk.exception.CloudSDKException; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; @@ -10,7 +11,7 @@ import java.util.Arrays; * @version 1.4 * @date 2023/3/15 */ -public enum WaylineRcLostActionEnum { +public enum ExitWaylineWhenRcLostActionEnum { CONTINUE_WAYLINE, EXECUTE_RC_LOST_ACTION; @@ -20,7 +21,8 @@ public enum WaylineRcLostActionEnum { } @JsonCreator - public static WaylineRcLostActionEnum find(int val) { - return Arrays.stream(values()).filter(lostActionEnum -> lostActionEnum.ordinal() == val).findAny().get(); + public static ExitWaylineWhenRcLostActionEnum find(int val) { + return Arrays.stream(values()).filter(lostActionEnum -> lostActionEnum.ordinal() == val).findAny() + .orElseThrow(() -> new CloudSDKException(ExitWaylineWhenRcLostActionEnum.class, val)); } } diff --git a/src/main/java/com/dji/sample/manage/model/enums/HmsEnum.java b/src/main/java/com/dji/sample/manage/model/enums/HmsEnum.java deleted file mode 100644 index 20af72f..0000000 --- a/src/main/java/com/dji/sample/manage/model/enums/HmsEnum.java +++ /dev/null @@ -1,177 +0,0 @@ -package com.dji.sample.manage.model.enums; - -import lombok.Getter; - -import java.util.Arrays; - -/** - * @author sean - * @version 1.1 - * @date 2022/7/7 - */ -@Getter -public enum HmsEnum { - - IN_THE_SKY("_in_the_sky", 1); - - private int val; - - private String text; - - HmsEnum(String text, int val) { - this.text = text; - this.val = val; - } - - @Getter - public enum MessageLanguage { - - EN("en"), - - ZH("zh"); - - String language; - - MessageLanguage(String language) { - this.language = language; - } - } - - @Getter - public enum HmsFaqIdEnum { - - DOCK_TIP("dock_tip_"), - - FPV_TIP("fpv_tip_"); - - private String text; - - HmsFaqIdEnum(String text) { - this.text = text; - } - - } - - @Getter - public enum HmsBatteryIndexEnum { - LEFT(0, "left", "左"), - - RIGHT(1, "right", "右"), - - UNKNOWN(-1, "unknown", "未知"); - - private int val; - - private String en; - - private String zh; - - HmsBatteryIndexEnum(int val, String en, String zh) { - this.val = val; - this.en = en; - this.zh = zh; - } - - public static HmsBatteryIndexEnum find(int val) { - return Arrays.stream(HmsBatteryIndexEnum.values()) - .filter(battery -> battery.val == val) - .findAny() - .orElse(UNKNOWN); - } - } - - @Getter - public enum HmsDockCoverIndexEnum { - LEFT(0, "left", "左"), - - RIGHT(1, "right", "右"), - - UNKNOWN(-1, "unknown", "未知"); - - private int val; - - private String en; - - private String zh; - - HmsDockCoverIndexEnum(int val, String en, String zh) { - this.val = val; - this.en = en; - this.zh = zh; - } - - public static HmsDockCoverIndexEnum find(int val) { - return Arrays.stream(HmsDockCoverIndexEnum.values()) - .filter(dockCover -> dockCover.val == val) - .findAny() - .orElse(UNKNOWN); - } - } - - @Getter - public enum HmsChargingRodIndexEnum { - - FRONT(0, "front", "前"), - - BACK(1, "back", "后"), - - LEFT(2, "left", "左"), - - RIGHT(3, "right", "右"), - - UNKNOWN(-1, "unknown", "未知"); - - private int val; - - private String en; - - private String zh; - - HmsChargingRodIndexEnum(int val, String en, String zh) { - this.val = val; - this.en = en; - this.zh = zh; - } - - public static HmsChargingRodIndexEnum find(int val) { - return Arrays.stream(HmsChargingRodIndexEnum.values()) - .filter(rod -> rod.val == val) - .findAny() - .orElse(UNKNOWN); - } - } - - @Getter - public enum FormatKeyEnum { - - ALARM_ID("alarmid", 0), - - COMPONENT_INDEX("component_index", 1), - - INDEX("index", 2), - - BATTERY_INDEX("battery_index", 3), - - DOCK_COVER_INDEX("dock_cover_index", 4), - - CHARGING_ROD_INDEX("charging_rod_index", 5), - - UNKNOWN("unknown", -1); - - public static final char KEY_START = '%'; - - String key; - int index; - - FormatKeyEnum(String key, int index) { - this.key = key; - this.index = index; - } - - public static FormatKeyEnum find(String key) { - return Arrays.stream(FormatKeyEnum.values()) - .filter(format -> format.getKey().equals(key)) - .findAny().orElse(UNKNOWN); - } - } -} diff --git a/src/main/java/com/dji/sample/manage/model/enums/LogsFileMethodEnum.java b/src/main/java/com/dji/sample/manage/model/enums/LogsFileMethodEnum.java deleted file mode 100644 index 42b1b87..0000000 --- a/src/main/java/com/dji/sample/manage/model/enums/LogsFileMethodEnum.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.manage.model.enums; - -import lombok.Getter; - -/** - * @author sean - * @version 1.3 - * @date 2022/11/14 - */ -@Getter -public enum LogsFileMethodEnum { - - FILE_UPLOAD_LIST("fileupload_list"), - - FILE_UPLOAD_START("fileupload_start"), - - FILE_UPLOAD_UPDATE("fileupload_update"), - - UNKNOWN("unknown"); - - private String method; - - LogsFileMethodEnum(String method) { - this.method = method; - } -} diff --git a/src/main/java/com/dji/sample/manage/model/enums/PropertySetFieldEnum.java b/src/main/java/com/dji/sample/manage/model/enums/PropertySetFieldEnum.java new file mode 100644 index 0000000..a80f0f9 --- /dev/null +++ b/src/main/java/com/dji/sample/manage/model/enums/PropertySetFieldEnum.java @@ -0,0 +1,68 @@ +package com.dji.sample.manage.model.enums; + +import com.dji.sample.manage.model.receiver.*; +import com.dji.sdk.cloudapi.property.PropertySetEnum; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public enum PropertySetFieldEnum { + + NIGHT_LIGHTS_STATE(PropertySetEnum.NIGHT_LIGHTS_STATE, NightLightsStateReceiver.class), + + HEIGHT_LIMIT(PropertySetEnum.HEIGHT_LIMIT, HeightLimitReceiver.class), + + DISTANCE_LIMIT_STATUS(PropertySetEnum.DISTANCE_LIMIT_STATUS, DistanceLimitStatusReceiver.class), + + OBSTACLE_AVOIDANCE(PropertySetEnum.OBSTACLE_AVOIDANCE, ObstacleAvoidanceReceiver.class), + + RTH_ALTITUDE(PropertySetEnum.RTH_ALTITUDE, RthAltitudeReceiver.class), + + OUT_OF_CONTROL_ACTION(PropertySetEnum.OUT_OF_CONTROL_ACTION, OutOfControlActionReceiver.class), + +// EXIT_WAYLINE_WHEN_RC_LOST(PropertySetEnum.EXIT_WAYLINE_WHEN_RC_LOST, .class), +// +// THERMAL_CURRENT_PALETTE_STYLE(PropertySetEnum.THERMAL_CURRENT_PALETTE_STYLE, .class), +// +// THERMAL_GAIN_MODE(PropertySetEnum.THERMAL_GAIN_MODE, .class), +// +// THERMAL_ISOTHERM_STATE(PropertySetEnum.THERMAL_ISOTHERM_STATE, .class), +// +// THERMAL_ISOTHERM_UPPER_LIMIT(PropertySetEnum.THERMAL_ISOTHERM_UPPER_LIMIT, .class), +// +// THERMAL_ISOTHERM_LOWER_LIMIT(PropertySetEnum.THERMAL_ISOTHERM_LOWER_LIMIT, .class), + + ; + + private final PropertySetEnum property; + + private final Class clazz; + + PropertySetFieldEnum(PropertySetEnum property, Class clazz) { + this.property = property; + this.clazz = clazz; + } + + public PropertySetEnum getProperty() { + return property; + } + + @JsonValue + public String getPropertyName() { + return property.getProperty(); + } + + public Class getClazz() { + return clazz; + } + + public static PropertySetFieldEnum find(String property) { + return Arrays.stream(values()).filter(propertyEnum -> propertyEnum.property.getProperty().equals(property)).findAny() + .orElseThrow(); + } +} diff --git a/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareQueryParam.java b/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareQueryParam.java index 6dc4ad5..ffcc8fb 100644 --- a/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareQueryParam.java +++ b/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareQueryParam.java @@ -1,5 +1,6 @@ package com.dji.sample.manage.model.param; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -18,8 +19,10 @@ import javax.validation.constraints.NotNull; @NoArgsConstructor public class DeviceFirmwareQueryParam { + @JsonProperty("device_name") private String deviceName; + @JsonProperty("product_version") private String productVersion; private Boolean status; @@ -28,5 +31,6 @@ public class DeviceFirmwareQueryParam { private Long page; @NotNull + @JsonProperty("page_size") private Long pageSize; } diff --git a/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareUploadParam.java b/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareUploadParam.java index f48f4f0..deeb67f 100644 --- a/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareUploadParam.java +++ b/src/main/java/com/dji/sample/manage/model/param/DeviceFirmwareUploadParam.java @@ -1,5 +1,6 @@ package com.dji.sample.manage.model.param; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import javax.validation.constraints.NotNull; @@ -14,11 +15,13 @@ import java.util.List; public class DeviceFirmwareUploadParam { @NotNull + @JsonProperty("release_note") private String releaseNote; @NotNull private Boolean status; @NotNull + @JsonProperty("device_name") private List deviceName; } diff --git a/src/main/java/com/dji/sample/manage/model/param/DeviceHmsQueryParam.java b/src/main/java/com/dji/sample/manage/model/param/DeviceHmsQueryParam.java index c35e8bb..35eaca8 100644 --- a/src/main/java/com/dji/sample/manage/model/param/DeviceHmsQueryParam.java +++ b/src/main/java/com/dji/sample/manage/model/param/DeviceHmsQueryParam.java @@ -1,5 +1,6 @@ package com.dji.sample.manage.model.param; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -18,10 +19,13 @@ import java.util.Set; @NoArgsConstructor public class DeviceHmsQueryParam { + @JsonProperty("device_sn") private Set deviceSn; + @JsonProperty("begin_time") private Long beginTime; + @JsonProperty("end_time") private Long endTime; private String language; @@ -30,9 +34,11 @@ public class DeviceHmsQueryParam { private Long page; + @JsonProperty("page_size") private Long pageSize; private Integer level; + @JsonProperty("update_time") private Long updateTime; } diff --git a/src/main/java/com/dji/sample/manage/model/param/DeviceLogsCreateParam.java b/src/main/java/com/dji/sample/manage/model/param/DeviceLogsCreateParam.java index 0c6aea1..7870d79 100644 --- a/src/main/java/com/dji/sample/manage/model/param/DeviceLogsCreateParam.java +++ b/src/main/java/com/dji/sample/manage/model/param/DeviceLogsCreateParam.java @@ -1,6 +1,6 @@ package com.dji.sample.manage.model.param; -import com.dji.sample.manage.model.receiver.LogsFileUpload; +import com.dji.sdk.cloudapi.log.FileUploadStartFile; import lombok.Data; import java.util.List; @@ -17,5 +17,5 @@ public class DeviceLogsCreateParam { private Long happenTime; - private List files; + private List files; } diff --git a/src/main/java/com/dji/sample/manage/model/param/DeviceLogsGetParam.java b/src/main/java/com/dji/sample/manage/model/param/DeviceLogsGetParam.java new file mode 100644 index 0000000..54325a9 --- /dev/null +++ b/src/main/java/com/dji/sample/manage/model/param/DeviceLogsGetParam.java @@ -0,0 +1,19 @@ +package com.dji.sample.manage.model.param; + +import com.dji.sdk.cloudapi.log.LogModuleEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@Data +public class DeviceLogsGetParam { + + @JsonProperty("domain_list") + List domainList; +} diff --git a/src/main/java/com/dji/sample/manage/model/param/DeviceLogsQueryParam.java b/src/main/java/com/dji/sample/manage/model/param/DeviceLogsQueryParam.java index c52a777..5674bb8 100644 --- a/src/main/java/com/dji/sample/manage/model/param/DeviceLogsQueryParam.java +++ b/src/main/java/com/dji/sample/manage/model/param/DeviceLogsQueryParam.java @@ -1,5 +1,6 @@ package com.dji.sample.manage.model.param; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; /** @@ -12,13 +13,17 @@ public class DeviceLogsQueryParam { private Long page; + @JsonProperty("page_size") private Long pageSize; private Integer status; + @JsonProperty("begin_time") private Long beginTime; + @JsonProperty("end_time") private Long endTime; + @JsonProperty("logs_information") private String logsInformation; } diff --git a/src/main/java/com/dji/sample/manage/model/param/DeviceOtaCreateParam.java b/src/main/java/com/dji/sample/manage/model/param/DeviceOtaCreateParam.java deleted file mode 100644 index 12fbb3d..0000000 --- a/src/main/java/com/dji/sample/manage/model/param/DeviceOtaCreateParam.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.dji.sample.manage.model.param; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 1.2 - * @date 2022/8/16 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class DeviceOtaCreateParam { - - private String sn; - - private String productVersion; - - private String fileUrl; - - private String md5; - - private Long fileSize; - - private Integer firmwareUpgradeType; - - private String fileName; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/AlternateLandPointReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/AlternateLandPointReceiver.java deleted file mode 100644 index fa6924e..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/AlternateLandPointReceiver.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.0 - * @date 2022/5/11 - */ -@Data -public class AlternateLandPointReceiver { - - private Double latitude; - - private Double longitude; - - private Double safeLandHeight; - - private Integer isConfigured; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/BackupBatteryReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/BackupBatteryReceiver.java deleted file mode 100644 index 257316d..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/BackupBatteryReceiver.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Data; - -/** - * @author sean - * @version 1.3 - * @date 2022/11/3 - */ -@Data -public class BackupBatteryReceiver { - - private Integer voltage; - - private Float temperature; - - @JsonProperty("switch") - private Integer batterySwitch; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/BasicDeviceProperty.java b/src/main/java/com/dji/sample/manage/model/receiver/BasicDeviceProperty.java index f32273d..c02b546 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/BasicDeviceProperty.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/BasicDeviceProperty.java @@ -1,5 +1,7 @@ package com.dji.sample.manage.model.receiver; +import com.dji.sdk.cloudapi.device.OsdDockDrone; + /** * @author sean * @version 1.3 @@ -11,7 +13,7 @@ public abstract class BasicDeviceProperty { return false; } - public boolean canPublish(String fieldName, OsdSubDeviceReceiver osd) { + public boolean canPublish(OsdDockDrone osd) { return valid(); } } diff --git a/src/main/java/com/dji/sample/manage/model/receiver/BatteryReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/BatteryReceiver.java deleted file mode 100644 index dc0162f..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/BatteryReceiver.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.Data; - -import java.util.List; - -/** - * @author sean - * @version 0.3 - * @date 2022/1/27 - */ -@Data -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) -public class BatteryReceiver { - - private List batteries; - - private Integer capacityPercent; - - private Integer landingPower; - - private Integer remainFlightTime; - - private Integer returnHomePower; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/BatteryStateReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/BatteryStateReceiver.java deleted file mode 100644 index 275adc1..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/BatteryStateReceiver.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.Data; - -/** - * @author sean.zhou - * @version 0.1 - * @date 2021/11/24 - */ -@Data -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) -public class BatteryStateReceiver { - - private String firmwareVersion; - - private Integer index; - - private Integer loopTimes; - - private Integer capacityPercent; - - private String sn; - - private Integer subType; - - private Float temperature; - - private Integer type; - - private Integer voltage; - -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/receiver/BindDeviceReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/BindDeviceReceiver.java deleted file mode 100644 index 7f13246..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/BindDeviceReceiver.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.1 - * @date 2022/6/13 - */ -@Data -public class BindDeviceReceiver { - - private String deviceBindingCode; - - private String organizationId; - - private String deviceCallsign; - - private String sn; - - private String deviceModelKey; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/BindStatusReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/BindStatusReceiver.java deleted file mode 100644 index 61c8477..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/BindStatusReceiver.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 1.1 - * @date 2022/6/14 - */ -@Builder -@Data -@AllArgsConstructor -@NoArgsConstructor -@JsonInclude -public class BindStatusReceiver { - - private String sn; - - private Boolean isDeviceBindOrganization; - - private String organizationId; - - private String organizationName; - - private String deviceCallsign; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/CapacityCameraReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/CapacityCameraReceiver.java index e5321fb..9747533 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/CapacityCameraReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/CapacityCameraReceiver.java @@ -1,8 +1,6 @@ package com.dji.sample.manage.model.receiver; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.dji.sdk.cloudapi.device.PayloadIndex; import lombok.Data; import java.util.List; @@ -13,16 +11,14 @@ import java.util.List; * @version 0.1 */ @Data -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class CapacityCameraReceiver { private Integer availableVideoNumber; private Integer coexistVideoNumberMax; - private String cameraIndex; + private PayloadIndex cameraIndex; - @JsonProperty(value = "video_list") - private List videosList; + private List videoList; } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/receiver/CapacityDeviceReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/CapacityDeviceReceiver.java index 750db59..63edf06 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/CapacityDeviceReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/CapacityDeviceReceiver.java @@ -1,7 +1,5 @@ package com.dji.sample.manage.model.receiver; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; import lombok.Data; import java.util.List; @@ -12,7 +10,6 @@ import java.util.List; * @version 0.1 */ @Data -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class CapacityDeviceReceiver { private String sn; @@ -22,4 +19,5 @@ public class CapacityDeviceReceiver { private Integer coexistVideoNumberMax; private List cameraList; + } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/receiver/CapacityVideoReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/CapacityVideoReceiver.java index 6c17c15..1939641 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/CapacityVideoReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/CapacityVideoReceiver.java @@ -1,7 +1,6 @@ package com.dji.sample.manage.model.receiver; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.dji.sdk.cloudapi.livestream.VideoTypeEnum; import lombok.Data; import java.util.List; @@ -12,12 +11,11 @@ import java.util.List; * @version 0.1 */ @Data -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class CapacityVideoReceiver { private String videoIndex; - private String videoType; + private VideoTypeEnum videoType; - private List switchableVideoTypes; + private List switchableVideoTypes; } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DeviceBasicReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DeviceBasicReceiver.java index fa22b73..423624c 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/DeviceBasicReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/DeviceBasicReceiver.java @@ -1,8 +1,7 @@ package com.dji.sample.manage.model.receiver; +import com.dji.sample.manage.model.dto.DevicePayloadReceiver; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; import lombok.Data; import java.util.List; @@ -14,16 +13,15 @@ import java.util.List; */ @Data @JsonIgnoreProperties(ignoreUnknown = true) -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class DeviceBasicReceiver { - private String controlSource; - private String deviceSn; - private Double homeLatitude; + private String controlSource; + + private Float homeLatitude; - private Double homeLongitude; + private Float homeLongitude; private Integer lowBatteryWarningThreshold; diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DeviceHmsReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DeviceHmsReceiver.java deleted file mode 100644 index cc0d66c..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/DeviceHmsReceiver.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.1 - * @date 2022/7/6 - */ -@Data -public class DeviceHmsReceiver { - - private String code; - - private String deviceType; - - private Integer imminent; - - private Integer inTheSky; - - private Integer level; - - private Integer module; - - private HmsArgsReceiver args; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DevicePayloadReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DevicePayloadReceiver.java deleted file mode 100644 index 830c9d6..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/DevicePayloadReceiver.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.Data; - -/** - * @author sean.zhou - * @date 2021/11/18 - * @version 0.1 - */ -@Data -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) -public class DevicePayloadReceiver { - - private String deviceSn; - - private String controlSource; - - private String payloadIndex; - - private String sn; - -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java index 1fb2789..42c9004 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java @@ -1,6 +1,8 @@ package com.dji.sample.manage.model.receiver; -import com.dji.sample.manage.model.enums.StateSwitchEnum; +import com.dji.sdk.cloudapi.device.DockDistanceLimitStatus; +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.device.SwitchActionEnum; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -20,7 +22,7 @@ import java.util.Objects; @NoArgsConstructor public class DistanceLimitStatusReceiver extends BasicDeviceProperty { - private Integer state; + private SwitchActionEnum state; private Integer distanceLimit; @@ -30,30 +32,20 @@ public class DistanceLimitStatusReceiver extends BasicDeviceProperty { @Override public boolean valid() { - boolean valid = Objects.nonNull(state) || Objects.nonNull(distanceLimit); - if (Objects.nonNull(state)) { - valid = StateSwitchEnum.find(state).isPresent(); + if (Objects.isNull(state) && Objects.isNull(distanceLimit)) { + return false; } if (Objects.nonNull(distanceLimit)) { - valid &= distanceLimit >= DISTANCE_MIN && distanceLimit <= DISTANCE_MAX; + return distanceLimit >= DISTANCE_MIN && distanceLimit <= DISTANCE_MAX; } - return valid; + return true; } @Override - public boolean canPublish(String fieldName, OsdSubDeviceReceiver osd) { - DistanceLimitStatusReceiver distanceLimitStatus = osd.getDistanceLimitStatus(); - switch (fieldName) { - case "state": - return Objects.isNull(distanceLimitStatus.getState()) || - Objects.nonNull(distanceLimitStatus.getState()) && - distanceLimitStatus.getState().intValue() != this.state; - case "distance_limit": - return Objects.isNull(distanceLimitStatus.getDistanceLimit()) || - Objects.nonNull(distanceLimitStatus.getDistanceLimit()) && - distanceLimitStatus.getDistanceLimit().intValue() != this.distanceLimit; - default: - throw new RuntimeException("Property " + fieldName + " does not exist."); - } + public boolean canPublish(OsdDockDrone osd) { + DockDistanceLimitStatus distanceLimitStatus = osd.getDistanceLimitStatus(); + return (Objects.nonNull(distanceLimitStatus.getState()) && distanceLimitStatus.getState() != this.state) + || (Objects.nonNull(distanceLimitStatus.getDistanceLimit()) + && distanceLimitStatus.getDistanceLimit().intValue() != this.distanceLimit); } } diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DockMediaFileDetailReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DockMediaFileDetailReceiver.java deleted file mode 100644 index bd7745a..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/DockMediaFileDetailReceiver.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.1 - * @date 2022/6/17 - */ -@Data -public class DockMediaFileDetailReceiver { - - private Integer remainUpload; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DockSubDeviceReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DockSubDeviceReceiver.java deleted file mode 100644 index 4708ea7..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/DockSubDeviceReceiver.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.0 - * @date 2022/5/11 - */ -@Data -public class DockSubDeviceReceiver { - - private String deviceSn; - - private Integer deviceOnlineStatus; - - private Integer devicePaired; - - private String deviceModelKey; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DockWirelessLinkReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DockWirelessLinkReceiver.java deleted file mode 100644 index 83bfb3f..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/DockWirelessLinkReceiver.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Data; - -/** - * @author sean - * @version 1.3 - * @date 2022/11/3 - */ -@Data -public class DockWirelessLinkReceiver { - - @JsonProperty("4g_freq_band") - private Float fourGFreqBand; - - @JsonProperty("4g_gnd_quality") - private Integer fourGGndQuality; - - @JsonProperty("4g_link_state") - private Integer fourGLinkState; - - @JsonProperty("4g_quality") - private Integer fourGQuality; - - @JsonProperty("4g_uav_quality") - private Integer fourGUavQuality; - - private Integer dongleNumber; - - private Integer linkWorkmode; - - private Float sdrFreqBand; - - private Integer sdrLinkState; - - private Integer sdrQuality; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DroneBatteryMaintenanceInfoReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DroneBatteryMaintenanceInfoReceiver.java deleted file mode 100644 index 1718aca..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/DroneBatteryMaintenanceInfoReceiver.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.4 - * @date 2022/11/3 - */ -@Data -public class DroneBatteryMaintenanceInfoReceiver { - - private Integer maintenanceState; - - private Long maintenanceTimeLeft; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DroneChargeStateReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DroneChargeStateReceiver.java deleted file mode 100644 index 6fe4f49..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/DroneChargeStateReceiver.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.0 - * @date 2022/5/11 - */ -@Data -public class DroneChargeStateReceiver { - - private Integer state; - - private Integer capacityPercent; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/FirmwareProgressExtReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/FirmwareProgressExtReceiver.java deleted file mode 100644 index 9818b93..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/FirmwareProgressExtReceiver.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.4 - * @date 2023/3/30 - */ -@Data -public class FirmwareProgressExtReceiver { - - private Long rate; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/FirmwareVersionReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/FirmwareVersionReceiver.java index a3c2634..94ed706 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/FirmwareVersionReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/FirmwareVersionReceiver.java @@ -1,6 +1,6 @@ package com.dji.sample.manage.model.receiver; -import com.dji.sample.manage.model.enums.DeviceDomainEnum; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/com/dji/sample/manage/model/receiver/HeightLimitReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/HeightLimitReceiver.java index ded4720..a8b8e4f 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/HeightLimitReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/HeightLimitReceiver.java @@ -1,5 +1,6 @@ package com.dji.sample.manage.model.receiver; +import com.dji.sdk.cloudapi.device.OsdDockDrone; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -22,10 +23,15 @@ public class HeightLimitReceiver extends BasicDeviceProperty { private static final int HEIGHT_LIMIT_MIN = 20; - private Integer value; + private Integer heightLimit; @Override public boolean valid() { - return Objects.nonNull(this.value) && this.value >= HEIGHT_LIMIT_MIN && this.value <= HEIGHT_LIMIT_MAX; + return Objects.nonNull(this.heightLimit) && this.heightLimit >= HEIGHT_LIMIT_MIN && this.heightLimit <= HEIGHT_LIMIT_MAX; + } + + @Override + public boolean canPublish(OsdDockDrone osd) { + return heightLimit.intValue() != osd.getHeightLimit(); } } diff --git a/src/main/java/com/dji/sample/manage/model/receiver/HmsArgsReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/HmsArgsReceiver.java deleted file mode 100644 index 2d35a1e..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/HmsArgsReceiver.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.1 - * @date 2022/7/6 - */ -@Data -public class HmsArgsReceiver { - - private Long componentIndex; - - private Integer sensorIndex; - - private Integer alarmId; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/LiveStatusReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/LiveStatusReceiver.java deleted file mode 100644 index 463cbf8..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/LiveStatusReceiver.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.Data; - -/** - * @author sean.zhou - * @version 0.1 - * @date 2021/11/23 - */ -@Data -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) -public class LiveStatusReceiver { - - private Long liveTime; - - private Integer liveTrendline; - - private String videoId; - - private Integer videoQuality; -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/receiver/LiveviewWorldRegionReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/LiveviewWorldRegionReceiver.java deleted file mode 100644 index b6a09e9..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/LiveviewWorldRegionReceiver.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.4 - * @date 2023/3/8 - */ -@Data -public class LiveviewWorldRegionReceiver { - - private Double bottom; - - private Double left; - - private Double right; - - private Double top; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/LogsExtFileReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/LogsExtFileReceiver.java deleted file mode 100644 index 93b15f2..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/LogsExtFileReceiver.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Data; - -/** - * @author sean - * @version 1.2 - * @date 2022/9/9 - */ -@Data -public class LogsExtFileReceiver { - - @JsonProperty("module") - private String deviceModelDomain; - - private Long size; - - private String deviceSn; - - private String key; - - private String fingerprint; - - private LogsProgressReceiver progress; - -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/LogsFile.java b/src/main/java/com/dji/sample/manage/model/receiver/LogsFile.java deleted file mode 100644 index 29d2fa6..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/LogsFile.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 1.2 - * @date 2022/9/7 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class LogsFile { - - private Integer bootIndex; - - private Long endTime; - - private Long startTime; - - private Long size; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/LogsProgressReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/LogsProgressReceiver.java deleted file mode 100644 index f2dad0c..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/LogsProgressReceiver.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.2 - * @date 2022/9/9 - */ -@Data -public class LogsProgressReceiver { - - private Integer currentStep; - - private Integer totalStep; - - private Integer progress; - - private Long finishTime; - - private Float uploadRate; - - private String status; - - private Integer result; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/NetworkStateReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/NetworkStateReceiver.java deleted file mode 100644 index 2aac8ae..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/NetworkStateReceiver.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.0 - * @date 2022/5/11 - */ -@Data -public class NetworkStateReceiver { - - private Integer type; - - private Integer quality; - - private Float rate; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/NightLightsStateReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/NightLightsStateReceiver.java index aae250e..c966b26 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/NightLightsStateReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/NightLightsStateReceiver.java @@ -1,10 +1,8 @@ package com.dji.sample.manage.model.receiver; -import com.dji.sample.manage.model.enums.StateSwitchEnum; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.device.SwitchActionEnum; +import com.fasterxml.jackson.annotation.JsonCreator; import java.util.Objects; @@ -13,16 +11,22 @@ import java.util.Objects; * @version 1.3 * @date 2022/11/25 */ -@EqualsAndHashCode(callSuper = true) -@Data -@AllArgsConstructor -@NoArgsConstructor public class NightLightsStateReceiver extends BasicDeviceProperty { - private Integer value; + private SwitchActionEnum nightLightsState; + + @JsonCreator + public NightLightsStateReceiver(Integer nightLightsState) { + this.nightLightsState = SwitchActionEnum.find(nightLightsState); + } @Override public boolean valid() { - return Objects.nonNull(value) && StateSwitchEnum.find(value).isPresent(); + return Objects.nonNull(nightLightsState); + } + + @Override + public boolean canPublish(OsdDockDrone osd) { + return nightLightsState != osd.getNightLightsState(); } } diff --git a/src/main/java/com/dji/sample/manage/model/receiver/ObstacleAvoidanceReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/ObstacleAvoidanceReceiver.java index 4187d57..cc10413 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/ObstacleAvoidanceReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/ObstacleAvoidanceReceiver.java @@ -1,6 +1,8 @@ package com.dji.sample.manage.model.receiver; -import com.dji.sample.manage.model.enums.StateSwitchEnum; +import com.dji.sdk.cloudapi.device.ObstacleAvoidance; +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.device.SwitchActionEnum; import lombok.Data; import lombok.EqualsAndHashCode; @@ -15,46 +17,21 @@ import java.util.Objects; @Data public class ObstacleAvoidanceReceiver extends BasicDeviceProperty { - private Integer horizon; + private SwitchActionEnum horizon; - private Integer upside; + private SwitchActionEnum upside; - private Integer downside; + private SwitchActionEnum downside; - @Override public boolean valid() { - boolean valid = Objects.nonNull(this.horizon) || Objects.nonNull(this.upside) || Objects.nonNull(this.downside); - - if (Objects.nonNull(this.horizon)) { - valid = StateSwitchEnum.find(horizon).isPresent(); - } - if (Objects.nonNull(this.upside)) { - valid &= StateSwitchEnum.find(upside).isPresent(); - } - if (Objects.nonNull(this.downside)) { - valid &= StateSwitchEnum.find(downside).isPresent(); - } - return valid; + return Objects.nonNull(this.horizon) || Objects.nonNull(this.upside) || Objects.nonNull(this.downside); } @Override - public boolean canPublish(String fieldName, OsdSubDeviceReceiver osd) { - ObstacleAvoidanceReceiver obstacleAvoidance = osd.getObstacleAvoidance(); - switch (fieldName) { - case "horizon": - return Objects.isNull(obstacleAvoidance.getHorizon()) || - Objects.nonNull(obstacleAvoidance.getHorizon()) && - obstacleAvoidance.getHorizon().intValue() != this.horizon; - case "upside": - return Objects.isNull(obstacleAvoidance.getUpside()) || - Objects.nonNull(obstacleAvoidance.getUpside()) && - obstacleAvoidance.getUpside().intValue() != this.upside; - case "downside": - return Objects.isNull(obstacleAvoidance.getDownside()) || - Objects.nonNull(obstacleAvoidance.getDownside()) && - obstacleAvoidance.getDownside().intValue() != this.downside; - default: - throw new RuntimeException("Property " + fieldName + " does not exist."); - } + public boolean canPublish(OsdDockDrone osd) { + ObstacleAvoidance obstacleAvoidance = osd.getObstacleAvoidance(); + return (Objects.nonNull(obstacleAvoidance.getHorizon()) && horizon != obstacleAvoidance.getHorizon()) + || (Objects.nonNull(obstacleAvoidance.getUpside()) && upside != obstacleAvoidance.getUpside()) + || (Objects.nonNull(obstacleAvoidance.getDownside()) && downside != obstacleAvoidance.getDownside()); } } diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OrganizationGetReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OrganizationGetReceiver.java deleted file mode 100644 index 3b92484..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/OrganizationGetReceiver.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.1 - * @date 2022/6/13 - */ -@Data -public class OrganizationGetReceiver { - - private String deviceBindingCode; - - private String organizationId; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OsdCameraReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OsdCameraReceiver.java deleted file mode 100644 index 96de1bc..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/OsdCameraReceiver.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.dji.sample.control.model.enums.CameraModeEnum; -import com.dji.sample.control.model.enums.CameraStateEnum; -import lombok.Data; - -/** - * @author sean - * @version 1.4 - * @date 2023/3/8 - */ -@Data -public class OsdCameraReceiver { - - private CameraModeEnum cameraMode; - - private LiveviewWorldRegionReceiver liveviewWorldRegion; - - private String payloadIndex; - - private CameraStateEnum photoState; - - private Integer recordTime; - - private CameraStateEnum recordingState; - - private Long remainPhotoNum; - - private Long remainRecordDuration; - - private Float zoomFactor; - - private Float irZoomFactor; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OsdDockReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OsdDockReceiver.java deleted file mode 100644 index 8826d35..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/OsdDockReceiver.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.dji.sample.manage.model.enums.DockDrcStateEnum; -import com.dji.sample.manage.model.enums.DockModeCodeEnum; -import lombok.Data; - -/** - * @author sean - * @version 1.3 - * @date 2022/11/3 - */ -@Data -public class OsdDockReceiver { - - private NetworkStateReceiver networkState; - - private Integer droneInDock; - - private DroneChargeStateReceiver droneChargeState; - - private Integer rainfall; - - private Float windSpeed; - - private Float environmentTemperature; - - private Float temperature; - - private Integer humidity; - - private Double latitude; - - private Double longitude; - - private Double height; - - private AlternateLandPointReceiver alternateLandPoint; - - private Long firstPowerOn; - - private PositionStateReceiver positionState; - - private StorageReceiver storage; - - private DockModeCodeEnum modeCode; - - private Integer coverState; - - private Integer supplementLightState; - - private Boolean emergencyStopState; - - private Integer airConditionerMode; - - private Integer batteryStoreMode; - - private Integer alarmState; - - private Integer putterState; - - private DockSubDeviceReceiver subDevice; - - private Integer jobNumber; - - private Long accTime; - - private Long activationTime; - - private DeviceMaintainStatusReceiver maintainStatus; - - private Integer electricSupplyVoltage; - - private Integer workingVoltage; - - private Integer workingCurrent; - - private BackupBatteryReceiver backupBattery; - - private DroneBatteryMaintenanceInfoReceiver droneBatteryMaintenanceInfo; - - private Integer flighttaskStepCode; - - private Integer flighttaskPrepareCapacity; - - private DockMediaFileDetailReceiver mediaFileDetail; - - private DockSdrReceiver sdr; - - private DockWirelessLinkReceiver wirelessLink; - - private DockDrcStateEnum drcState; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OsdGatewayReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OsdGatewayReceiver.java deleted file mode 100644 index 4e0a299..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/OsdGatewayReceiver.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.Data; - -/** - * @author sean.zhou - * @version 0.1 - * @date 2021/11/23 - */ -@Data -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) -public class OsdGatewayReceiver { - - private Double latitude; - - private Double longitude; - - @JsonProperty("capacity_percent") - private Integer remainPower; - - private Integer transmissionSignalQuality; - - private LiveStatusReceiver liveStatus; - - private WirelessLinkStateReceiver wirelessLinkState; -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OsdPayloadReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OsdPayloadReceiver.java deleted file mode 100644 index e4125c6..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/OsdPayloadReceiver.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.0 - * @date 2022/5/6 - */ -@Data -public class OsdPayloadReceiver { - - private String payloadIndex; - - private Double gimbalPitch; - - private Double gimbalRoll; - - private Double gimbalYaw; - - private Double measureTargetAltitude; - - private Double measureTargetDistance; - - private Double measureTargetLatitude; - - private Double measureTargetLongitude; - - private Integer measureTargetErrorState; - - private Integer version; - -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OsdSubDeviceReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OsdSubDeviceReceiver.java deleted file mode 100644 index 148ad9a..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/OsdSubDeviceReceiver.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.dji.sample.manage.model.enums.DeviceModeCodeEnum; -import com.dji.sample.manage.model.enums.DroneRcLostActionEnum; -import com.dji.sample.manage.model.enums.WaylineRcLostActionEnum; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.Data; - -import java.util.List; - -/** - * @author sean.zhou - * @version 0.1 - * @date 2021/11/23 - */ -@Data -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) -public class OsdSubDeviceReceiver { - - private Float attitudeHead; - - private Double attitudePitch; - - private Double attitudeRoll; - - private Double elevation; - - private BatteryReceiver battery; - - private String firmwareVersion; - - private Integer gear; - - private Double height; - - private Double homeDistance; - - private Float horizontalSpeed; - - private Double latitude; - - private Double longitude; - - private DeviceModeCodeEnum modeCode; - - private Double totalFlightDistance; - - private Double totalFlightTime; - - private Float verticalSpeed; - - private Double windDirection; - - private Float windSpeed; - - private PositionStateReceiver positionState; - - private List payloads; - - private StorageReceiver storage; - - private Integer nightLightsState; - - private Integer heightLimit; - - private DistanceLimitStatusReceiver distanceLimitStatus; - - private ObstacleAvoidanceReceiver obstacleAvoidance; - - private Long activationTime; - - private List cameras; - - private DroneRcLostActionEnum rcLostAction; - - private Integer rthAltitude; - - private Integer totalFlightSorties; - - private WaylineRcLostActionEnum exitWaylineWhenRcLost; -} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OutOfControlActionReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OutOfControlActionReceiver.java index 836242e..7b00d69 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/OutOfControlActionReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/OutOfControlActionReceiver.java @@ -1,10 +1,8 @@ package com.dji.sample.manage.model.receiver; -import com.dji.sample.manage.model.enums.DroneRcLostActionEnum; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.device.RcLostActionEnum; +import com.fasterxml.jackson.annotation.JsonCreator; import java.util.Objects; @@ -13,17 +11,22 @@ import java.util.Objects; * @version 1.4 * @date 2023/3/3 */ -@EqualsAndHashCode(callSuper = true) -@Data -@AllArgsConstructor -@NoArgsConstructor public class OutOfControlActionReceiver extends BasicDeviceProperty { - private Integer value; + private RcLostActionEnum rcLostAction; + + @JsonCreator + public OutOfControlActionReceiver(Integer rcLostAction) { + this.rcLostAction = RcLostActionEnum.find(rcLostAction); + } @Override public boolean valid() { - return Objects.nonNull(value) && value >= 0 && value < DroneRcLostActionEnum.values().length; + return Objects.nonNull(rcLostAction); } + @Override + public boolean canPublish(OsdDockDrone osd) { + return rcLostAction != osd.getRcLostAction(); + } } diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OutputLogsExtReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OutputLogsExtReceiver.java deleted file mode 100644 index 84039b7..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/OutputLogsExtReceiver.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -import java.util.List; - -/** - * @author sean - * @version 1.2 - * @date 2022/9/9 - */ -@Data -public class OutputLogsExtReceiver { - - private List files; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OutputLogsProgressReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OutputLogsProgressReceiver.java index 3fd7170..9f5a0a6 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/OutputLogsProgressReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/OutputLogsProgressReceiver.java @@ -1,5 +1,6 @@ package com.dji.sample.manage.model.receiver; +import com.dji.sdk.cloudapi.log.FileUploadProgressExt; import lombok.Data; /** @@ -10,7 +11,7 @@ import lombok.Data; @Data public class OutputLogsProgressReceiver { - private OutputLogsExtReceiver ext; + private FileUploadProgressExt ext; private String status; } diff --git a/src/main/java/com/dji/sample/manage/model/receiver/PositionStateReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/PositionStateReceiver.java deleted file mode 100644 index ad7baec..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/PositionStateReceiver.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.Data; - -/** - * @author sean - * @version 0.3 - * @date 2022/1/27 - */ -@Data -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) -public class PositionStateReceiver { - - private Integer isCalibration; - - private Integer gpsNumber; - - private Integer isFixed; - - private Integer quality; - - private Integer rtkNumber; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/RequestConfigReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/RequestConfigReceiver.java deleted file mode 100644 index e468a6f..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/RequestConfigReceiver.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.3 - * @date 2022/11/10 - */ -@Data -public class RequestConfigReceiver { - - private String configType; - - private String configScope; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/RthAltitudeReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/RthAltitudeReceiver.java index 1727944..0d3bd54 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/RthAltitudeReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/RthAltitudeReceiver.java @@ -1,5 +1,6 @@ package com.dji.sample.manage.model.receiver; +import com.dji.sdk.cloudapi.device.OsdDockDrone; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -18,7 +19,7 @@ import java.util.Objects; @NoArgsConstructor public class RthAltitudeReceiver extends BasicDeviceProperty { - private Integer value; + private Integer rthAltitude; private static final int RTH_ALTITUDE_MAX = 500; @@ -26,7 +27,11 @@ public class RthAltitudeReceiver extends BasicDeviceProperty { @Override public boolean valid() { - return Objects.nonNull(this.value) && this.value >= RTH_ALTITUDE_MIN && this.value <= RTH_ALTITUDE_MAX; + return Objects.nonNull(rthAltitude) && rthAltitude >= RTH_ALTITUDE_MIN && rthAltitude <= RTH_ALTITUDE_MAX; } + @Override + public boolean canPublish(OsdDockDrone osd) { + return rthAltitude != osd.getRthAltitude().intValue(); + } } diff --git a/src/main/java/com/dji/sample/manage/model/receiver/StorageReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/StorageReceiver.java deleted file mode 100644 index 6cb4b75..0000000 --- a/src/main/java/com/dji/sample/manage/model/receiver/StorageReceiver.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.dji.sample.manage.model.receiver; - -import lombok.Data; - -/** - * @author sean - * @version 1.0 - * @date 2022/5/11 - */ -@Data -public class StorageReceiver { - - private Long total; - - private Long used; -} diff --git a/src/main/java/com/dji/sample/manage/model/receiver/WirelessLinkStateReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/WirelessLinkStateReceiver.java index 1efbe3e..797d351 100644 --- a/src/main/java/com/dji/sample/manage/model/receiver/WirelessLinkStateReceiver.java +++ b/src/main/java/com/dji/sample/manage/model/receiver/WirelessLinkStateReceiver.java @@ -1,7 +1,5 @@ package com.dji.sample.manage.model.receiver; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; import lombok.Data; /** @@ -10,7 +8,6 @@ import lombok.Data; * @date 2021/11/23 */ @Data -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class WirelessLinkStateReceiver { private Integer downloadQuality; diff --git a/src/main/java/com/dji/sample/manage/service/ICapacityCameraService.java b/src/main/java/com/dji/sample/manage/service/ICapacityCameraService.java index f47185c..df4d3ee 100644 --- a/src/main/java/com/dji/sample/manage/service/ICapacityCameraService.java +++ b/src/main/java/com/dji/sample/manage/service/ICapacityCameraService.java @@ -30,9 +30,8 @@ public interface ICapacityCameraService { * Save the live capability data of the device. * @param capacityCameraReceivers * @param deviceSn - * @param timestamp */ - void saveCapacityCameraReceiverList(List capacityCameraReceivers, String deviceSn, Long timestamp); + void saveCapacityCameraReceiverList(List capacityCameraReceivers, String deviceSn); /** * Convert the received camera capability object into camera data transfer object. diff --git a/src/main/java/com/dji/sample/manage/service/IDeviceFirmwareService.java b/src/main/java/com/dji/sample/manage/service/IDeviceFirmwareService.java index 72f50ab..aab0992 100644 --- a/src/main/java/com/dji/sample/manage/service/IDeviceFirmwareService.java +++ b/src/main/java/com/dji/sample/manage/service/IDeviceFirmwareService.java @@ -1,12 +1,12 @@ package com.dji.sample.manage.service; -import com.dji.sample.common.model.PaginationData; import com.dji.sample.manage.model.dto.DeviceFirmwareDTO; import com.dji.sample.manage.model.dto.DeviceFirmwareNoteDTO; import com.dji.sample.manage.model.dto.DeviceFirmwareUpgradeDTO; import com.dji.sample.manage.model.param.DeviceFirmwareQueryParam; import com.dji.sample.manage.model.param.DeviceFirmwareUploadParam; -import com.dji.sample.manage.model.param.DeviceOtaCreateParam; +import com.dji.sdk.cloudapi.firmware.OtaCreateDevice; +import com.dji.sdk.common.PaginationData; import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -43,7 +43,7 @@ public interface IDeviceFirmwareService { * @param upgradeDTOS * @return */ - List getDeviceOtaFirmware(String workspaceId, List upgradeDTOS); + List getDeviceOtaFirmware(String workspaceId, List upgradeDTOS); /** * Query firmware version information by page. diff --git a/src/main/java/com/dji/sample/manage/service/IDeviceHmsService.java b/src/main/java/com/dji/sample/manage/service/IDeviceHmsService.java index f5376c1..afbd681 100644 --- a/src/main/java/com/dji/sample/manage/service/IDeviceHmsService.java +++ b/src/main/java/com/dji/sample/manage/service/IDeviceHmsService.java @@ -1,10 +1,8 @@ package com.dji.sample.manage.service; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; import com.dji.sample.manage.model.dto.DeviceHmsDTO; import com.dji.sample.manage.model.param.DeviceHmsQueryParam; -import org.springframework.messaging.MessageHeaders; +import com.dji.sdk.common.PaginationData; /** * @author sean @@ -13,13 +11,6 @@ import org.springframework.messaging.MessageHeaders; */ public interface IDeviceHmsService { - /** - * Handle hms messages. - * @param receiver - * @param headers - */ - void handleHms(CommonTopicReceiver receiver, MessageHeaders headers); - /** * Query hms data by paging according to query parameters. * @param param diff --git a/src/main/java/com/dji/sample/manage/service/IDeviceLogsService.java b/src/main/java/com/dji/sample/manage/service/IDeviceLogsService.java index aded702..b4f6800 100644 --- a/src/main/java/com/dji/sample/manage/service/IDeviceLogsService.java +++ b/src/main/java/com/dji/sample/manage/service/IDeviceLogsService.java @@ -1,13 +1,12 @@ package com.dji.sample.manage.service; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; import com.dji.sample.manage.model.dto.DeviceLogsDTO; import com.dji.sample.manage.model.param.DeviceLogsCreateParam; import com.dji.sample.manage.model.param.DeviceLogsQueryParam; -import com.dji.sample.manage.model.param.LogsFileUpdateParam; -import org.springframework.messaging.MessageHeaders; +import com.dji.sdk.cloudapi.log.FileUploadUpdateRequest; +import com.dji.sdk.cloudapi.log.LogModuleEnum; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; import java.net.URL; import java.util.List; @@ -33,7 +32,7 @@ public interface IDeviceLogsService { * @param domainList * @return */ - ResponseResult getRealTimeLogs(String deviceSn, List domainList); + HttpResultResponse getRealTimeLogs(String deviceSn, List domainList); /** * Add device logs. @@ -53,7 +52,7 @@ public interface IDeviceLogsService { * @param param * @return */ - ResponseResult pushFileUpload(String username, String deviceSn, DeviceLogsCreateParam param); + HttpResultResponse pushFileUpload(String username, String deviceSn, DeviceLogsCreateParam param); /** * Push a request to modify the status of the logs file. @@ -61,7 +60,7 @@ public interface IDeviceLogsService { * @param param * @return */ - ResponseResult pushUpdateFile(String deviceSn, LogsFileUpdateParam param); + HttpResultResponse pushUpdateFile(String deviceSn, FileUploadUpdateRequest param); /** * Delete log records. @@ -70,14 +69,6 @@ public interface IDeviceLogsService { */ void deleteLogs(String deviceSn, String logsId); - /** - * Handle logs file upload progress. - * @param receiver - * @param headers - * @return - */ - CommonTopicReceiver handleFileUploadProgress(CommonTopicReceiver receiver, MessageHeaders headers); - /** * Update status, which is updated when the logs upload succeeds or fails. * @param logsId diff --git a/src/main/java/com/dji/sample/manage/service/IDevicePayloadService.java b/src/main/java/com/dji/sample/manage/service/IDevicePayloadService.java index 11fd20c..d6abfec 100644 --- a/src/main/java/com/dji/sample/manage/service/IDevicePayloadService.java +++ b/src/main/java/com/dji/sample/manage/service/IDevicePayloadService.java @@ -1,8 +1,9 @@ package com.dji.sample.manage.service; +import com.dji.sample.manage.model.dto.DeviceDTO; import com.dji.sample.manage.model.dto.DevicePayloadDTO; -import com.dji.sample.manage.model.receiver.DevicePayloadReceiver; -import com.dji.sample.manage.model.receiver.FirmwareVersionReceiver; +import com.dji.sample.manage.model.dto.DevicePayloadReceiver; +import com.dji.sdk.cloudapi.device.PayloadFirmwareVersion; import java.util.Collection; import java.util.List; @@ -26,7 +27,7 @@ public interface IDevicePayloadService { * @param payloadReceiverList * @return */ - Boolean savePayloadDTOs(List payloadReceiverList); + Boolean savePayloadDTOs(DeviceDTO drone, List payloadReceiverList); /** * Save a payload data. @@ -52,7 +53,7 @@ public interface IDevicePayloadService { * Update the firmware version information of the payload. * @param receiver */ - void updateFirmwareVersion(FirmwareVersionReceiver receiver); + Boolean updateFirmwareVersion(String droneSn, PayloadFirmwareVersion receiver); /** * Delete payload data based on payload sn. @@ -67,4 +68,6 @@ public interface IDevicePayloadService { * @return */ Boolean checkAuthorityPayload(String deviceSn, String payloadIndex); + + void updatePayloadControl(DeviceDTO drone, List payloads); } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/service/IDeviceRedisService.java b/src/main/java/com/dji/sample/manage/service/IDeviceRedisService.java index 074101a..cd1afc2 100644 --- a/src/main/java/com/dji/sample/manage/service/IDeviceRedisService.java +++ b/src/main/java/com/dji/sample/manage/service/IDeviceRedisService.java @@ -1,9 +1,8 @@ package com.dji.sample.manage.service; -import com.dji.sample.component.mqtt.model.EventsOutputProgressReceiver; import com.dji.sample.component.mqtt.model.EventsReceiver; import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.receiver.FirmwareProgressExtReceiver; +import com.dji.sdk.cloudapi.firmware.OtaProgress; import java.util.Optional; import java.util.Set; @@ -42,6 +41,14 @@ public interface IDeviceRedisService { */ Boolean delDeviceOnline(String sn); + /** + * Save the device's osd real-time data. + * @param sn + * @param data + * @return + */ + void setDeviceOsd(String sn, Object data); + /** * Get the device's osd real-time data. * @param sn @@ -50,20 +57,26 @@ public interface IDeviceRedisService { * @return */ Optional getDeviceOsd(String sn, Class clazz); + /** + * Delete the device's osd real-time data. + * @param sn + * @return + */ + Boolean delDeviceOsd(String sn); /** * Save the firmware update progress of the device in redis. * @param sn * @param events */ - void setFirmwareUpgrading(String sn, EventsReceiver> events); + void setFirmwareUpgrading(String sn, EventsReceiver events); /** * Query the firmware update progress of the device in redis. * @param sn * @return */ - Optional>> getFirmwareUpgradingProgress(String sn); + Optional> getFirmwareUpgradingProgress(String sn); /** * Delete the firmware update progress of the device in redis. @@ -92,4 +105,8 @@ public interface IDeviceRedisService { * @return */ Boolean delHmsKeysBySn(String sn); + + void gatewayOffline(String gatewaySn); + + void subDeviceOffline(String deviceSn); } 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 7cf1a17..ec0452c 100644 --- a/src/main/java/com/dji/sample/manage/service/IDeviceService.java +++ b/src/main/java/com/dji/sample/manage/service/IDeviceService.java @@ -1,23 +1,20 @@ package com.dji.sample.manage.service; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.CommonTopicResponse; -import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession; +import com.dji.sample.component.websocket.model.BizCodeEnum; import com.dji.sample.manage.model.dto.DeviceDTO; import com.dji.sample.manage.model.dto.DeviceFirmwareUpgradeDTO; import com.dji.sample.manage.model.dto.TopologyDeviceDTO; -import com.dji.sample.manage.model.enums.DeviceModeCodeEnum; -import com.dji.sample.manage.model.enums.DeviceSetPropertyEnum; -import com.dji.sample.manage.model.enums.DockModeCodeEnum; import com.dji.sample.manage.model.param.DeviceQueryParam; -import com.dji.sample.manage.model.receiver.StatusGatewayReceiver; +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.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; import com.fasterxml.jackson.databind.JsonNode; -import org.springframework.messaging.Message; -import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.Optional; /** @@ -28,44 +25,34 @@ import java.util.Optional; public interface IDeviceService { /** - * The device goes online. - * @param deviceGateway gateway - * @return Whether the online is successful. - */ - Boolean deviceOnline(StatusGatewayReceiver deviceGateway); - - /** - * The device goes offline. - * @param gateway - * @return Whether the offline is successful. + * The aircraft goes offline. + * @param deviceSn aircraft's SN */ - Boolean deviceOffline(StatusGatewayReceiver gateway); + void subDeviceOffline(String deviceSn); /** - * The aircraft goes offline. - * @param deviceSn aircraft's SN - * @return Whether the offline is successful. + * The gateway goes offline. + * @param gatewaySn gateway's SN */ - Boolean subDeviceOffline(String deviceSn); + void gatewayOffline(String gatewaySn); /** - * When the device goes online, it needs to subscribe to topics. - * @param sn device's SN + * Subscribe to the topic of the gateway when the gateway device goes online, and unsubscribe from the topic of the sub-device. + * @param gateway */ - void subscribeTopicOnline(String sn); + void gatewayOnlineSubscribeTopic(GatewayManager gateway); /** - * When the device goes offine, it needs to cancel the subscribed topics. - * @param sn device's SN + * Subscribe to the gateway's and sub-device's topics when the drone comes online. + * @param gateway */ - void unsubscribeTopicOffline(String sn); + void subDeviceOnlineSubscribeTopic(GatewayManager gateway); /** - * Delete all device data according to the SN of the device. - * @param ids device's SN - * @return + * When the gateway device goes offline, unsubscribe from the topics of the gateway and sub-device. + * @param gateway */ - Boolean delDeviceByDeviceSns(List ids); + void offlineUnsubscribeTopic(GatewayManager gateway); /** * Obtain device data according to different query conditions. @@ -74,13 +61,6 @@ public interface IDeviceService { */ List getDevicesByParams(DeviceQueryParam param); - /** - * When you receive a status topic message, you need to reply to it. - * @param sn the target of sn - * @param response - */ - void publishStatusReply(String sn, CommonTopicResponse response); - /** * The business interface on the web side. Get all information about all devices in this workspace. * @param workspaceId @@ -94,13 +74,6 @@ public interface IDeviceService { */ void spliceDeviceTopo(DeviceDTO device); - /** - * Push the topology information to the pilot after one device is online. - * @param sessions The collection of connection objects on the pilot side. - * @param sn - */ - void pushDeviceOnlineTopo(Collection sessions, String sn, String gatewaySn); - /** * Query the information of the device according to the sn of the device. * @param sn device sn @@ -120,26 +93,20 @@ public interface IDeviceService { * it also broadcasts a push of device online, offline and topology update to PILOT via websocket, * and PILOT will get the device topology list again after receiving the push. * @param workspaceId - * @param sn + * @param deviceSn */ - void pushDeviceOfflineTopo(String workspaceId, String sn); + void pushDeviceOfflineTopo(String workspaceId, String deviceSn); /** * When the server receives the request of any device online, offline and topology update in the same workspace, * it also broadcasts a push of device online, offline and topology update to PILOT via websocket, * and PILOT will get the device topology list again after receiving the push. * @param workspaceId - * @param deviceSn * @param gatewaySn + * @param deviceSn */ void pushDeviceOnlineTopo(String workspaceId, String gatewaySn, String deviceSn); - /** - * Handle messages from the osd topic. - * @param message osd - */ - void handleOSD(Message message); - /** * Update the device information. * @param deviceDTO @@ -182,24 +149,16 @@ public interface IDeviceService { * @param upgradeDTOS * @return */ - ResponseResult createDeviceOtaJob(String workspaceId, List upgradeDTOS); + HttpResultResponse createDeviceOtaJob(String workspaceId, List upgradeDTOS); /** * Set the property parameters of the drone. * @param workspaceId * @param dockSn - * @param propertyEnum * @param param + * @return */ - void devicePropertySet(String workspaceId, String dockSn, DeviceSetPropertyEnum propertyEnum, JsonNode param); - - /** - * Set one property parameters of the drone. - * @param topic - * @param propertyEnum - * @param value - */ - void deviceOnePropertySet(String topic, DeviceSetPropertyEnum propertyEnum, Map.Entry value); + int devicePropertySet(String workspaceId, String dockSn, JsonNode param); /** * Check the working status of the dock. @@ -213,7 +172,7 @@ public interface IDeviceService { * @param deviceSn * @return */ - DeviceModeCodeEnum getDeviceMode(String deviceSn); + DroneModeCodeEnum getDeviceMode(String deviceSn); /** * Check if the dock is in drc mode. @@ -229,4 +188,13 @@ public interface IDeviceService { */ Boolean checkAuthorityFlight(String gatewaySn); + Integer saveDevice(DeviceDTO device); + + Boolean saveOrUpdateDevice(DeviceDTO device); + + void pushOsdDataToPilot(String workspaceId, String sn, DeviceOsdHost data); + + void pushOsdDataToWeb(String workspaceId, BizCodeEnum codeEnum, String sn, Object data); + + void updateFlightControl(DeviceDTO gateway, ControlSourceEnum controlSource); } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/service/ILiveStreamService.java b/src/main/java/com/dji/sample/manage/service/ILiveStreamService.java index 2fb7a4f..3bd82e4 100644 --- a/src/main/java/com/dji/sample/manage/service/ILiveStreamService.java +++ b/src/main/java/com/dji/sample/manage/service/ILiveStreamService.java @@ -1,9 +1,8 @@ package com.dji.sample.manage.service; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.manage.model.dto.CapacityDeviceDTO; import com.dji.sample.manage.model.dto.LiveTypeDTO; -import com.dji.sample.manage.model.receiver.LiveCapacityReceiver; +import com.dji.sdk.common.HttpResultResponse; import java.util.List; @@ -21,38 +20,31 @@ public interface ILiveStreamService { */ List getLiveCapacity(String workspaceId); - /** - * Save live capability data. - * @param liveCapacityReceiver - * @param timestamp - */ - void saveLiveCapacity(LiveCapacityReceiver liveCapacityReceiver, Long timestamp); - /** * Initiate a live streaming by publishing mqtt message. * @param liveParam Parameters needed for on-demand. * @return */ - ResponseResult liveStart(LiveTypeDTO liveParam); + HttpResultResponse liveStart(LiveTypeDTO liveParam); /** * Stop the live streaming by publishing mqtt message. * @param videoId * @return */ - ResponseResult liveStop(String videoId); + HttpResultResponse liveStop(String videoId); /** * Readjust the clarity of the live streaming by publishing mqtt messages. * @param liveParam * @return */ - ResponseResult liveSetQuality(LiveTypeDTO liveParam); + HttpResultResponse liveSetQuality(LiveTypeDTO liveParam); /** * Switches the lens of the device during the live streaming. * @param liveParam * @return */ - ResponseResult liveLensChange(LiveTypeDTO liveParam); + HttpResultResponse liveLensChange(LiveTypeDTO liveParam); } diff --git a/src/main/java/com/dji/sample/manage/service/ILogsFileIndexService.java b/src/main/java/com/dji/sample/manage/service/ILogsFileIndexService.java index d350a06..9d7da29 100644 --- a/src/main/java/com/dji/sample/manage/service/ILogsFileIndexService.java +++ b/src/main/java/com/dji/sample/manage/service/ILogsFileIndexService.java @@ -1,8 +1,8 @@ package com.dji.sample.manage.service; import com.dji.sample.manage.model.dto.LogsFileDTO; -import com.dji.sample.manage.model.receiver.LogsFile; -import com.dji.sample.manage.model.receiver.LogsFileUpload; +import com.dji.sample.manage.model.dto.LogsFileUploadDTO; +import com.dji.sdk.cloudapi.log.LogFileIndex; import java.util.List; import java.util.Optional; @@ -22,21 +22,21 @@ public interface ILogsFileIndexService { * @param fileId * @return */ - Boolean insertFileIndex(LogsFile file, String deviceSn, Integer domain, String fileId); + Boolean insertFileIndex(LogFileIndex file, String deviceSn, Integer domain, String fileId); /** * Query logs file upload information based on the file id. * @param fileId * @return */ - Optional getFileIndexByFileId(String fileId); + Optional getFileIndexByFileId(String fileId); /** * Batch query logs file upload information. * @param fileIds * @return */ - List getFileIndexByFileIds(List fileIds); + List getFileIndexByFileIds(List fileIds); /** * Delete log index data based on file id. diff --git a/src/main/java/com/dji/sample/manage/service/ILogsFileService.java b/src/main/java/com/dji/sample/manage/service/ILogsFileService.java index 24db5db..0384ac1 100644 --- a/src/main/java/com/dji/sample/manage/service/ILogsFileService.java +++ b/src/main/java/com/dji/sample/manage/service/ILogsFileService.java @@ -1,8 +1,9 @@ package com.dji.sample.manage.service; import com.dji.sample.manage.model.dto.LogsFileDTO; -import com.dji.sample.manage.model.receiver.LogsExtFileReceiver; -import com.dji.sample.manage.model.receiver.LogsFileUpload; +import com.dji.sample.manage.model.dto.LogsFileUploadDTO; +import com.dji.sdk.cloudapi.log.FileUploadProgressFile; +import com.dji.sdk.cloudapi.log.FileUploadStartFile; import java.net.URL; import java.util.List; @@ -26,7 +27,7 @@ public interface ILogsFileService { * @param logsId * @return */ - List getLogsFileByLogsId(String logsId); + List getLogsFileByLogsId(String logsId); /** * Added logs file. @@ -34,7 +35,7 @@ public interface ILogsFileService { * @param logsId * @return */ - Boolean insertFile(LogsFileUpload file, String logsId); + Boolean insertFile(FileUploadStartFile file, String logsId); /** * Delete logs files. @@ -47,7 +48,7 @@ public interface ILogsFileService { * @param logsId * @param fileReceiver */ - void updateFile(String logsId, LogsExtFileReceiver fileReceiver); + void updateFile(String logsId, FileUploadProgressFile fileReceiver); /** * Update file upload status. diff --git a/src/main/java/com/dji/sample/manage/service/ITSAService.java b/src/main/java/com/dji/sample/manage/service/ITSAService.java deleted file mode 100644 index e11a903..0000000 --- a/src/main/java/com/dji/sample/manage/service/ITSAService.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.dji.sample.manage.service; - -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession; -import com.dji.sample.component.websocket.model.CustomWebSocketMessage; -import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.dto.TelemetryDTO; - -import java.util.Collection; - -/** - * @author sean - * @version 0.3 - * @date 2022/2/21 - */ -public interface ITSAService { - - /** - * Real-time push telemetry data. - * @param workspaceId - * @param osdData - * @param sn - */ - void pushTelemetryData(String workspaceId, Object osdData, String sn); - - /** - * Handle device's osd data. - * @param receiver - * @param webSessions - * @param wsMessage - */ - void handleOSD(CommonTopicReceiver receiver, DeviceDTO device, - Collection webSessions, CustomWebSocketMessage wsMessage); - -} diff --git a/src/main/java/com/dji/sample/manage/service/ITopologyService.java b/src/main/java/com/dji/sample/manage/service/ITopologyService.java index 457e823..012d9c6 100644 --- a/src/main/java/com/dji/sample/manage/service/ITopologyService.java +++ b/src/main/java/com/dji/sample/manage/service/ITopologyService.java @@ -1,6 +1,6 @@ package com.dji.sample.manage.service; -import com.dji.sample.manage.model.dto.TopologyDTO; +import com.dji.sdk.cloudapi.tsa.TopologyList; import java.util.List; import java.util.Optional; @@ -17,12 +17,12 @@ public interface ITopologyService { * @param workspaceId * @return */ - List getDeviceTopology(String workspaceId); + List getDeviceTopology(String workspaceId); /** * Query the topology according to the gateway sn. * @param gatewaySn * @return */ - Optional getDeviceTopologyByGatewaySn(String gatewaySn); + Optional getDeviceTopologyByGatewaySn(String gatewaySn); } diff --git a/src/main/java/com/dji/sample/manage/service/IUserService.java b/src/main/java/com/dji/sample/manage/service/IUserService.java index 133c4c7..7100565 100644 --- a/src/main/java/com/dji/sample/manage/service/IUserService.java +++ b/src/main/java/com/dji/sample/manage/service/IUserService.java @@ -1,9 +1,9 @@ package com.dji.sample.manage.service; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.manage.model.dto.UserDTO; import com.dji.sample.manage.model.dto.UserListDTO; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; import java.util.Optional; @@ -15,7 +15,7 @@ public interface IUserService { * @param workspaceId * @return */ - ResponseResult getUserByUsername(String username, String workspaceId); + HttpResultResponse getUserByUsername(String username, String workspaceId); /** * Verify the username and password to log in. @@ -24,7 +24,7 @@ public interface IUserService { * @param flag * @return */ - ResponseResult userLogin(String username, String password, Integer flag); + HttpResultResponse userLogin(String username, String password, Integer flag); /** * Create a user object containing a new token. diff --git a/src/main/java/com/dji/sample/manage/service/IWorkspaceService.java b/src/main/java/com/dji/sample/manage/service/IWorkspaceService.java index 306760d..eb3bcf5 100644 --- a/src/main/java/com/dji/sample/manage/service/IWorkspaceService.java +++ b/src/main/java/com/dji/sample/manage/service/IWorkspaceService.java @@ -1,9 +1,7 @@ package com.dji.sample.manage.service; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; import com.dji.sample.manage.model.dto.WorkspaceDTO; -import org.springframework.messaging.MessageHeaders; import java.util.Optional; @@ -23,9 +21,4 @@ public interface IWorkspaceService { */ Optional getWorkspaceNameByBindCode(String bindCode); - /** - * Handle the request for obtaining the organization information corresponding to the device binding. - * @param receiver - */ - void replyOrganizationGet(CommonTopicReceiver receiver, MessageHeaders headers); } diff --git a/src/main/java/com/dji/sample/manage/service/impl/AbstractTSAService.java b/src/main/java/com/dji/sample/manage/service/impl/AbstractTSAService.java deleted file mode 100644 index 91e390a..0000000 --- a/src/main/java/com/dji/sample/manage/service/impl/AbstractTSAService.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.dji.sample.manage.service.impl; - -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -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.component.websocket.service.ISendMessageService; -import com.dji.sample.component.websocket.service.IWebSocketManageService; -import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.dto.TelemetryDTO; -import com.dji.sample.manage.model.enums.UserTypeEnum; -import com.dji.sample.manage.service.ITSAService; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Autowired; - -import java.util.Collection; - -/** - * @author sean - * @version 0.3 - * @date 2022/2/21 - */ -public abstract class AbstractTSAService implements ITSAService { - - protected AbstractTSAService tsaService; - - @Autowired - protected ObjectMapper mapper; - - @Autowired - private IWebSocketManageService webSocketManageService; - - public AbstractTSAService(AbstractTSAService tsaService) { - this.tsaService = tsaService; - } - - @Autowired - protected ISendMessageService sendMessageService; - - @Override - public void pushTelemetryData(String workspaceId, Object osdData, String sn) { - // All connected accounts on the pilot side of this workspace. - Collection pilotSessions = webSocketManageService - .getValueWithWorkspaceAndUserType(workspaceId, UserTypeEnum.PILOT.getVal()); - - TelemetryDTO telemetry = TelemetryDTO.builder() - .sn(sn) - .build(); - CustomWebSocketMessage pilotMessage = CustomWebSocketMessage.builder() - .timestamp(System.currentTimeMillis()) - .bizCode(BizCodeEnum.DEVICE_OSD.getCode()) - .data(telemetry) - .build(); - - this.pushTelemetryData(pilotSessions, pilotMessage, osdData); - } - - public abstract void pushTelemetryData(Collection sessions, - CustomWebSocketMessage message, Object Object); - - public abstract void handleOSD(CommonTopicReceiver receiver, DeviceDTO device, - Collection webSessions, CustomWebSocketMessage wsMessage); -} diff --git a/src/main/java/com/dji/sample/manage/service/impl/CameraVideoServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/CameraVideoServiceImpl.java index bfe6de9..23a061a 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/CameraVideoServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/CameraVideoServiceImpl.java @@ -3,9 +3,11 @@ package com.dji.sample.manage.service.impl; import com.dji.sample.manage.model.dto.CapacityVideoDTO; import com.dji.sample.manage.model.receiver.CapacityVideoReceiver; import com.dji.sample.manage.service.ICameraVideoService; +import com.dji.sdk.cloudapi.livestream.VideoTypeEnum; import org.springframework.stereotype.Service; import java.util.UUID; +import java.util.stream.Collectors; /** * @author sean.zhou @@ -13,18 +15,20 @@ import java.util.UUID; * @date 2021/11/19 */ @Service -//@Transactional public class CameraVideoServiceImpl implements ICameraVideoService { @Override public CapacityVideoDTO receiver2Dto(CapacityVideoReceiver receiver) { - CapacityVideoDTO.CapacityVideoDTOBuilder builder = CapacityVideoDTO.builder(); - - if (receiver != null) { - builder.id(UUID.randomUUID().toString()) - .index(receiver.getVideoIndex()) - .type(receiver.getVideoType()) - .switchVideoTypes(receiver.getSwitchableVideoTypes()); + if (null == receiver) { + return null; + } + CapacityVideoDTO.CapacityVideoDTOBuilder builder = CapacityVideoDTO.builder() + .id(UUID.randomUUID().toString()) + .index(receiver.getVideoIndex()) + .type(receiver.getVideoType().getType()); + if (null != receiver.getSwitchableVideoTypes()) { + builder.switchVideoTypes(receiver.getSwitchableVideoTypes().stream() + .map(VideoTypeEnum::getType).collect(Collectors.toList())); } return builder.build(); } diff --git a/src/main/java/com/dji/sample/manage/service/impl/CapacityCameraServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/CapacityCameraServiceImpl.java index ec8ac77..3f0b2da 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/CapacityCameraServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/CapacityCameraServiceImpl.java @@ -4,16 +4,17 @@ import com.dji.sample.component.redis.RedisConst; import com.dji.sample.component.redis.RedisOpsUtils; import com.dji.sample.manage.model.dto.CapacityCameraDTO; import com.dji.sample.manage.model.dto.DeviceDictionaryDTO; -import com.dji.sample.manage.model.enums.DeviceDomainEnum; import com.dji.sample.manage.model.receiver.CapacityCameraReceiver; import com.dji.sample.manage.service.ICameraVideoService; import com.dji.sample.manage.service.ICapacityCameraService; import com.dji.sample.manage.service.IDeviceDictionaryService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.device.PayloadIndex; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @@ -24,7 +25,6 @@ import java.util.stream.Collectors; * @version 0.1 */ @Service -//@Transactional public class CapacityCameraServiceImpl implements ICapacityCameraService { @Autowired @@ -44,37 +44,32 @@ public class CapacityCameraServiceImpl implements ICapacityCameraService { } @Override - public void saveCapacityCameraReceiverList(List capacityCameraReceivers, String deviceSn, Long timestamp) { + public void saveCapacityCameraReceiverList(List capacityCameraReceivers, String deviceSn) { List capacity = capacityCameraReceivers.stream() .map(this::receiver2Dto).collect(Collectors.toList()); RedisOpsUtils.hashSet(RedisConst.LIVE_CAPACITY, deviceSn, capacity); } - @Override public CapacityCameraDTO receiver2Dto(CapacityCameraReceiver receiver) { CapacityCameraDTO.CapacityCameraDTOBuilder builder = CapacityCameraDTO.builder(); if (receiver == null) { return builder.build(); } - int[] indexArr = Arrays.stream(receiver.getCameraIndex().split("-")) - .map(Integer::valueOf) - .mapToInt(Integer::intValue) - .toArray(); + PayloadIndex cameraIndex = receiver.getCameraIndex(); // The cameraIndex consists of type and subType and the index of the payload hanging on the drone. // type-subType-index - if (indexArr.length == 3) { - Optional dictionaryOpt = dictionaryService - .getOneDictionaryInfoByTypeSubType(DeviceDomainEnum.PAYLOAD.getVal(), indexArr[0], indexArr[1]); - dictionaryOpt.ifPresent(dictionary -> - builder.name(dictionary.getDeviceName())); - } + Optional dictionaryOpt = dictionaryService.getOneDictionaryInfoByTypeSubType( + DeviceDomainEnum.PAYLOAD.getDomain(), cameraIndex.getType().getType(), cameraIndex.getSubType().getSubType()); + dictionaryOpt.ifPresent(dictionary -> builder.name(dictionary.getDeviceName())); + return builder .id(UUID.randomUUID().toString()) - .videosList(receiver.getVideosList() + .videosList(receiver.getVideoList() .stream() .map(cameraVideoService::receiver2Dto) + .filter(Objects::nonNull) .collect(Collectors.toList())) - .index(receiver.getCameraIndex()) + .index(receiver.getCameraIndex().toString()) .build(); } } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java index 1747040..edd7114 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java @@ -4,34 +4,36 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.dji.sample.common.model.Pagination; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.impl.MessageSenderServiceImpl; +import com.dji.sample.component.mqtt.model.EventsReceiver; import com.dji.sample.component.oss.model.OssConfiguration; import com.dji.sample.component.oss.service.impl.OssServiceContext; 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.IWebSocketManageService; -import com.dji.sample.component.websocket.service.impl.SendMessageServiceImpl; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; import com.dji.sample.manage.dao.IDeviceFirmwareMapper; import com.dji.sample.manage.model.dto.*; import com.dji.sample.manage.model.entity.DeviceFirmwareEntity; import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.model.param.DeviceFirmwareQueryParam; import com.dji.sample.manage.model.param.DeviceFirmwareUploadParam; -import com.dji.sample.manage.model.param.DeviceOtaCreateParam; -import com.dji.sample.manage.model.receiver.FirmwareProgressExtReceiver; import com.dji.sample.manage.service.IDeviceFirmwareService; import com.dji.sample.manage.service.IDeviceRedisService; import com.dji.sample.manage.service.IFirmwareModelService; -import com.fasterxml.jackson.core.type.TypeReference; +import com.dji.sdk.cloudapi.firmware.FirmwareUpgradeTypeEnum; +import com.dji.sdk.cloudapi.firmware.OtaCreateDevice; +import com.dji.sdk.cloudapi.firmware.OtaProgress; +import com.dji.sdk.cloudapi.firmware.OtaProgressStatusEnum; +import com.dji.sdk.cloudapi.firmware.api.AbstractFirmwareService; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; import com.fasterxml.jackson.databind.ObjectMapper; 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.util.DigestUtils; @@ -58,22 +60,16 @@ import java.util.zip.ZipInputStream; */ @Service @Slf4j -public class DeviceFirmwareServiceImpl implements IDeviceFirmwareService { +public class DeviceFirmwareServiceImpl extends AbstractFirmwareService implements IDeviceFirmwareService { @Autowired private IDeviceFirmwareMapper mapper; - @Autowired - private MessageSenderServiceImpl messageSenderService; - @Autowired private ObjectMapper objectMapper; @Autowired - private SendMessageServiceImpl webSocketMessageService; - - @Autowired - private IWebSocketManageService webSocketManageService; + private IWebSocketMessageService webSocketMessageService; @Autowired private OssServiceContext ossServiceContext; @@ -104,8 +100,8 @@ public class DeviceFirmwareServiceImpl implements IDeviceFirmwareService { } @Override - public List getDeviceOtaFirmware(String workspaceId, List upgradeDTOS) { - List deviceOtaList = new ArrayList<>(); + public List getDeviceOtaFirmware(String workspaceId, List upgradeDTOS) { + List deviceOtaList = new ArrayList<>(); upgradeDTOS.forEach(upgradeDevice -> { boolean exist = deviceRedisService.checkDeviceOnline(upgradeDevice.getSn()); if (!exist) { @@ -116,28 +112,29 @@ public class DeviceFirmwareServiceImpl implements IDeviceFirmwareService { if (firmwareOpt.isEmpty()) { throw new IllegalArgumentException("This firmware version does not exist or is not available."); } - DeviceOtaCreateParam ota = dto2OtaCreateDto(firmwareOpt.get()); + OtaCreateDevice ota = dto2OtaCreateDto(firmwareOpt.get()); ota.setSn(upgradeDevice.getSn()); - ota.setFirmwareUpgradeType(upgradeDevice.getFirmwareUpgradeType()); + ota.setFirmwareUpgradeType(FirmwareUpgradeTypeEnum.find(upgradeDevice.getFirmwareUpgradeType())); deviceOtaList.add(ota); }); return deviceOtaList; } - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_OTA_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) - public CommonTopicReceiver handleOtaProgress(CommonTopicReceiver receiver, MessageHeaders headers) { - String sn = receiver.getGateway(); + @Override + public TopicEventsResponse otaProgress(TopicEventsRequest> request, MessageHeaders headers) { + String sn = request.getGateway(); + + EventsReceiver eventsReceiver = new EventsReceiver() + .setBid(request.getBid()) + .setOutput(request.getData().getOutput()) + .setResult(request.getData().getResult()); - EventsReceiver> eventsReceiver = objectMapper.convertValue(receiver.getData(), - new TypeReference>>(){}); - eventsReceiver.setBid(receiver.getBid()); - EventsOutputProgressReceiver output = eventsReceiver.getOutput(); log.info("SN: {}, {} ===> Upgrading progress: {}", - sn, receiver.getMethod(), output.getProgress().toString()); + sn, request.getMethod(), eventsReceiver.getOutput().getProgress()); - if (eventsReceiver.getResult() != ResponseResult.CODE_SUCCESS) { - log.error("SN: {}, {} ===> Error code: {}", sn, receiver.getMethod(), eventsReceiver.getResult()); + if (!eventsReceiver.getResult().isSuccess()) { + log.error("SN: {}, {} ===> Error: {}", sn, request.getMethod(), eventsReceiver.getResult()); } Optional deviceOpt = deviceRedisService.getDeviceOnline(sn); @@ -145,16 +142,15 @@ public class DeviceFirmwareServiceImpl implements IDeviceFirmwareService { return null; } - EventsResultStatusEnum statusEnum = EventsResultStatusEnum.find(output.getStatus()); + OtaProgressStatusEnum statusEnum = eventsReceiver.getOutput().getStatus(); DeviceDTO device = deviceOpt.get(); - handleProgress(device.getWorkspaceId(), sn, eventsReceiver, statusEnum.getEnd()); - handleProgress(device.getWorkspaceId(), device.getChildDeviceSn(), eventsReceiver, statusEnum.getEnd()); + handleProgress(device.getWorkspaceId(), sn, eventsReceiver, statusEnum.isEnd()); + handleProgress(device.getWorkspaceId(), device.getChildDeviceSn(), eventsReceiver, statusEnum.isEnd()); - return receiver; + return new TopicEventsResponse().setData(MqttReply.success()); } - private void handleProgress(String workspaceId, String sn, - EventsReceiver> events, boolean isEnd) { + private void handleProgress(String workspaceId, String sn, EventsReceiver events, boolean isEnd) { boolean upgrade = deviceRedisService.getFirmwareUpgradingProgress(sn).isPresent(); if (!upgrade) { return; @@ -343,16 +339,15 @@ public class DeviceFirmwareServiceImpl implements IDeviceFirmwareService { .build(); } - private DeviceOtaCreateParam dto2OtaCreateDto(DeviceFirmwareDTO dto) { + private OtaCreateDevice dto2OtaCreateDto(DeviceFirmwareDTO dto) { if (dto == null) { return null; } - return DeviceOtaCreateParam.builder() - .fileSize(dto.getFileSize()) - .fileUrl(ossServiceContext.getObjectUrl(OssConfiguration.bucket, dto.getObjectKey()).toString()) - .fileName(dto.getFileName()) - .md5(dto.getFileMd5()) - .productVersion(dto.getProductVersion()) - .build(); + return new OtaCreateDevice() + .setFileSize(dto.getFileSize()) + .setFileUrl(ossServiceContext.getObjectUrl(OssConfiguration.bucket, dto.getObjectKey()).toString()) + .setFileName(dto.getFileName()) + .setMd5(dto.getFileMd5()) + .setProductVersion(dto.getProductVersion()); } } diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceHmsServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceHmsServiceImpl.java index e201155..3348c64 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/DeviceHmsServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceHmsServiceImpl.java @@ -3,15 +3,8 @@ package com.dji.sample.manage.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.dji.sample.common.model.Pagination; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.component.mqtt.model.ChannelName; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.component.mqtt.model.MapKeyConst; -import com.dji.sample.component.mqtt.model.TopicConst; import com.dji.sample.component.websocket.model.BizCodeEnum; -import com.dji.sample.component.websocket.service.impl.SendMessageServiceImpl; -import com.dji.sample.component.websocket.service.impl.WebSocketManageServiceImpl; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; import com.dji.sample.manage.dao.IDeviceHmsMapper; import com.dji.sample.manage.model.common.HmsJsonUtil; import com.dji.sample.manage.model.common.HmsMessage; @@ -19,20 +12,19 @@ import com.dji.sample.manage.model.dto.DeviceDTO; import com.dji.sample.manage.model.dto.DeviceHmsDTO; import com.dji.sample.manage.model.dto.TelemetryDTO; import com.dji.sample.manage.model.entity.DeviceHmsEntity; -import com.dji.sample.manage.model.enums.DeviceDomainEnum; -import com.dji.sample.manage.model.enums.HmsEnum; import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.model.param.DeviceHmsQueryParam; -import com.dji.sample.manage.model.receiver.DeviceHmsReceiver; -import com.dji.sample.manage.model.receiver.HmsArgsReceiver; import com.dji.sample.manage.service.IDeviceHmsService; import com.dji.sample.manage.service.IDeviceRedisService; -import com.fasterxml.jackson.core.type.TypeReference; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.hms.*; +import com.dji.sdk.cloudapi.hms.api.AbstractHmsService; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; +import com.dji.sdk.mqtt.events.TopicEventsRequest; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.MessageHeaders; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -54,7 +46,7 @@ import java.util.stream.Collectors; @Service @Transactional @Slf4j -public class DeviceHmsServiceImpl implements IDeviceHmsService { +public class DeviceHmsServiceImpl extends AbstractHmsService implements IDeviceHmsService { @Autowired private IDeviceHmsMapper mapper; @@ -63,33 +55,25 @@ public class DeviceHmsServiceImpl implements IDeviceHmsService { private ObjectMapper objectMapper; @Autowired - private SendMessageServiceImpl sendMessageService; - - @Autowired - private WebSocketManageServiceImpl webSocketManageService; + private IWebSocketMessageService sendMessageService; @Autowired private IDeviceRedisService deviceRedisService; private static final Pattern PATTERN_KEY = Pattern.compile( - HmsEnum.FormatKeyEnum.KEY_START + "(" + - Arrays.stream(HmsEnum.FormatKeyEnum.values()) - .map(HmsEnum.FormatKeyEnum::getKey) + Arrays.stream(HmsFormatKeyEnum.values()) + .map(HmsFormatKeyEnum::getKey) .collect(Collectors.joining("|")) + ")"); @Override - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_HMS) - public void handleHms(CommonTopicReceiver receiver, MessageHeaders headers) { - String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString(); - String sn = topic.substring((TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT).length(), - topic.indexOf(TopicConst.EVENTS_SUF)); - + public void hms(TopicEventsRequest response, MessageHeaders headers) { + String sn = response.getFrom(); DeviceHmsEntity entity = DeviceHmsEntity.builder() - .bid(receiver.getBid()) - .tid(receiver.getTid()) - .createTime(receiver.getTimestamp()) + .bid(response.getBid()) + .tid(response.getTid()) + .createTime(response.getTimestamp()) .updateTime(0L) .sn(sn) .build(); @@ -97,8 +81,7 @@ public class DeviceHmsServiceImpl implements IDeviceHmsService { Set hmsMap = deviceRedisService.getAllHmsKeys(sn); List unReadList = new ArrayList<>(); - objectMapper.convertValue(((Map) (receiver.getData())).get(MapKeyConst.LIST), - new TypeReference>() {}) + response.getData().getList() .forEach(hmsReceiver -> { final DeviceHmsEntity hms = entity.clone(); this.fillEntity(hms, hmsReceiver); @@ -133,10 +116,10 @@ public class DeviceHmsServiceImpl implements IDeviceHmsService { .eq(param.getUpdateTime() != null, DeviceHmsEntity::getUpdateTime, param.getUpdateTime()) .eq(param.getLevel() != null, DeviceHmsEntity::getLevel, param.getLevel()) .like(StringUtils.hasText(param.getMessage()) && - HmsEnum.MessageLanguage.ZH.getLanguage().equals(param.getLanguage()), + HmsMessageLanguageEnum.ZH.getLanguage().equals(param.getLanguage()), DeviceHmsEntity::getMessageZh, param.getMessage()) .like(StringUtils.hasText(param.getMessage()) && - HmsEnum.MessageLanguage.EN.getLanguage().equals(param.getLanguage()), + HmsMessageLanguageEnum.EN.getLanguage().equals(param.getLanguage()), DeviceHmsEntity::getMessageEn, param.getMessage()) .orderByDesc(DeviceHmsEntity::getCreateTime); if (param.getPage() == null || param.getPageSize() == null) { @@ -186,23 +169,19 @@ public class DeviceHmsServiceImpl implements IDeviceHmsService { * @param dto * @param receiver */ - private void fillEntity(DeviceHmsEntity dto, DeviceHmsReceiver receiver) { - dto.setLevel(receiver.getLevel()); - dto.setModule(receiver.getModule()); + private void fillEntity(DeviceHmsEntity dto, DeviceHms receiver) { + dto.setLevel(receiver.getLevel().getLevel()); + dto.setModule(receiver.getModule().getModule()); dto.setHmsId(UUID.randomUUID().toString()); - Optional domainEnumOpt = Optional.ofNullable(receiver.getDeviceType()) - .map(type -> type.split("-")).map(type -> type[0]).map(Integer::parseInt).map(DeviceDomainEnum::find); - if (domainEnumOpt.isEmpty()) { - throw new RuntimeException("The device type does not match, please check the data."); - } - if (DeviceDomainEnum.DOCK == domainEnumOpt.get()) { - dto.setHmsKey(HmsEnum.HmsFaqIdEnum.DOCK_TIP.getText() + receiver.getCode()); + DeviceDomainEnum domain = receiver.getDeviceType().getDomain(); + if (DeviceDomainEnum.DOCK == domain) { + dto.setHmsKey(HmsFaqIdEnum.DOCK_TIP.getText() + receiver.getCode()); return; } - StringBuilder key = new StringBuilder(HmsEnum.HmsFaqIdEnum.FPV_TIP.getText()).append(receiver.getCode()); + StringBuilder key = new StringBuilder(HmsFaqIdEnum.FPV_TIP.getText()).append(receiver.getCode()); - if (receiver.getInTheSky() == HmsEnum.IN_THE_SKY.getVal()) { - key.append(HmsEnum.IN_THE_SKY.getText()); + if (receiver.getInTheSky()) { + key.append(HmsInTheSkyEnum.IN_THE_SKY.getText()); } dto.setHmsKey(key.toString()); } @@ -213,7 +192,7 @@ public class DeviceHmsServiceImpl implements IDeviceHmsService { * @param dto * @param args */ - private void fillMessage(DeviceHmsEntity dto, HmsArgsReceiver args) { + private void fillMessage(DeviceHmsEntity dto, DeviceHmsArgs args) { HmsMessage hmsMessage = HmsJsonUtil.get(dto.getHmsKey()); String zh = StringUtils.hasText(hmsMessage.getZh()) ? hmsMessage.getZh() : String.format("未知错误(%s)", dto.getHmsKey()); String en = StringUtils.hasText(hmsMessage.getEn()) ? hmsMessage.getEn() : String.format("Unknown(%s)", dto.getHmsKey());// @@ -228,27 +207,37 @@ public class DeviceHmsServiceImpl implements IDeviceHmsService { * @param hmsArgs * @return */ - private List fillKeyArgs(String l, HmsArgsReceiver hmsArgs) { - List args = new ArrayList<>(); - args.add(Objects.nonNull(hmsArgs.getAlarmId()) ? Long.toHexString(hmsArgs.getAlarmId()) : null); - args.add(Objects.nonNull(hmsArgs.getComponentIndex()) ? String.valueOf(hmsArgs.getComponentIndex() + 1) : null); + private Map fillKeyArgs(String l, DeviceHmsArgs hmsArgs) { + Map args = new HashMap<>(); + args.put(HmsFormatKeyEnum.ALARM_ID.getKey(), Objects.nonNull(hmsArgs.getAlarmId()) ? Long.toHexString(hmsArgs.getAlarmId()) : null); + args.put(HmsFormatKeyEnum.COMPONENT_INDEX.getKey(), + Objects.nonNull(hmsArgs.getComponentIndex()) ? String.valueOf(hmsArgs.getComponentIndex() + 1) : null); if (Objects.nonNull(hmsArgs.getSensorIndex())) { - args.add(String.valueOf(hmsArgs.getSensorIndex() + 1)); + args.put(HmsFormatKeyEnum.INDEX.getKey(), String.valueOf(hmsArgs.getSensorIndex() + 1)); - HmsEnum.HmsBatteryIndexEnum hmsBatteryIndexEnum = HmsEnum.HmsBatteryIndexEnum.find(hmsArgs.getSensorIndex()); - HmsEnum.HmsDockCoverIndexEnum hmsDockCoverIndexEnum = HmsEnum.HmsDockCoverIndexEnum.find(hmsArgs.getSensorIndex()); - HmsEnum.HmsChargingRodIndexEnum hmsChargingRodIndexEnum = HmsEnum.HmsChargingRodIndexEnum.find(hmsArgs.getSensorIndex()); + HmsBatteryIndexEnum hmsBatteryIndexEnum = Optional.ofNullable(hmsArgs.getSensorIndex()) + .filter(arg -> arg <= 1).map(HmsBatteryIndexEnum::find).orElse(null); + HmsDockCoverIndexEnum hmsDockCoverIndexEnum = Optional.ofNullable(hmsArgs.getSensorIndex()) + .filter(arg -> arg <= 1).map(HmsDockCoverIndexEnum::find).orElse(null); + HmsChargingRodIndexEnum hmsChargingRodIndexEnum = Optional.ofNullable(hmsArgs.getSensorIndex()) + .filter(arg -> arg <= 3).map(HmsChargingRodIndexEnum::find).orElse(null); switch (l) { case "zh": - args.add(hmsBatteryIndexEnum.getZh()); - args.add(hmsDockCoverIndexEnum.getZh()); - args.add(hmsChargingRodIndexEnum.getZh()); + args.put(HmsFormatKeyEnum.BATTERY_INDEX.getKey(), Optional.ofNullable(hmsBatteryIndexEnum) + .map(HmsBatteryIndexEnum::getZh).orElse(null)); + args.put(HmsFormatKeyEnum.DOCK_COVER_INDEX.getKey(), Optional.ofNullable(hmsDockCoverIndexEnum) + .map(HmsDockCoverIndexEnum::getZh).orElse(null)); + args.put(HmsFormatKeyEnum.CHARGING_ROD_INDEX.getKey(), Optional.ofNullable(hmsChargingRodIndexEnum) + .map(HmsChargingRodIndexEnum::getZh).orElse(null)); break; case "en": - args.add(hmsBatteryIndexEnum.getEn()); - args.add(hmsDockCoverIndexEnum.getEn()); - args.add(hmsChargingRodIndexEnum.getEn()); + args.put(HmsFormatKeyEnum.BATTERY_INDEX.getKey(), Optional.ofNullable(hmsBatteryIndexEnum) + .map(HmsBatteryIndexEnum::getEn).orElse(null)); + args.put(HmsFormatKeyEnum.DOCK_COVER_INDEX.getKey(), Optional.ofNullable(hmsDockCoverIndexEnum) + .map(HmsDockCoverIndexEnum::getEn).orElse(null)); + args.put(HmsFormatKeyEnum.CHARGING_ROD_INDEX.getKey(), Optional.ofNullable(hmsChargingRodIndexEnum) + .map(HmsChargingRodIndexEnum::getEn).orElse(null)); break; default: break; @@ -265,17 +254,15 @@ public class DeviceHmsServiceImpl implements IDeviceHmsService { * @param hmsArgs * @return */ - private String format(String l, String format, HmsArgsReceiver hmsArgs) { - List args = fillKeyArgs(l, hmsArgs); + private String format(String l, String format, DeviceHmsArgs hmsArgs) { + Map args = fillKeyArgs(l, hmsArgs); List list = parse(format); StringBuilder sb = new StringBuilder(); for (String word : list) { if (!StringUtils.hasText(word)) { continue; } - HmsEnum.FormatKeyEnum keyEnum = HmsEnum.FormatKeyEnum.find(word.substring(1)); - sb.append(HmsEnum.FormatKeyEnum.KEY_START != word.charAt(0) || HmsEnum.FormatKeyEnum.UNKNOWN == keyEnum ? - word : args.get(keyEnum.getIndex())); + sb.append(args.getOrDefault(word, word)); } return sb.toString(); } diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java index a5aca9a..799de27 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java @@ -3,35 +3,39 @@ package com.dji.sample.manage.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.dji.sample.common.model.Pagination; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.IMessageSenderService; +import com.dji.sample.component.mqtt.model.EventsReceiver; 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.component.websocket.service.IWebSocketMessageService; import com.dji.sample.manage.dao.IDeviceLogsMapper; import com.dji.sample.manage.model.dto.*; import com.dji.sample.manage.model.entity.DeviceLogsEntity; -import com.dji.sample.manage.model.enums.*; +import com.dji.sample.manage.model.enums.DeviceLogsStatusEnum; +import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.model.param.DeviceLogsCreateParam; import com.dji.sample.manage.model.param.DeviceLogsQueryParam; -import com.dji.sample.manage.model.param.LogsFileUpdateParam; -import com.dji.sample.manage.model.receiver.*; import com.dji.sample.manage.service.IDeviceLogsService; import com.dji.sample.manage.service.IDeviceRedisService; import com.dji.sample.manage.service.ILogsFileService; import com.dji.sample.manage.service.ITopologyService; -import com.dji.sample.media.model.StsCredentialsDTO; import com.dji.sample.storage.service.IStorageService; -import com.fasterxml.jackson.core.type.TypeReference; +import com.dji.sdk.cloudapi.log.*; +import com.dji.sdk.cloudapi.log.api.AbstractLogService; +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.MessageHeaders; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -53,7 +57,7 @@ import java.util.stream.Collectors; @Service @Transactional @Slf4j -public class DeviceLogsServiceImpl implements IDeviceLogsService { +public class DeviceLogsServiceImpl extends AbstractLogService implements IDeviceLogsService { private static final String LOGS_FILE_SUFFIX = ".tar"; @@ -63,9 +67,6 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService { @Autowired private ITopologyService topologyService; - @Autowired - private IMessageSenderService messageSenderService; - @Autowired private ILogsFileService logsFileService; @@ -76,11 +77,14 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService { private ObjectMapper objectMapper; @Autowired - private ISendMessageService webSocketMessageService; + private IWebSocketMessageService webSocketMessageService; @Autowired private IDeviceRedisService deviceRedisService; + @Autowired + private AbstractLogService abstractLogService; + @Override public PaginationData getUploadedLogs(String deviceSn, DeviceLogsQueryParam param) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() @@ -100,22 +104,20 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService { } @Override - public ResponseResult getRealTimeLogs(String deviceSn, List domainList) { + public HttpResultResponse getRealTimeLogs(String deviceSn, List domainList) { boolean exist = deviceRedisService.checkDeviceOnline(deviceSn); if (!exist) { - return ResponseResult.error("Device is offline."); + return HttpResultResponse.error("Device is offline."); } - ServiceReply> data = messageSenderService.publishServicesTopic( - new TypeReference>() {}, deviceSn, LogsFileMethodEnum.FILE_UPLOAD_LIST.getMethod(), - Map.of(MapKeyConst.MODULE_LIST, domainList)); - - for (LogsFileUpload file : data.getOutput()) { + TopicServicesResponse> response = abstractLogService + .fileuploadList(SDKManager.getDeviceSDK(deviceSn), new FileUploadListRequest().setModuleList(domainList)); + for (FileUploadListFile file : response.getData().getOutput().getFiles()) { if (file.getDeviceSn().isBlank()) { file.setDeviceSn(deviceSn); } } - return ResponseResult.success(new LogsFileUploadList(data.getOutput(), data.getResult())); + return HttpResultResponse.success(response.getData().getOutput()); } @Override @@ -132,7 +134,7 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService { if (!insert) { return ""; } - for (LogsFileUpload file : param.getFiles()) { + for (FileUploadStartFile file : param.getFiles()) { insert = logsFileService.insertFile(file, entity.getLogsId()); if (!insert) { return ""; @@ -144,47 +146,46 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService { @Override - public ResponseResult pushFileUpload(String username, String deviceSn, DeviceLogsCreateParam param) { - StsCredentialsDTO stsCredentials = storageService.getSTSCredentials(); + public HttpResultResponse pushFileUpload(String username, String deviceSn, DeviceLogsCreateParam param) { + StsCredentialsResponse stsCredentials = storageService.getSTSCredentials(); + stsCredentials.getCredentials().setExpire(System.currentTimeMillis() + (stsCredentials.getCredentials().getExpire() - 60) * 1000); LogsUploadCredentialsDTO credentialsDTO = new LogsUploadCredentialsDTO(stsCredentials); // Set the storage name of the file. - List files = param.getFiles(); + List files = param.getFiles(); files.forEach(file -> file.setObjectKey(credentialsDTO.getObjectKeyPrefix() + "/" + UUID.randomUUID().toString() + LOGS_FILE_SUFFIX)); - credentialsDTO.setParams(LogsFileUploadList.builder().files(files).build()); - String bid = UUID.randomUUID().toString(); - ServiceReply reply = messageSenderService.publishServicesTopic( - deviceSn, LogsFileMethodEnum.FILE_UPLOAD_START.getMethod(), credentialsDTO, bid); + credentialsDTO.setParams(new FileUploadStartParam().setFiles(files)); - if (ResponseResult.CODE_SUCCESS != reply.getResult()) { - return ResponseResult.error(String.valueOf(reply.getResult())); - } + TopicServicesResponse response = abstractLogService.fileuploadStart( + SDKManager.getDeviceSDK(deviceSn), new FileUploadStartRequest() + .setCredentials(stsCredentials.getCredentials()) + .setBucket(stsCredentials.getBucket()) + .setEndpoint(stsCredentials.getEndpoint()) + .setFileStoreDir(stsCredentials.getObjectKeyPrefix()) + .setProvider(stsCredentials.getProvider()) + .setRegion(stsCredentials.getRegion()) + .setParams(new FileUploadStartParam().setFiles(files))); - String logsId = this.insertDeviceLogs(bid, username, deviceSn, param); - if (!bid.equals(logsId)) { - return ResponseResult.error("Database insert failed."); + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); } + String id = this.insertDeviceLogs(response.getBid(), username, deviceSn, param); + // Save the status of the log upload. - RedisOpsUtils.hashSet(RedisConst.LOGS_FILE_PREFIX + deviceSn, bid, LogsOutputProgressDTO.builder().logsId(logsId).build()); - return ResponseResult.success(); + RedisOpsUtils.hashSet(RedisConst.LOGS_FILE_PREFIX + deviceSn, id, LogsOutputProgressDTO.builder().logsId(id).build()); + return HttpResultResponse.success(); } @Override - public ResponseResult pushUpdateFile(String deviceSn, LogsFileUpdateParam param) { - LogsFileUpdateMethodEnum method = LogsFileUpdateMethodEnum.find(param.getStatus()); - if (LogsFileUpdateMethodEnum.UNKNOWN == method) { - return ResponseResult.error("Illegal param"); - } - ServiceReply reply = messageSenderService.publishServicesTopic( - deviceSn, LogsFileMethodEnum.FILE_UPLOAD_UPDATE.getMethod(), param); + public HttpResultResponse pushUpdateFile(String deviceSn, FileUploadUpdateRequest param) { + TopicServicesResponse response = abstractLogService.fileuploadUpdate(SDKManager.getDeviceSDK(deviceSn), param); - if (ResponseResult.CODE_SUCCESS != reply.getResult()) { - return ResponseResult.error("Error Code : " + reply.getResult()); + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); } - - return ResponseResult.success(); + return HttpResultResponse.success(); } @Override @@ -194,92 +195,82 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService { logsFileService.deleteFileByLogsId(logsId); } - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FILE_UPLOAD_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) @Override - public CommonTopicReceiver handleFileUploadProgress(CommonTopicReceiver receiver, MessageHeaders headers) { - String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString(); - String sn = topic.substring((TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT).length(), - topic.indexOf(TopicConst.EVENTS_SUF)); - - EventsReceiver eventsReceiver = objectMapper.convertValue(receiver.getData(), - new TypeReference>(){}); - + public TopicEventsResponse fileuploadProgress(TopicEventsRequest> request, MessageHeaders headers) { EventsReceiver webSocketData = new EventsReceiver<>(); - webSocketData.setBid(receiver.getBid()); - webSocketData.setSn(sn); + webSocketData.setBid(request.getBid()); + webSocketData.setSn(request.getGateway()); - Optional deviceOpt = deviceRedisService.getDeviceOnline(sn); + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getGateway()); if (deviceOpt.isEmpty()) { return null; } DeviceDTO device = deviceOpt.get(); + String key = RedisConst.LOGS_FILE_PREFIX + request.getGateway(); try { - OutputLogsProgressReceiver output = eventsReceiver.getOutput(); - EventsResultStatusEnum statusEnum = EventsResultStatusEnum.find(output.getStatus()); + FileUploadProgress output = request.getData().getOutput(); log.info("Logs upload progress: {}", output.toString()); - String key = RedisConst.LOGS_FILE_PREFIX + sn; LogsOutputProgressDTO progress; boolean exist = RedisOpsUtils.checkExist(key); - if (!exist && !statusEnum.getEnd()) { - progress = LogsOutputProgressDTO.builder().logsId(receiver.getBid()).build(); - RedisOpsUtils.hashSet(key, receiver.getBid(), progress); + if (!exist && !output.getStatus().isEnd()) { + progress = LogsOutputProgressDTO.builder().logsId(request.getBid()).build(); + RedisOpsUtils.hashSet(key, request.getBid(), progress); } else if (exist) { - progress = (LogsOutputProgressDTO) RedisOpsUtils.hashGet(key, receiver.getBid()); + progress = (LogsOutputProgressDTO) RedisOpsUtils.hashGet(key, request.getBid()); } else { progress = LogsOutputProgressDTO.builder().build(); } progress.setStatus(output.getStatus()); // If the logs file is empty, delete the cache of this task. - List fileReceivers = output.getExt().getFiles(); + List fileReceivers = output.getExt().getFiles(); if (CollectionUtils.isEmpty(fileReceivers)) { - RedisOpsUtils.del(RedisConst.LOGS_FILE_PREFIX + sn); + RedisOpsUtils.del(key); } // refresh cache. List fileProgressList = new ArrayList<>(); fileReceivers.forEach(file -> { - LogsProgressReceiver logsProgress = file.getProgress(); + LogFileProgress logsProgress = file.getProgress(); if (!StringUtils.hasText(file.getDeviceSn())) { - if (String.valueOf(DeviceDomainEnum.DOCK.getVal()).equals(file.getDeviceModelDomain())) { - file.setDeviceSn(sn); - } else if (String.valueOf(DeviceDomainEnum.SUB_DEVICE.getVal()).equals(file.getDeviceModelDomain())) { + if (LogModuleEnum.DOCK == file.getModule()) { + file.setDeviceSn(request.getGateway()); + } else if (LogModuleEnum.DRONE == file.getModule()) { file.setDeviceSn(device.getChildDeviceSn()); } } fileProgressList.add(LogsProgressDTO.builder() .deviceSn(file.getDeviceSn()) - .deviceModelDomain(file.getDeviceModelDomain()) + .deviceModelDomain(file.getModule().getDomain()) .result(logsProgress.getResult()) - .status(logsProgress.getStatus()) + .status(logsProgress.getStatus().getStatus()) .uploadRate(logsProgress.getUploadRate()) .progress(((logsProgress.getCurrentStep() - 1) * 100 + logsProgress.getProgress()) / logsProgress.getTotalStep()) .build()); }); progress.setFiles(fileProgressList); webSocketData.setOutput(progress); - RedisOpsUtils.hashSet(RedisConst.LOGS_FILE_PREFIX + sn, receiver.getBid(), progress); + RedisOpsUtils.hashSet(RedisConst.LOGS_FILE_PREFIX + request.getGateway(), request.getBid(), progress); // Delete the cache at the end of the task. - if (statusEnum.getEnd()) { - RedisOpsUtils.del(RedisConst.LOGS_FILE_PREFIX + sn); - this.updateLogsStatus(receiver.getBid(), DeviceLogsStatusEnum.find(statusEnum).getVal()); + if (output.getStatus().isEnd()) { + RedisOpsUtils.del(key); + updateLogsStatus(request.getBid(), DeviceLogsStatusEnum.find(output.getStatus()).getVal()); - fileReceivers.forEach(file -> logsFileService.updateFile(receiver.getBid(), file)); + fileReceivers.forEach(file -> logsFileService.updateFile(request.getBid(), file)); } } catch (NullPointerException e) { - this.updateLogsStatus(receiver.getBid(), DeviceLogsStatusEnum.FAILED.getVal()); - - RedisOpsUtils.del(RedisConst.LOGS_FILE_PREFIX + sn); + this.updateLogsStatus(request.getBid(), DeviceLogsStatusEnum.FAILED.getVal()); + RedisOpsUtils.del(key); } webSocketMessageService.sendBatch(device.getWorkspaceId(), UserTypeEnum.WEB.getVal(), BizCodeEnum.FILE_UPLOAD_PROGRESS.getCode(), webSocketData); - return receiver; + return new TopicEventsResponse().setData(MqttReply.success()); } @Override @@ -315,7 +306,7 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService { .status(entity.getStatus()) .logsInformation(entity.getLogsInfo()) .userName(entity.getUsername()) - .deviceLogs(LogsFileUploadList.builder().files(logsFileService.getLogsFileByLogsId(entity.getLogsId())).build()) + .deviceLogs(LogsFileUploadListDTO.builder().files(logsFileService.getLogsFileByLogsId(entity.getLogsId())).build()) .logsProgress(Objects.requireNonNullElse(progress, new LogsOutputProgressDTO()).getFiles()) .deviceTopo(topologyService.getDeviceTopologyByGatewaySn(entity.getDeviceSn()).orElse(null)) .build(); diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java deleted file mode 100644 index e5a596e..0000000 --- a/src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.dji.sample.manage.service.impl; - -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.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.receiver.OsdPayloadReceiver; -import com.dji.sample.manage.model.receiver.OsdSubDeviceReceiver; -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.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * @author sean - * @version 0.3 - * @date 2022/2/21 - */ -@Service -@Slf4j -public class DeviceOSDServiceImpl extends AbstractTSAService { - - protected DeviceOSDServiceImpl(@Autowired @Qualifier("dockOSDServiceImpl") AbstractTSAService tsaService) { - super(tsaService); - } - - @Override - public void pushTelemetryData(Collection sessions, - CustomWebSocketMessage message, Object osdData) { - if (osdData instanceof OsdSubDeviceReceiver) { - OsdSubDeviceReceiver data = (OsdSubDeviceReceiver) osdData; - TelemetryDTO telemetry = message.getData(); - telemetry.setHost(TelemetryDeviceDTO.builder() - .latitude(data.getLatitude()) - .longitude(data.getLongitude()) - .altitude(data.getElevation()) - .attitudeHead(data.getAttitudeHead()) - .elevation(data.getElevation()) - .horizontalSpeed(data.getHorizontalSpeed()) - .verticalSpeed(data.getVerticalSpeed()) - .build()); - - this.sendMessageService.sendBatch(sessions, message); - } - } - @Override - public void handleOSD(CommonTopicReceiver receiver, DeviceDTO device, - Collection webSessions, - CustomWebSocketMessage wsMessage) { - if (DeviceDomainEnum.SUB_DEVICE.getVal() == device.getDomain()) { - wsMessage.setBizCode(BizCodeEnum.DEVICE_OSD.getCode()); - - OsdSubDeviceReceiver data = mapper.convertValue(receiver.getData(), OsdSubDeviceReceiver.class); - List payloadsList = device.getPayloadsList(); - try { - Map receiverData = (Map) 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); - } -} diff --git a/src/main/java/com/dji/sample/manage/service/impl/DevicePayloadServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DevicePayloadServiceImpl.java index 04169bd..5d2e795 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/DevicePayloadServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/DevicePayloadServiceImpl.java @@ -2,31 +2,20 @@ package com.dji.sample.manage.service.impl; 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.component.websocket.service.IWebSocketMessageService; 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.dto.*; 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 com.dji.sdk.cloudapi.device.*; 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; @@ -54,7 +43,7 @@ public class DevicePayloadServiceImpl implements IDevicePayloadService { private ICapacityCameraService capacityCameraService; @Autowired - private ISendMessageService sendMessageService; + private IWebSocketMessageService sendMessageService; @Autowired private IDeviceRedisService deviceRedisService; @@ -80,31 +69,19 @@ public class DevicePayloadServiceImpl implements IDevicePayloadService { } @Override - public Boolean savePayloadDTOs(List payloadReceiverList) { - if (payloadReceiverList.isEmpty()) { - return true; - } - - String deviceSn = payloadReceiverList.get(0).getDeviceSn(); - Optional deviceOpt = deviceRedisService.getDeviceOnline(deviceSn); - if (deviceOpt.isEmpty()) { - return false; - } - DeviceDTO device = deviceOpt.get(); - List payloads = new ArrayList<>(); - - Map controlMap = CollectionUtils.isEmpty(device.getPayloadsList()) ? - Collections.emptyMap() : - device.getPayloadsList().stream() - .collect(Collectors.toMap(DevicePayloadDTO::getPayloadIndex, DevicePayloadDTO::getControlSource)); + public Boolean savePayloadDTOs(DeviceDTO device, List payloadReceiverList) { + Map controlMap = CollectionUtils.isEmpty(device.getPayloadsList()) ? + Collections.emptyMap() : device.getPayloadsList().stream() + .collect(Collectors.toMap(DevicePayloadDTO::getPayloadSn, DevicePayloadDTO::getControlSource)); for (DevicePayloadReceiver payloadReceiver : payloadReceiverList) { + payloadReceiver.setDeviceSn(device.getDeviceSn()); int payloadId = this.saveOnePayloadDTO(payloadReceiver); if (payloadId <= 0) { + log.error("Payload data saving failed."); return false; } - payloads.add(this.receiver2Dto(payloadReceiver)); - if (!controlMap.getOrDefault(payloadReceiver.getPayloadIndex(), "").equals(payloadReceiver.getControlSource())) { + if (controlMap.get(payloadReceiver.getSn()) != payloadReceiver.getControlSource()) { sendMessageService.sendBatch(device.getWorkspaceId(), UserTypeEnum.WEB.getVal(), BizCodeEnum.CONTROL_SOURCE_CHANGE.getCode(), DeviceAuthorityDTO.builder() @@ -115,18 +92,15 @@ public class DevicePayloadServiceImpl implements IDevicePayloadService { } } - if (payloads.isEmpty()) { - payloads = this.getDevicePayloadEntitiesByDeviceSn(deviceSn); - } + List payloads = this.getDevicePayloadEntitiesByDeviceSn(device.getDeviceSn()); device.setPayloadsList(payloads); - deviceRedisService.setDeviceOnline(device); return true; } @Override public Integer saveOnePayloadDTO(DevicePayloadReceiver payloadReceiver) { - return this.saveOnePayloadEntity(payloadDTOConvertToEntity(payloadReceiver)); + return this.saveOnePayloadEntity(receiverConvertToEntity(payloadReceiver)); } @Override @@ -150,46 +124,45 @@ public class DevicePayloadServiceImpl implements IDevicePayloadService { } @Override - public void updateFirmwareVersion(FirmwareVersionReceiver receiver) { - mapper.update(DevicePayloadEntity.builder() - .firmwareVersion(receiver.getFirmwareVersion()) - .build() - , new LambdaUpdateWrapper() - .eq(DevicePayloadEntity::getDeviceSn, receiver.getSn())); + public Boolean updateFirmwareVersion(String droneSn, PayloadFirmwareVersion receiver) { + return mapper.update(DevicePayloadEntity.builder() + .firmwareVersion(receiver.getFirmwareVersion()).build(), + new LambdaUpdateWrapper() + .eq(DevicePayloadEntity::getDeviceSn, droneSn) + .eq(DevicePayloadEntity::getPayloadSn, droneSn + "-" + receiver.getPosition().getPosition()) + ) > 0; } /** * Handle payload data for devices. - * @param payloadReceiverList - * @param headers + * @param drone + * @param payloads */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_PAYLOAD) - public void handleDeviceBasicPayload(List payloadReceiverList, MessageHeaders headers) { - if (payloadReceiverList.isEmpty()) { + public void updatePayloadControl(DeviceDTO drone, List payloads) { + boolean match = payloads.stream().peek(p -> p.setSn(Objects.requireNonNullElse(p.getSn(), + p.getDeviceSn() + "-" + p.getPayloadIndex().getPosition().getPosition()))) + .anyMatch(p -> ControlSourceEnum.UNKNOWN == p.getControlSource()); + if (match) { return; } - 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) { + + if (payloads.isEmpty()) { + drone.setPayloadsList(null); + this.deletePayloadsByDeviceSn(List.of(drone.getDeviceSn())); + deviceRedisService.setDeviceOnline(drone); return; } // Filter unsaved payload information. - Set payloadSns = this.getDevicePayloadEntitiesByDeviceSn(payloadReceiverList.get(0).getDeviceSn()) + Set payloadSns = this.getDevicePayloadEntitiesByDeviceSn(drone.getDeviceSn()) .stream().map(DevicePayloadDTO::getPayloadSn).collect(Collectors.toSet()); - Set newPayloadSns = payloadReceiverList.stream().map(DevicePayloadReceiver::getSn).collect(Collectors.toSet()); + Set newPayloadSns = payloads.stream().map(DevicePayloadReceiver::getSn).collect(Collectors.toSet()); payloadSns.removeAll(newPayloadSns); this.deletePayloadsByPayloadsSn(payloadSns); // Save the new payload information. - boolean isSave = this.savePayloadDTOs(payloadReceiverList); - if (isSave) { - RedisOpsUtils.setWithExpire(key, timestamp, RedisConst.DEVICE_ALIVE_SECOND); - } + boolean isSave = this.savePayloadDTOs(drone, payloads); log.debug("The result of saving the payloads is {}.", isSave); } @@ -205,14 +178,14 @@ public class DevicePayloadServiceImpl implements IDevicePayloadService { @Override public Boolean checkAuthorityPayload(String deviceSn, String payloadIndex) { return deviceRedisService.getDeviceOnline(deviceSn).flatMap(device -> - Optional.of(DeviceDomainEnum.SUB_DEVICE.getVal() == device.getDomain() + Optional.of(DeviceDomainEnum.DRONE == device.getDomain() && !CollectionUtils.isEmpty(device.getPayloadsList()) - && ControlSourceEnum.A.getControlSource() - .equals(device.getPayloadsList().stream() - .filter(payload -> payloadIndex.equals(payload.getPayloadIndex())) + && ControlSourceEnum.A == + device.getPayloadsList().stream() + .filter(payload -> payloadIndex.equals(payload.getPayloadIndex().toString())) .map(DevicePayloadDTO::getControlSource).findAny() - .orElse(ControlSourceEnum.B.getControlSource())))).orElse(true); - + .orElse(ControlSourceEnum.B))) + .orElse(true); } /** @@ -227,8 +200,11 @@ public class DevicePayloadServiceImpl implements IDevicePayloadService { .payloadName(entity.getPayloadName()) .payloadDesc(entity.getPayloadDesc()) .index(entity.getPayloadIndex()) - .payloadIndex(entity.getPayloadType() + "-" + entity.getSubType() + "-" + entity.getPayloadIndex()) - .controlSource(entity.getControlSource()); + .payloadIndex(new PayloadIndex() + .setType(DeviceTypeEnum.find(entity.getPayloadType())) + .setSubType(DeviceSubTypeEnum.find(entity.getSubType())) + .setPosition(PayloadPositionEnum.find(entity.getPayloadIndex()))) + .controlSource(ControlSourceEnum.find(entity.getControlSource())); } return builder.build(); } @@ -238,7 +214,7 @@ public class DevicePayloadServiceImpl implements IDevicePayloadService { * @param dto payload * @return */ - private DevicePayloadEntity payloadDTOConvertToEntity(DevicePayloadReceiver dto) { + private DevicePayloadEntity receiverConvertToEntity(DevicePayloadReceiver dto) { if (dto == null) { return new DevicePayloadEntity(); } @@ -246,27 +222,17 @@ public class DevicePayloadServiceImpl implements IDevicePayloadService { // The cameraIndex consists of type and subType and the index of the payload hanging on the drone. // type-subType-index - String[] payloadIndexArr = dto.getPayloadIndex().split("-"); - try { - int[] arr = Arrays.stream(payloadIndexArr) - .mapToInt(Integer::parseInt) - .toArray(); - - Optional 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]) - .controlSource(dto.getControlSource()); - } catch (NumberFormatException e) { - builder.payloadType(-1) - .subType(-1) - .payloadIndex(-1); - } + Optional dictionaryOpt = dictionaryService.getOneDictionaryInfoByTypeSubType( + DeviceDomainEnum.PAYLOAD.getDomain(), dto.getPayloadIndex().getType().getType(), + dto.getPayloadIndex().getSubType().getSubType()); + dictionaryOpt.ifPresent(dictionary -> + builder.payloadName(dictionary.getDeviceName()) + .payloadDesc(dictionary.getDeviceDesc())); + + builder.payloadType(dto.getPayloadIndex().getType().getType()) + .subType(dto.getPayloadIndex().getSubType().getSubType()) + .payloadIndex(dto.getPayloadIndex().getPosition().getPosition()) + .controlSource(dto.getControlSource().getControlSource()); return builder .payloadSn(dto.getSn()) diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceRedisServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceRedisServiceImpl.java index 4629892..4d01f56 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/DeviceRedisServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceRedisServiceImpl.java @@ -1,12 +1,13 @@ package com.dji.sample.manage.service.impl; -import com.dji.sample.component.mqtt.model.EventsOutputProgressReceiver; import com.dji.sample.component.mqtt.model.EventsReceiver; import com.dji.sample.component.redis.RedisConst; import com.dji.sample.component.redis.RedisOpsUtils; import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.receiver.FirmwareProgressExtReceiver; +import com.dji.sample.manage.service.ICapacityCameraService; import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.firmware.OtaProgress; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Optional; @@ -21,6 +22,9 @@ import java.util.stream.Collectors; @Service public class DeviceRedisServiceImpl implements IDeviceRedisService { + @Autowired + private ICapacityCameraService capacityCameraService; + @Override public Boolean checkDeviceOnline(String sn) { String key = RedisConst.DEVICE_ONLINE_PREFIX + sn; @@ -42,19 +46,29 @@ public class DeviceRedisServiceImpl implements IDeviceRedisService { return RedisOpsUtils.del(RedisConst.DEVICE_ONLINE_PREFIX + sn); } + @Override + public void setDeviceOsd(String sn, Object data) { + RedisOpsUtils.setWithExpire(RedisConst.OSD_PREFIX + sn, data, RedisConst.DEVICE_ALIVE_SECOND); + } + @Override public Optional getDeviceOsd(String sn, Class clazz) { return Optional.ofNullable(clazz.cast(RedisOpsUtils.get(RedisConst.OSD_PREFIX + sn))); } @Override - public void setFirmwareUpgrading(String sn, EventsReceiver> events) { + public Boolean delDeviceOsd(String sn) { + return RedisOpsUtils.del(RedisConst.OSD_PREFIX + sn); + } + + @Override + public void setFirmwareUpgrading(String sn, EventsReceiver events) { RedisOpsUtils.setWithExpire(RedisConst.FIRMWARE_UPGRADING_PREFIX + sn, events, RedisConst.DEVICE_ALIVE_SECOND * 20); } @Override - public Optional>> getFirmwareUpgradingProgress(String sn) { - return Optional.ofNullable((EventsReceiver>) RedisOpsUtils.get(RedisConst.FIRMWARE_UPGRADING_PREFIX + sn)); + public Optional> getFirmwareUpgradingProgress(String sn) { + return Optional.ofNullable((EventsReceiver) RedisOpsUtils.get(RedisConst.FIRMWARE_UPGRADING_PREFIX + sn)); } @Override @@ -77,4 +91,19 @@ public class DeviceRedisServiceImpl implements IDeviceRedisService { public Boolean delHmsKeysBySn(String sn) { return RedisOpsUtils.del(RedisConst.HMS_PREFIX + sn); } + + @Override + public void gatewayOffline(String gatewaySn) { + delDeviceOnline(gatewaySn); + delHmsKeysBySn(gatewaySn); + capacityCameraService.deleteCapacityCameraByDeviceSn(gatewaySn); + } + + @Override + public void subDeviceOffline(String deviceSn) { + delDeviceOnline(deviceSn); + delDeviceOsd(deviceSn); + delHmsKeysBySn(deviceSn); + capacityCameraService.deleteCapacityCameraByDeviceSn(deviceSn); + } } 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 40b5314..f5bbe95 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 @@ -4,53 +4,55 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.dji.sample.common.error.CommonErrorEnum; -import com.dji.sample.common.model.Pagination; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.IMessageSenderService; -import com.dji.sample.component.mqtt.service.IMqttTopicService; -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.mqtt.model.EventsReceiver; import com.dji.sample.component.websocket.model.BizCodeEnum; -import com.dji.sample.component.websocket.model.CustomWebSocketMessage; -import com.dji.sample.component.websocket.service.ISendMessageService; -import com.dji.sample.component.websocket.service.IWebSocketManageService; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; import com.dji.sample.control.model.enums.DroneAuthorityEnum; import com.dji.sample.manage.dao.IDeviceMapper; import com.dji.sample.manage.model.dto.*; import com.dji.sample.manage.model.entity.DeviceEntity; -import com.dji.sample.manage.model.enums.*; -import com.dji.sample.manage.model.param.DeviceOtaCreateParam; +import com.dji.sample.manage.model.enums.DeviceFirmwareStatusEnum; +import com.dji.sample.manage.model.enums.PropertySetFieldEnum; +import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.model.param.DeviceQueryParam; -import com.dji.sample.manage.model.receiver.*; +import com.dji.sample.manage.model.receiver.BasicDeviceProperty; import com.dji.sample.manage.service.*; -import com.fasterxml.jackson.core.type.TypeReference; +import com.dji.sdk.cloudapi.device.*; +import com.dji.sdk.cloudapi.firmware.*; +import com.dji.sdk.cloudapi.firmware.api.AbstractFirmwareService; +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.exception.CloudSDKException; +import com.dji.sdk.mqtt.IMqttTopicService; +import com.dji.sdk.mqtt.MqttGatewayPublish; +import com.dji.sdk.mqtt.events.EventsSubscribe; +import com.dji.sdk.mqtt.osd.OsdSubscribe; +import com.dji.sdk.mqtt.property.PropertySetReplyResultEnum; +import com.dji.sdk.mqtt.property.PropertySetSubscribe; +import com.dji.sdk.mqtt.requests.RequestsSubscribe; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.ServicesSubscribe; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import com.dji.sdk.mqtt.state.StateSubscribe; +import com.dji.sdk.mqtt.status.StatusSubscribe; 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.integration.annotation.ServiceActivator; -import org.springframework.integration.mqtt.support.MqttHeaders; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageHeaders; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import java.io.IOException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; +import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; -import static com.dji.sample.component.mqtt.model.TopicConst.*; - /** * * @author sean.zhou @@ -63,7 +65,7 @@ import static com.dji.sample.component.mqtt.model.TopicConst.*; public class DeviceServiceImpl implements IDeviceService { @Autowired - private IMessageSenderService messageSender; + private MqttGatewayPublish messageSender; @Autowired private IDeviceMapper mapper; @@ -81,14 +83,11 @@ public class DeviceServiceImpl implements IDeviceService { private IDevicePayloadService payloadService; @Autowired - private ISendMessageService sendMessageService; + private IWebSocketMessageService webSocketMessageService; @Autowired private ObjectMapper objectMapper; - @Autowired - private IWebSocketManageService webSocketManageService; - @Autowired private IDeviceFirmwareService deviceFirmwareService; @@ -99,180 +98,99 @@ public class DeviceServiceImpl implements IDeviceService { private IDeviceRedisService deviceRedisService; @Autowired - @Qualifier("gatewayOSDServiceImpl") - private ITSAService tsaService; + private StatusSubscribe statusSubscribe; - private static final List INIT_TOPICS_SUFFIX = List.of( - OSD_SUF, STATE_SUF, SERVICES_SUF + _REPLY_SUF, EVENTS_SUF, PROPERTY_SUF + SET_SUF + _REPLY_SUF); + @Autowired + private StateSubscribe stateSubscribe; - @Override - public Boolean deviceOffline(StatusGatewayReceiver gateway) { - String gatewaySn = gateway.getSn(); - this.subscribeTopicOnline(gatewaySn); + @Autowired + private OsdSubscribe osdSubscribe; - // Only the remote controller is logged in and the aircraft is not connected. - Optional deviceOpt = deviceRedisService.getDeviceOnline(gatewaySn); - if (deviceOpt.isEmpty()) { - Optional gatewayOpt = this.getDeviceBySn(gatewaySn); - if (gatewayOpt.isPresent()) { - DeviceDTO value = gatewayOpt.get(); - value.setChildDeviceSn(null); - deviceRedisService.setDeviceOnline(value); - this.pushDeviceOnlineTopo(value.getWorkspaceId(), gatewaySn, gatewaySn); - return true; - } - - // When connecting for the first time - DeviceEntity gatewayDevice = deviceGatewayConvertToDeviceEntity(gateway); - return onlineSaveDevice(gatewayDevice, null, null).isPresent(); - } + @Autowired + private ServicesSubscribe servicesSubscribe; - DeviceDTO deviceDTO = deviceOpt.get(); - String deviceSn = deviceDTO.getChildDeviceSn(); - if (!StringUtils.hasText(deviceSn)) { - return true; - } + @Autowired + private EventsSubscribe eventsSubscribe; - return subDeviceOffline(deviceSn); - } + @Autowired + private RequestsSubscribe requestsSubscribe; - @Override - public Boolean subDeviceOffline(String deviceSn) { + @Autowired + private PropertySetSubscribe propertySetSubscribe; + + @Autowired + private AbstractPropertyService abstractPropertyService; + @Autowired + private AbstractFirmwareService abstractFirmwareService; + + @Override + public void subDeviceOffline(String deviceSn) { // If no information about this device exists in the cache, the drone is considered to be offline. Optional deviceOpt = deviceRedisService.getDeviceOnline(deviceSn); if (deviceOpt.isEmpty()) { log.debug("The drone is already offline."); - return true; + return; } - DeviceDTO device = deviceOpt.get(); - // Cancel drone-related subscriptions. - this.unsubscribeTopicOffline(deviceSn); - - capacityCameraService.deleteCapacityCameraByDeviceSn(deviceSn); - deviceRedisService.delDeviceOnline(deviceSn); - RedisOpsUtils.del(RedisConst.OSD_PREFIX + deviceSn); - deviceRedisService.delHmsKeysBySn(deviceSn); + try { + gatewayOnlineSubscribeTopic(SDKManager.getDeviceSDK(String.valueOf(deviceOpt.get().getParentSn()))); + } catch (CloudSDKException e) { + log.debug("The gateway is already offline.", e); + } + deviceRedisService.subDeviceOffline(deviceSn); // Publish the latest device topology information in the current workspace. - this.pushDeviceOfflineTopo(device.getWorkspaceId(), deviceSn); - + pushDeviceOfflineTopo(deviceOpt.get().getWorkspaceId(), deviceSn); log.debug("{} offline.", deviceSn); - return true; } @Override - public Boolean deviceOnline(StatusGatewayReceiver deviceGateway) { - String deviceSn = deviceGateway.getSubDevices().get(0).getSn(); - - Optional deviceOpt = deviceRedisService.getDeviceOnline(deviceSn); - Optional gatewayOpt = deviceRedisService.getDeviceOnline(deviceGateway.getSn()); - - if (deviceOpt.isPresent() && gatewayOpt.isPresent()) { - DeviceDTO device = DeviceDTO.builder().loginTime(LocalDateTime.now()).deviceSn(deviceSn).build(); - DeviceDTO gateway = DeviceDTO.builder() - .loginTime(LocalDateTime.now()) - .deviceSn(deviceGateway.getSn()) - .childDeviceSn(deviceSn).build(); - this.updateDevice(gateway); - this.updateDevice(device); - String workspaceId = deviceOpt.get().getWorkspaceId(); - if (StringUtils.hasText(workspaceId)) { - this.subscribeTopicOnline(deviceSn); - this.subscribeTopicOnline(deviceGateway.getSn()); - } - log.warn("{} is already online.", deviceSn); - return true; - } - - List gatewaysList = this.getDevicesByParams( - DeviceQueryParam.builder() - .childSn(deviceSn) - .build()); - gatewaysList.stream() - .filter(gateway -> !gateway.getDeviceSn().equals(deviceGateway.getSn())) - .findAny() - .ifPresent(gateway -> { - gateway.setChildDeviceSn(""); - this.updateDevice(gateway); - }); - - DeviceEntity gateway = deviceGatewayConvertToDeviceEntity(deviceGateway); - Optional gatewayEntityOpt = onlineSaveDevice(gateway, deviceSn, null); - if (gatewayEntityOpt.isEmpty()) { - log.error("Failed to go online, please check the status data or code logic."); - return false; - } - - DeviceEntity subDevice = subDeviceConvertToDeviceEntity(deviceGateway.getSubDevices().get(0)); - Optional subDeviceEntityOpt = onlineSaveDevice(subDevice, null, gateway.getDeviceSn()); - if (subDeviceEntityOpt.isEmpty()) { - log.error("Failed to go online, please check the status data or code logic."); - return false; - } - - subDevice = subDeviceEntityOpt.get(); - gateway = gatewayEntityOpt.get(); - - // dock go online - if (DeviceDomainEnum.DOCK.getVal() == deviceGateway.getDomain() && !subDevice.getBoundStatus()) { - // Directly bind the drone of the dock to the same workspace as the dock. - bindDevice(DeviceDTO.builder().deviceSn(deviceSn).workspaceId(gateway.getWorkspaceId()).build()); - subDevice.setWorkspaceId(gateway.getWorkspaceId()); + public void gatewayOffline(String gatewaySn) { + // If no information about this device exists in the cache, the drone is considered to be offline. + Optional deviceOpt = deviceRedisService.getDeviceOnline(gatewaySn); + if (deviceOpt.isEmpty()) { + log.debug("The gateway is already offline."); + return; } - // Subscribe to topic related to drone devices. - this.subscribeTopicOnline(deviceGateway.getSn()); - this.subscribeTopicOnline(deviceSn); - this.pushDeviceOnlineTopo(subDevice.getWorkspaceId(), deviceGateway.getSn(), deviceSn); - - log.debug("{} online.", subDevice.getDeviceSn()); - return true; - } - - @Override - public void subscribeTopicOnline(String sn) { - String[] subscribedTopic = topicService.getSubscribedTopic(); - for (String s : subscribedTopic) { - // If you have already subscribed to the topic of the device, you do not need to subscribe again. - if (s.contains(sn)) { - return; - } - } - String prefix = THING_MODEL_PRE + PRODUCT + sn; - INIT_TOPICS_SUFFIX.forEach(suffix -> topicService.subscribe(prefix + suffix)); + deviceRedisService.subDeviceOffline(deviceOpt.get().getChildDeviceSn()); + deviceRedisService.gatewayOffline(gatewaySn); + offlineUnsubscribeTopic(SDKManager.getDeviceSDK(gatewaySn)); + // Publish the latest device topology information in the current workspace. + pushDeviceOfflineTopo(deviceOpt.get().getWorkspaceId(), gatewaySn); + log.debug("{} offline.", gatewaySn); } @Override - public void unsubscribeTopicOffline(String sn) { - String prefix = THING_MODEL_PRE + PRODUCT + sn; - INIT_TOPICS_SUFFIX.forEach(suffix -> topicService.unsubscribe(prefix + suffix)); + public void gatewayOnlineSubscribeTopic(GatewayManager gateway) { + statusSubscribe.subscribe(gateway); + stateSubscribe.subscribe(gateway, true); + osdSubscribe.subscribe(gateway, true); + servicesSubscribe.subscribe(gateway); + eventsSubscribe.subscribe(gateway, true); + requestsSubscribe.subscribe(gateway); + propertySetSubscribe.subscribe(gateway); } @Override - public Boolean delDeviceByDeviceSns(List ids) { - if (CollectionUtils.isEmpty(ids)) { - return true; - } - return mapper.delete(new LambdaQueryWrapper() - .in(DeviceEntity::getDeviceSn, ids)) - > 0; + public void subDeviceOnlineSubscribeTopic(GatewayManager gateway) { + statusSubscribe.subscribe(gateway); + stateSubscribe.subscribe(gateway, false); + osdSubscribe.subscribe(gateway, false); + servicesSubscribe.subscribe(gateway); + eventsSubscribe.subscribe(gateway, false); + requestsSubscribe.subscribe(gateway); + propertySetSubscribe.subscribe(gateway); } @Override - public void publishStatusReply(String sn, CommonTopicResponse response) { - Map result = new ConcurrentHashMap<>(1); - result.put("result", 0); - response.setData(result); - - messageSender.publish( - new StringBuilder() - .append(BASIC_PRE) - .append(PRODUCT) - .append(sn) - .append(STATUS_SUF) - .append(_REPLY_SUF) - .toString(), - response); + public void offlineUnsubscribeTopic(GatewayManager gateway) { + statusSubscribe.unsubscribe(gateway); + stateSubscribe.unsubscribe(gateway); + osdSubscribe.unsubscribe(gateway); + servicesSubscribe.unsubscribe(gateway); + eventsSubscribe.unsubscribe(gateway); + requestsSubscribe.unsubscribe(gateway); + propertySetSubscribe.unsubscribe(gateway); } @Override @@ -307,11 +225,11 @@ public class DeviceServiceImpl implements IDeviceService { List devicesList = this.getDevicesByParams( DeviceQueryParam.builder() .workspaceId(workspaceId) - .domains(List.of(DeviceDomainEnum.GATEWAY.getVal(), DeviceDomainEnum.DOCK.getVal())) + .domains(List.of(DeviceDomainEnum.REMOTER_CONTROL.getDomain(), DeviceDomainEnum.DOCK.getDomain())) .build()); devicesList.stream() - .filter(gateway -> DeviceDomainEnum.DOCK.getVal() == gateway.getDomain() || + .filter(gateway -> DeviceDomainEnum.DOCK == gateway.getDomain() || deviceRedisService.checkDeviceOnline(gateway.getDeviceSn())) .forEach(this::spliceDeviceTopo); @@ -338,7 +256,7 @@ public class DeviceServiceImpl implements IDeviceService { @Override public Optional getDeviceTopoForPilot(String sn) { - if (sn.isBlank()) { + if (!StringUtils.hasText(sn)) { return Optional.empty(); } List topologyDeviceList = this.getDevicesByParams( @@ -354,263 +272,78 @@ public class DeviceServiceImpl implements IDeviceService { return Optional.of(topologyDeviceList.get(0)); } - @Override - public void pushDeviceOnlineTopo(Collection sessions, String sn, String gatewaySn) { - - CustomWebSocketMessage pilotMessage = - CustomWebSocketMessage.builder() - .timestamp(System.currentTimeMillis()) - .bizCode(BizCodeEnum.DEVICE_ONLINE.getCode()) - .data(new TopologyDeviceDTO()) - .build(); - - this.getDeviceTopoForPilot(sn) - .ifPresent(pilotMessage::setData); - pilotMessage.getData().setOnlineStatus(deviceRedisService.checkDeviceOnline(sn)); - pilotMessage.getData().setGatewaySn(gatewaySn.equals(sn) ? "" : gatewaySn); - - sendMessageService.sendBatch(sessions, pilotMessage); - } - @Override public TopologyDeviceDTO deviceConvertToTopologyDTO(DeviceDTO device) { - TopologyDeviceDTO.TopologyDeviceDTOBuilder builder = TopologyDeviceDTO.builder(); - - if (device != null) { - builder.sn(device.getDeviceSn()) - .deviceCallsign(device.getNickname()) - .deviceModel(DeviceModelDTO.builder() - .domain(String.valueOf(device.getDomain())) - .subType(String.valueOf(device.getSubType())) - .type(String.valueOf(device.getType())) - .key(device.getDomain() + "-" + device.getType() + "-" + device.getSubType()) - .build()) - .iconUrls(device.getIconUrl()) - .onlineStatus(deviceRedisService.checkDeviceOnline(device.getDeviceSn())) - .boundStatus(device.getBoundStatus()) - .model(device.getDeviceName()) - .userId(device.getUserId()) - .domain(device.getDomain()) - .build(); + if (device == null) { + return null; } - return builder.build(); + return new TopologyDeviceDTO() + .setSn(device.getDeviceSn()) + .setDeviceCallsign(device.getNickname()) + .setDeviceModel(new TopologyDeviceModel() + .setDomain(device.getDomain()) + .setSubType(device.getSubType()) + .setType(device.getType()) + .setDeviceModelKey(DeviceEnum.find(device.getDomain(), device.getType(), device.getSubType()))) + .setIconUrls(device.getIconUrl()) + .setOnlineStatus(deviceRedisService.checkDeviceOnline(device.getDeviceSn())) + .setUserCallsign(device.getNickname()) + .setBoundStatus(device.getBoundStatus()) + .setModel(device.getDeviceName()) + .setUserId(device.getUserId()) + .setDomain(device.getDomain()) + .setGatewaySn(device.getParentSn()); } @Override - public void pushDeviceOnlineTopo(String workspaceId, String gatewaySn, String deviceSn) { - - // All connected accounts in this workspace. - Collection allSessions = webSocketManageService.getValueWithWorkspace(workspaceId); - - if (!gatewaySn.equals(deviceSn)) { - this.pushDeviceOnlineTopo(allSessions, deviceSn, gatewaySn); - this.pushDeviceUpdateTopo(allSessions, deviceSn); - } - this.pushDeviceOnlineTopo(allSessions, gatewaySn, gatewaySn); - this.pushDeviceUpdateTopo(allSessions, gatewaySn); + public void pushDeviceOfflineTopo(String workspaceId, String deviceSn) { + webSocketMessageService.sendBatch( + workspaceId, null, com.dji.sdk.websocket.BizCodeEnum.DEVICE_OFFLINE.getCode(), + new TopologyDeviceDTO().setSn(deviceSn).setOnlineStatus(false)); } @Override - public void pushDeviceOfflineTopo(String workspaceId, String sn) { - // All connected accounts of this workspace. - Collection allSessions = webSocketManageService - .getValueWithWorkspace(workspaceId); - - this.pushDeviceOfflineTopo(allSessions, sn); - this.pushDeviceUpdateTopo(allSessions, sn); + public void pushDeviceOnlineTopo(String workspaceId, String gatewaySn, String deviceSn) { + webSocketMessageService.sendBatch( + workspaceId, null, com.dji.sdk.websocket.BizCodeEnum.DEVICE_ONLINE.getCode(), + getDeviceTopoForPilot(deviceSn).orElseGet(TopologyDeviceDTO::new).setGatewaySn(gatewaySn)); } @Override - @ServiceActivator(inputChannel = ChannelName.INBOUND_OSD) - public void handleOSD(Message message) { - String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC).toString(); - byte[] payload = (byte[])message.getPayload(); - CommonTopicReceiver receiver; - try { - String from = topic.substring((THING_MODEL_PRE + PRODUCT).length(), - topic.indexOf(OSD_SUF)); - - Optional deviceOpt = deviceRedisService.getDeviceOnline(from); - - if (deviceOpt.isEmpty()) { - deviceOpt = this.getDeviceBySn(from); - if (deviceOpt.isEmpty()) { - log.error("Please restart the drone."); - return; - } - - if (!StringUtils.hasText(deviceOpt.get().getWorkspaceId())) { - this.unsubscribeTopicOffline(from); - return; - } - deviceRedisService.setDeviceOnline(deviceOpt.get()); - this.subscribeTopicOnline(from); - } - DeviceDTO device = deviceOpt.get(); - deviceRedisService.setDeviceOnline(device); - - receiver = objectMapper.readValue(payload, CommonTopicReceiver.class); - - CustomWebSocketMessage wsMessage = CustomWebSocketMessage.builder() - .timestamp(System.currentTimeMillis()) - .data(TelemetryDTO.builder().sn(from).build()) - .build(); - - Collection webSessions = webSocketManageService - .getValueWithWorkspaceAndUserType( - device.getWorkspaceId(), UserTypeEnum.WEB.getVal()); - - - tsaService.handleOSD(receiver, device, webSessions, wsMessage); - - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Notify the pilot side that there is an update of the device topology. - * @param sessions - * @param deviceSn - */ - private void pushDeviceUpdateTopo(Collection sessions, String deviceSn) { - - CustomWebSocketMessage pilotMessage = - CustomWebSocketMessage.builder() - .timestamp(System.currentTimeMillis()) - .bizCode(BizCodeEnum.DEVICE_UPDATE_TOPO.getCode()) - .data(new TopologyDeviceDTO()) - .build(); - sendMessageService.sendBatch(sessions, pilotMessage); + public void pushOsdDataToPilot(String workspaceId, String sn, DeviceOsdHost data) { + webSocketMessageService.sendBatch( + workspaceId, UserTypeEnum.PILOT.getVal(), com.dji.sdk.websocket.BizCodeEnum.DEVICE_OSD.getCode(), + new DeviceOsdWsResponse() + .setSn(sn) + .setHost(data)); } - /** - * Notify the pilot side that device is offline and needs to reacquire topology information. - * @param sessions - * @param sn - */ - private void pushDeviceOfflineTopo(Collection sessions, String sn) { - CustomWebSocketMessage pilotMessage = - CustomWebSocketMessage.builder() - .timestamp(System.currentTimeMillis()) - .bizCode(BizCodeEnum.DEVICE_OFFLINE.getCode()) - .data(TopologyDeviceDTO.builder() - .sn(sn) - .onlineStatus(false) - .build()) - .build(); - sendMessageService.sendBatch(sessions, pilotMessage); + @Override + public void pushOsdDataToWeb(String workspaceId, BizCodeEnum codeEnum, String sn, Object data) { + webSocketMessageService.sendBatch( + workspaceId, UserTypeEnum.WEB.getVal(), codeEnum.getCode(), TelemetryDTO.builder().sn(sn).host(data).build()); } /** * Save the device information and update the information directly if the device already exists. - * @param entity + * @param device * @return */ - private Optional saveDevice(DeviceEntity entity) { - DeviceEntity deviceEntity = mapper.selectOne( + public Boolean saveOrUpdateDevice(DeviceDTO device) { + int count = mapper.selectCount( new LambdaQueryWrapper() - .eq(DeviceEntity::getDeviceSn, entity.getDeviceSn())); - // Update the information directly if the device already exists. - if (deviceEntity != null) { - if (deviceEntity.getDeviceName().equals(entity.getNickname())) { - entity.setNickname(null); - } - entity.setId(deviceEntity.getId()); - mapper.updateById(entity); - fillNullField(entity, deviceEntity); - return Optional.of(entity); - } - return mapper.insert(entity) > 0 ? Optional.of(entity) : Optional.empty(); - } - - private void fillNullField(DeviceEntity entity, DeviceEntity oldEntity) { - if (Objects.isNull(entity) || Objects.isNull(oldEntity)) { - return; - } - if (Objects.isNull(entity.getWorkspaceId())) { - entity.setWorkspaceId(oldEntity.getWorkspaceId()); - } - if (Objects.isNull(entity.getUserId())) { - entity.setUserId(oldEntity.getUserId()); - } - if (Objects.isNull(entity.getChildSn())) { - entity.setChildSn(oldEntity.getChildSn()); - } - if (Objects.isNull(entity.getBoundStatus())) { - entity.setBoundStatus(oldEntity.getBoundStatus()); - } - if (Objects.isNull(entity.getBoundTime())) { - entity.setBoundTime(oldEntity.getBoundTime()); - } - if (Objects.isNull(entity.getFirmwareVersion())) { - entity.setFirmwareVersion(oldEntity.getFirmwareVersion()); - } - if (Objects.isNull(entity.getDeviceIndex())) { - entity.setDeviceIndex(oldEntity.getDeviceIndex()); - } - } - - /** - * Convert the received gateway device object into a database entity object. - * @param gateway - * @return - */ - private DeviceEntity deviceGatewayConvertToDeviceEntity(StatusGatewayReceiver gateway) { - if (gateway == null) { - return new DeviceEntity(); - } - DeviceEntity.DeviceEntityBuilder builder = DeviceEntity.builder(); - - // Query the model information of this gateway device. - Optional dictionaryOpt = dictionaryService - .getOneDictionaryInfoByTypeSubType(Objects.nonNull(gateway.getDomain()) ? - gateway.getDomain() : DeviceDomainEnum.GATEWAY.getVal(), - gateway.getType(), gateway.getSubType()); - - dictionaryOpt.ifPresent(entity -> - builder.deviceName(entity.getDeviceName()) - .nickname(entity.getDeviceName()) - .deviceDesc(entity.getDeviceDesc())); - - return builder - .deviceSn(gateway.getSn()) - .subType(gateway.getSubType()) - .deviceType(gateway.getType()) - .version(gateway.getVersion()) - .domain(gateway.getDomain() != null ? - gateway.getDomain() : DeviceDomainEnum.GATEWAY.getVal()) - .deviceIndex(gateway.getSubDevices().isEmpty() ? null : gateway.getSubDevices().get(0).getIndex()) - .build(); + .eq(DeviceEntity::getDeviceSn, device.getDeviceSn())); + return count > 0 ? updateDevice(device) : saveDevice(device) > 0; } /** - * Convert the received drone device object into a database entity object. + * Save the device information. * @param device * @return */ - private DeviceEntity subDeviceConvertToDeviceEntity(StatusSubDeviceReceiver device) { - if (device == null) { - return new DeviceEntity(); - } - DeviceEntity.DeviceEntityBuilder builder = DeviceEntity.builder(); - - // Query the model information of this drone device. - Optional dictionaryOpt = dictionaryService - .getOneDictionaryInfoByTypeSubType(DeviceDomainEnum.SUB_DEVICE.getVal(), device.getType(), device.getSubType()); - - dictionaryOpt.ifPresent(dictionary -> - builder.deviceName(dictionary.getDeviceName()) - .nickname(dictionary.getDeviceName()) - .deviceDesc(dictionary.getDeviceDesc())); - - return builder - .deviceSn(device.getSn()) - .deviceType(device.getType()) - .subType(device.getSubType()) - .version(device.getVersion()) - .domain(DeviceDomainEnum.SUB_DEVICE.getVal()) - .build(); + public Integer saveDevice(DeviceDTO device) { + DeviceEntity entity = deviceDTO2Entity(device); + return mapper.insert(entity) > 0 ? entity.getId() : -1; } /** @@ -622,34 +355,39 @@ public class DeviceServiceImpl implements IDeviceService { if (entity == null) { return null; } - DeviceDTO deviceDTO = DeviceDTO.builder() - .deviceSn(entity.getDeviceSn()) - .childDeviceSn(entity.getChildSn()) - .deviceName(entity.getDeviceName()) - .deviceDesc(entity.getDeviceDesc()) - .controlSource(entity.getDeviceIndex()) - .workspaceId(entity.getWorkspaceId()) - .type(entity.getDeviceType()) - .subType(entity.getSubType()) - .domain(entity.getDomain()) - .iconUrl(IconUrlDTO.builder() - .normalUrl(entity.getUrlNormal()) - .selectUrl(entity.getUrlSelect()) - .build()) - .boundStatus(entity.getBoundStatus()) - .loginTime(entity.getLoginTime() != null ? - LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getLoginTime()), ZoneId.systemDefault()) - : null) - .boundTime(entity.getBoundTime() != null ? - LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getBoundTime()), ZoneId.systemDefault()) - : null) - .nickname(entity.getNickname()) - .firmwareVersion(entity.getFirmwareVersion()) - .workspaceName(entity.getWorkspaceId() != null ? - workspaceService.getWorkspaceByWorkspaceId(entity.getWorkspaceId()) - .map(WorkspaceDTO::getWorkspaceName).orElse("") : "") - .firmwareStatus(DeviceFirmwareStatusEnum.NOT_UPGRADE.getVal()).build(); - + DeviceDTO.DeviceDTOBuilder builder = DeviceDTO.builder(); + try { + builder + .deviceSn(entity.getDeviceSn()) + .childDeviceSn(entity.getChildSn()) + .deviceName(entity.getDeviceName()) + .deviceDesc(entity.getDeviceDesc()) + .controlSource(ControlSourceEnum.find(entity.getDeviceIndex())) + .workspaceId(entity.getWorkspaceId()) + .type(DeviceTypeEnum.find(entity.getDeviceType())) + .subType(DeviceSubTypeEnum.find(entity.getSubType())) + .domain(DeviceDomainEnum.find(entity.getDomain())) + .iconUrl(new DeviceIconUrl() + .setNormalIconUrl(entity.getUrlNormal()) + .setSelectIconUrl(entity.getUrlSelect())) + .boundStatus(entity.getBoundStatus()) + .loginTime(entity.getLoginTime() != null ? + LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getLoginTime()), ZoneId.systemDefault()) + : null) + .boundTime(entity.getBoundTime() != null ? + LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getBoundTime()), ZoneId.systemDefault()) + : null) + .nickname(entity.getNickname()) + .firmwareVersion(entity.getFirmwareVersion()) + .workspaceName(entity.getWorkspaceId() != null ? + workspaceService.getWorkspaceByWorkspaceId(entity.getWorkspaceId()) + .map(WorkspaceDTO::getWorkspaceName).orElse("") : "") + .firmwareStatus(DeviceFirmwareStatusEnum.NOT_UPGRADE) + .thingVersion(entity.getVersion()).build(); + } catch (CloudSDKException e) { + log.error(e.getLocalizedMessage() + "Entity: {}", entity); + } + DeviceDTO deviceDTO = builder.build(); addFirmwareStatus(deviceDTO, entity); return deviceDTO; } @@ -659,13 +397,12 @@ public class DeviceServiceImpl implements IDeviceService { return; } // Query whether the device is updating firmware. - Optional>> progressOpt = - deviceRedisService.getFirmwareUpgradingProgress(entity.getDeviceSn()); + Optional> progressOpt = deviceRedisService.getFirmwareUpgradingProgress(entity.getDeviceSn()); if (progressOpt.isPresent()) { - deviceDTO.setFirmwareStatus(DeviceFirmwareStatusEnum.UPGRADING.getVal()); + deviceDTO.setFirmwareStatus(DeviceFirmwareStatusEnum.UPGRADING); deviceDTO.setFirmwareProgress(progressOpt.map(EventsReceiver::getOutput) - .map(EventsOutputProgressReceiver::getProgress) - .map(OutputProgressReceiver::getPercent) + .map(OtaProgress::getProgress) + .map(OtaProgressData::getPercent) .orElse(0)); return; } @@ -674,16 +411,16 @@ public class DeviceServiceImpl implements IDeviceService { // to see if it needs to be upgraded. Optional firmwareReleaseNoteOpt = deviceFirmwareService.getLatestFirmwareReleaseNote(entity.getDeviceName()); if (firmwareReleaseNoteOpt.isEmpty()) { - deviceDTO.setFirmwareStatus(DeviceFirmwareStatusEnum.NOT_UPGRADE.getVal()); + deviceDTO.setFirmwareStatus(DeviceFirmwareStatusEnum.NOT_UPGRADE); return; } if (entity.getFirmwareVersion().equals(firmwareReleaseNoteOpt.get().getProductVersion())) { - deviceDTO.setFirmwareStatus(Objects.requireNonNullElse(entity.getCompatibleStatus(), true) ? - DeviceFirmwareStatusEnum.NOT_UPGRADE.getVal() : - DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE.getVal()); + deviceDTO.setFirmwareStatus(entity.getCompatibleStatus() ? + DeviceFirmwareStatusEnum.NOT_UPGRADE : + DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE); return; } - deviceDTO.setFirmwareStatus(DeviceFirmwareStatusEnum.NORMAL_UPGRADE.getVal()); + deviceDTO.setFirmwareStatus(DeviceFirmwareStatusEnum.NORMAL_UPGRADE); } @Override @@ -698,7 +435,7 @@ public class DeviceServiceImpl implements IDeviceService { device.setBoundStatus(true); device.setBoundTime(LocalDateTime.now()); - boolean isUpd = this.saveDevice(this.deviceDTO2Entity(device)).isPresent(); + boolean isUpd = this.updateDevice(device); if (!isUpd) { return false; } @@ -712,111 +449,20 @@ public class DeviceServiceImpl implements IDeviceService { redisDevice.setWorkspaceId(device.getWorkspaceId()); deviceRedisService.setDeviceOnline(redisDevice); - if (DeviceDomainEnum.GATEWAY.getVal() == redisDevice.getDomain()) { - this.pushDeviceOnlineTopo(webSocketManageService.getValueWithWorkspace(device.getWorkspaceId()), - device.getDeviceSn(), device.getDeviceSn()); - } - if (DeviceDomainEnum.SUB_DEVICE.getVal() == redisDevice.getDomain()) { - DeviceDTO subDevice = this.getDevicesByParams(DeviceQueryParam.builder() - .childSn(device.getChildDeviceSn()) - .build()).get(0); - this.pushDeviceOnlineTopo(webSocketManageService.getValueWithWorkspace(device.getWorkspaceId()), - device.getDeviceSn(), subDevice.getDeviceSn()); + String gatewaySn, deviceSn; + if (DeviceDomainEnum.REMOTER_CONTROL == redisDevice.getDomain()) { + gatewaySn = device.getDeviceSn(); + deviceSn = redisDevice.getChildDeviceSn(); + } else { + gatewaySn = redisDevice.getParentSn(); + deviceSn = device.getDeviceSn(); } - this.subscribeTopicOnline(device.getDeviceSn()); + pushDeviceOnlineTopo(device.getWorkspaceId(), gatewaySn, deviceSn); + subDeviceOnlineSubscribeTopic(SDKManager.getDeviceSDK(gatewaySn)); return true; } - /** - * Handle dock binding status requests. - * @param receiver - * @param headers - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_AIRPORT_BIND_STATUS, outputChannel = ChannelName.OUTBOUND) - public void bindStatus(CommonTopicReceiver receiver, MessageHeaders headers) { - List> data = ((Map>>) receiver.getData()).get(MapKeyConst.DEVICES); - String dockSn = data.get(0).get(MapKeyConst.SN); - String droneSn = data.size() > 1 ? data.get(1).get(MapKeyConst.SN) : "null"; - - Optional dockOpt = this.getDeviceBySn(dockSn); - Optional droneOpt = this.getDeviceBySn(droneSn); - - List bindStatusResult = new ArrayList<>(); - bindStatusResult.add(dockOpt.isPresent() ? this.dto2BindStatus(dockOpt.get()) : - BindStatusReceiver.builder().sn(dockSn).isDeviceBindOrganization(false).build()); - if (data.size() > 1) { - bindStatusResult.add(droneOpt.isPresent() ? this.dto2BindStatus(droneOpt.get()) : - BindStatusReceiver.builder().sn(droneSn).isDeviceBindOrganization(false).build()); - } - - messageSender.publish(headers.get(MqttHeaders.RECEIVED_TOPIC) + _REPLY_SUF, - CommonTopicResponse.builder() - .tid(receiver.getTid()) - .bid(receiver.getBid()) - .timestamp(System.currentTimeMillis()) - .method(RequestsMethodEnum.AIRPORT_BIND_STATUS.getMethod()) - .data(RequestsReply.success(Map.of(MapKeyConst.BIND_STATUS, bindStatusResult))) - .build()); - - } - - /** - * Handle dock binding requests. - * @param receiver - * @param headers - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_BIND) - public void bindDevice(CommonTopicReceiver receiver, MessageHeaders headers) { - Map> data = objectMapper.convertValue(receiver.getData(), - new TypeReference>>() {}); - List devices = data.get(MapKeyConst.BIND_DEVICES); - BindDeviceReceiver dock = null; - BindDeviceReceiver drone = null; - for (BindDeviceReceiver device : devices) { - int val = Integer.parseInt(device.getDeviceModelKey().split("-")[0]); - if (val == DeviceDomainEnum.DOCK.getVal()) { - dock = device; - } - if (val == DeviceDomainEnum.SUB_DEVICE.getVal()) { - drone = device; - } - } - - Optional dockEntityOpt = this.bindDevice2Entity(DeviceDomainEnum.DOCK.getVal(), dock); - Optional droneEntityOpt = this.bindDevice2Entity(DeviceDomainEnum.SUB_DEVICE.getVal(), drone); - - List bindResult = new ArrayList<>(); - - droneEntityOpt.ifPresent(droneEntity -> { - dockEntityOpt.get().setChildSn(droneEntity.getDeviceSn()); - Optional deviceEntityOpt = this.saveDevice(droneEntity); - bindResult.add( - deviceEntityOpt.isPresent() ? - ErrorInfoReply.success(droneEntity.getDeviceSn()) : - new ErrorInfoReply(droneEntity.getDeviceSn(), - CommonErrorEnum.DEVICE_BINDING_FAILED.getErrorCode()) - ); - }); - Optional dockOpt = this.saveDevice(dockEntityOpt.get()); - - bindResult.add(dockOpt.isPresent() ? - ErrorInfoReply.success(dock.getSn()) : - new ErrorInfoReply(dock.getSn(), - CommonErrorEnum.DEVICE_BINDING_FAILED.getErrorCode())); - - String topic = headers.get(MqttHeaders.RECEIVED_TOPIC) + _REPLY_SUF; - messageSender.publish(topic, - CommonTopicResponse.builder() - .tid(receiver.getTid()) - .bid(receiver.getBid()) - .method(RequestsMethodEnum.AIRPORT_ORGANIZATION_BIND.getMethod()) - .timestamp(System.currentTimeMillis()) - .data(RequestsReply.success(Map.of(MapKeyConst.ERR_INFOS, bindResult))) - .build()); - - } - @Override public PaginationData getBoundDevicesWithDomain(String workspaceId, Long page, Long pageSize, Integer domain) { @@ -874,36 +520,11 @@ public class DeviceServiceImpl implements IDeviceService { return Optional.of(device); } - /** - * Update the firmware version information of the device or payload. - * @param receiver - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_FIRMWARE_VERSION) - public void updateFirmwareVersion(FirmwareVersionReceiver receiver) { - // If the reported version is empty, it will not be processed to prevent misleading page. - if (!StringUtils.hasText(receiver.getFirmwareVersion())) { - return; - } - - if (receiver.getDomain() == DeviceDomainEnum.SUB_DEVICE) { - final DeviceDTO device = DeviceDTO.builder() - .deviceSn(receiver.getSn()) - .firmwareVersion(receiver.getFirmwareVersion()) - .firmwareStatus(receiver.getCompatibleStatus() == null ? - null : DeviceFirmwareStatusEnum.CompatibleStatusEnum.INCONSISTENT.getVal() != receiver.getCompatibleStatus() ? - DeviceFirmwareStatusEnum.UNKNOWN.getVal() : DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE.getVal()) - .build(); - this.updateDevice(device); - return; - } - payloadService.updateFirmwareVersion(receiver); - } - @Override - public ResponseResult createDeviceOtaJob(String workspaceId, List upgradeDTOS) { - List deviceOtaFirmwares = deviceFirmwareService.getDeviceOtaFirmware(workspaceId, upgradeDTOS); + public HttpResultResponse createDeviceOtaJob(String workspaceId, List upgradeDTOS) { + List deviceOtaFirmwares = deviceFirmwareService.getDeviceOtaFirmware(workspaceId, upgradeDTOS); if (deviceOtaFirmwares.isEmpty()) { - return ResponseResult.error(); + return HttpResultResponse.error(); } Optional deviceOpt = deviceRedisService.getDeviceOnline(deviceOtaFirmwares.get(0).getSn()); @@ -911,22 +532,22 @@ public class DeviceServiceImpl implements IDeviceService { throw new RuntimeException("Device is offline."); } DeviceDTO device = deviceOpt.get(); - String gatewaySn = DeviceDomainEnum.DOCK.getVal() == device.getDomain() ? device.getDeviceSn() : device.getParentSn(); + String gatewaySn = DeviceDomainEnum.DOCK == device.getDomain() ? device.getDeviceSn() : device.getParentSn(); checkOtaConditions(gatewaySn); - String bid = UUID.randomUUID().toString(); - ServiceReply serviceReply = messageSender.publishServicesTopic( - gatewaySn, FirmwareMethodEnum.OTA_CREATE.getMethod(), Map.of(MapKeyConst.DEVICES, deviceOtaFirmwares), bid); - if (serviceReply.getResult() != ResponseResult.CODE_SUCCESS) { - return ResponseResult.error(serviceReply.getResult(), "Firmware Error Code: " + serviceReply.getResult()); + TopicServicesResponse> response = abstractFirmwareService.otaCreate( + SDKManager.getDeviceSDK(gatewaySn), new OtaCreateRequest().setDevices(deviceOtaFirmwares)); + ServicesReplyData serviceReply = response.getData(); + String bid = response.getBid(); + if (!serviceReply.getResult().isSuccess()) { + return HttpResultResponse.error(serviceReply.getResult()); } // Record the device state that needs to be updated. deviceOtaFirmwares.forEach(deviceOta -> deviceRedisService.setFirmwareUpgrading(deviceOta.getSn(), - EventsReceiver.>builder() - .bid(bid).sn(deviceOta.getSn()).build())); - return ResponseResult.success(); + EventsReceiver.builder().bid(bid).sn(deviceOta.getSn()).build())); + return HttpResultResponse.success(); } /** @@ -934,7 +555,7 @@ public class DeviceServiceImpl implements IDeviceService { * @param dockSn */ private void checkOtaConditions(String dockSn) { - Optional deviceOpt = deviceRedisService.getDeviceOsd(dockSn, OsdDockReceiver.class); + Optional deviceOpt = deviceRedisService.getDeviceOsd(dockSn, OsdDock.class); if (deviceOpt.isEmpty()) { throw new RuntimeException("Dock is offline."); } @@ -950,100 +571,81 @@ public class DeviceServiceImpl implements IDeviceService { } @Override - public void devicePropertySet(String workspaceId, String dockSn, DeviceSetPropertyEnum propertyEnum, JsonNode param) { + public int devicePropertySet(String workspaceId, String dockSn, JsonNode param) { + String property = param.fieldNames().next(); + PropertySetFieldEnum propertyEnum = PropertySetFieldEnum.find(property); + Optional dockOpt = deviceRedisService.getDeviceOnline(dockSn); if (dockOpt.isEmpty()) { throw new RuntimeException("Dock is offline."); } String childSn = dockOpt.get().getChildDeviceSn(); - boolean deviceOnline = deviceRedisService.checkDeviceOnline(childSn); - Optional osdOpt = deviceRedisService.getDeviceOsd(childSn, OsdSubDeviceReceiver.class); - if (!deviceOnline || osdOpt.isEmpty()) { + Optional osdOpt = deviceRedisService.getDeviceOsd(childSn, OsdDockDrone.class); + if (osdOpt.isEmpty()) { throw new RuntimeException("Device is offline."); } // Make sure the data is valid. - BasicDeviceProperty basicDeviceProperty = objectMapper.convertValue(param, propertyEnum.getClazz()); + BasicDeviceProperty basicDeviceProperty = objectMapper.convertValue(param.get(property), propertyEnum.getClazz()); boolean valid = basicDeviceProperty.valid(); if (!valid) { - throw new IllegalArgumentException(CommonErrorEnum.ILLEGAL_ARGUMENT.getErrorMsg()); - } - - String topic = THING_MODEL_PRE + PRODUCT + dockSn + PROPERTY_SUF + SET_SUF; - if (!param.isObject()) { - this.deviceOnePropertySet(topic, propertyEnum, Map.entry(propertyEnum.getProperty(), param)); - return; + throw new IllegalArgumentException(CommonErrorEnum.ILLEGAL_ARGUMENT.getMessage()); } - // If there are multiple parameters, set them separately. - for (Iterator> filed = param.fields(); filed.hasNext(); ) { - Map.Entry node = filed.next(); - boolean isPublish = basicDeviceProperty.canPublish(node.getKey(), osdOpt.get()); - if (!isPublish) { - continue; - } - this.deviceOnePropertySet(topic, propertyEnum, Map.entry(propertyEnum.getProperty(), node)); + boolean isPublish = basicDeviceProperty.canPublish(osdOpt.get()); + if (!isPublish) { + return PropertySetReplyResultEnum.SUCCESS.getResult(); } - - } - - @Override - public void deviceOnePropertySet(String topic, DeviceSetPropertyEnum propertyEnum, Map.Entry value) { - if (Objects.isNull(value) || Objects.isNull(value.getValue())) { - throw new IllegalArgumentException(CommonErrorEnum.ILLEGAL_ARGUMENT.getErrorMsg()); - } - - Map reply = messageSender.publishWithReply( - Map.class, topic, - CommonTopicResponse.builder() - .bid(UUID.randomUUID().toString()) - .tid(UUID.randomUUID().toString()) - .timestamp(System.currentTimeMillis()) - .data(value) - .build()); - - while (true) { - reply = (Map) reply.get(value.getKey()); - if (value.getValue() instanceof JsonNode) { - break; - } - value = (Map.Entry) value.getValue(); - } - - SetReply setReply = objectMapper.convertValue(reply, SetReply.class); - if (SetReplyStatusResultEnum.SUCCESS.getVal() != setReply.getResult()) { - throw new RuntimeException("Failed to set " + value.getKey() + "; Error Code: " + setReply.getResult()); - } - + BaseModel baseModel = objectMapper.convertValue(param, propertyEnum.getProperty().getClazz()); + PropertySetReplyResultEnum result = abstractPropertyService.propertySet( + SDKManager.getDeviceSDK(dockSn), propertyEnum.getProperty(), baseModel); + return result.getResult(); } @Override public DockModeCodeEnum getDockMode(String dockSn) { - return deviceRedisService.getDeviceOsd(dockSn, OsdDockReceiver.class) - .map(OsdDockReceiver::getModeCode).orElse(DockModeCodeEnum.DISCONNECTED); + return deviceRedisService.getDeviceOsd(dockSn, OsdDock.class) + .map(OsdDock::getModeCode).orElse(null); } @Override - public DeviceModeCodeEnum getDeviceMode(String deviceSn) { - return deviceRedisService.getDeviceOsd(deviceSn, OsdSubDeviceReceiver.class) - .map(OsdSubDeviceReceiver::getModeCode).orElse(DeviceModeCodeEnum.DISCONNECTED); + public DroneModeCodeEnum getDeviceMode(String deviceSn) { + return deviceRedisService.getDeviceOsd(deviceSn, OsdDockDrone.class) + .map(OsdDockDrone::getModeCode).orElse(DroneModeCodeEnum.DISCONNECTED); } @Override public Boolean checkDockDrcMode(String dockSn) { - return deviceRedisService.getDeviceOsd(dockSn, OsdDockReceiver.class) - .map(OsdDockReceiver::getDrcState) - .orElse(DockDrcStateEnum.DISCONNECTED) != DockDrcStateEnum.DISCONNECTED; + return deviceRedisService.getDeviceOsd(dockSn, OsdDock.class) + .map(OsdDock::getDrcState) + .orElse(DrcStateEnum.DISCONNECTED) != DrcStateEnum.DISCONNECTED; } @Override public Boolean checkAuthorityFlight(String gatewaySn) { return deviceRedisService.getDeviceOnline(gatewaySn).flatMap(gateway -> - Optional.of((DeviceDomainEnum.DOCK.getVal() == gateway.getDomain() - || DeviceDomainEnum.GATEWAY.getVal() == gateway.getDomain()) - && ControlSourceEnum.A.getControlSource().equals(gateway.getControlSource()))) + Optional.of((DeviceDomainEnum.DOCK == gateway.getDomain() + || DeviceDomainEnum.REMOTER_CONTROL == gateway.getDomain()) + && ControlSourceEnum.A == gateway.getControlSource())) .orElse(true); } + @Override + public void updateFlightControl(DeviceDTO gateway, ControlSourceEnum controlSource) { + if (controlSource == gateway.getControlSource()) { + return; + } + gateway.setControlSource(controlSource); + deviceRedisService.setDeviceOnline(gateway); + + webSocketMessageService.sendBatch(gateway.getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.CONTROL_SOURCE_CHANGE.getCode(), + DeviceAuthorityDTO.builder() + .controlSource(gateway.getControlSource()) + .sn(gateway.getDeviceSn()) + .type(DroneAuthorityEnum.FLIGHT) + .build()); + } + /** * Convert device data transfer object into database entity object. * @param dto @@ -1056,142 +658,26 @@ public class DeviceServiceImpl implements IDeviceService { } return builder.deviceSn(dto.getDeviceSn()) + .deviceIndex(Optional.ofNullable(dto.getControlSource()) + .map(ControlSourceEnum::getControlSource).orElse(null)) + .deviceName(dto.getDeviceName()) + .version(dto.getThingVersion()) .userId(dto.getUserId()) .nickname(dto.getNickname()) .workspaceId(dto.getWorkspaceId()) .boundStatus(dto.getBoundStatus()) + .domain(Optional.ofNullable(dto.getDomain()).map(DeviceDomainEnum::getDomain).orElse(null)) + .deviceType(Optional.ofNullable(dto.getType()).map(DeviceTypeEnum::getType).orElse(null)) + .subType(Optional.ofNullable(dto.getSubType()).map(DeviceSubTypeEnum::getSubType).orElse(null)) .loginTime(dto.getLoginTime() != null ? dto.getLoginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : null) .boundTime(dto.getBoundTime() != null ? dto.getBoundTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : null) .childSn(dto.getChildDeviceSn()) - .domain(dto.getDomain()) .firmwareVersion(dto.getFirmwareVersion()) .compatibleStatus(dto.getFirmwareStatus() == null ? null : - DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE != DeviceFirmwareStatusEnum.find(dto.getFirmwareStatus())) - .build(); - } - - /** - * Convert device binding data object into database entity object. - * - * @param domain - * @param receiver - * @return - */ - private Optional bindDevice2Entity(Integer domain, BindDeviceReceiver receiver) { - if (receiver == null) { - return Optional.empty(); - } - int[] droneKey = Arrays.stream(receiver.getDeviceModelKey().split("-")).mapToInt(Integer::parseInt).toArray(); - Optional dictionaryOpt = dictionaryService.getOneDictionaryInfoByTypeSubType(domain, droneKey[1], droneKey[2]); - DeviceEntity.DeviceEntityBuilder builder = DeviceEntity.builder(); - - dictionaryOpt.ifPresent(entity -> - builder.deviceName(entity.getDeviceName()) - .nickname(entity.getDeviceName()) - .deviceDesc(entity.getDeviceDesc())); - - Optional workspace = workspaceService.getWorkspaceNameByBindCode(receiver.getDeviceBindingCode()); - - DeviceEntity entity = builder - .workspaceId(workspace.isPresent() ? workspace.get().getWorkspaceId() : receiver.getOrganizationId()) - .domain(droneKey[0]) - .deviceType(droneKey[1]) - .subType(droneKey[2]) - .deviceSn(receiver.getSn()) - .boundStatus(true) - .loginTime(System.currentTimeMillis()) - .boundTime(System.currentTimeMillis()) - .urlSelect(IconUrlEnum.SELECT_EQUIPMENT.getUrl()) - .urlNormal(IconUrlEnum.NORMAL_EQUIPMENT.getUrl()) - .build(); - if (StringUtils.hasText(receiver.getDeviceCallsign())) { - entity.setNickname(receiver.getDeviceCallsign()); - } - return Optional.of(entity); - } - - /** - * Convert device data transfer object into device binding status data object. - * @param device - * @return - */ - private BindStatusReceiver dto2BindStatus(DeviceDTO device) { - if (device == null) { - return null; - } - return BindStatusReceiver.builder() - .sn(device.getDeviceSn()) - .deviceCallsign(device.getNickname()) - .isDeviceBindOrganization(device.getBoundStatus()) - .organizationId(device.getWorkspaceId()) - .organizationName(device.getWorkspaceName()) + DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE != dto.getFirmwareStatus()) + .deviceDesc(dto.getDeviceDesc()) .build(); } - - private Optional onlineSaveDevice(DeviceEntity device, String childSn, String parentSn) { - - Optional deviceOpt = this.getDeviceBySn(device.getDeviceSn()); - if (deviceOpt.isEmpty()) { - // Set the icon of the gateway device displayed in the pilot's map, required in the TSA module. - device.setUrlNormal(IconUrlEnum.NORMAL_PERSON.getUrl()); - // Set the icon of the gateway device displayed in the pilot's map when it is selected, required in the TSA module. - device.setUrlSelect(IconUrlEnum.SELECT_PERSON.getUrl()); - device.setBoundStatus(false); - } else { - DeviceDTO oldDevice = deviceOpt.get(); - device.setNickname(oldDevice.getNickname()); - device.setBoundStatus(oldDevice.getBoundStatus()); - } - - device.setChildSn(childSn); - device.setLoginTime(System.currentTimeMillis()); - - Optional saveDeviceOpt = this.saveDevice(device); - if (saveDeviceOpt.isEmpty()) { - return saveDeviceOpt; - } - - DeviceDTO redisDevice = this.deviceEntityConvertToDTO(saveDeviceOpt.get()); - redisDevice.setParentSn(parentSn); - - deviceRedisService.setDeviceOnline(redisDevice); - - return saveDeviceOpt; - } - - /** - * Handles messages in the state topic about basic drone data. - * - * Note: Only the data of the drone payload is handled here. You can handle other data from the drone - * according to your business needs. - * @param deviceBasic basic drone data - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_BASIC, outputChannel = ChannelName.INBOUND_STATE_PAYLOAD) - public List stateBasic(DeviceBasicReceiver deviceBasic) { - Optional deviceOpt = deviceRedisService.getDeviceOnline(deviceBasic.getDeviceSn()); - if (deviceOpt.isEmpty()) { - return deviceBasic.getPayloads(); - } - Optional dockOpt = deviceRedisService.getDeviceOnline(deviceOpt.get().getParentSn()); - if (dockOpt.isEmpty()) { - return deviceBasic.getPayloads(); - } - DeviceDTO dock = dockOpt.get(); - if (!deviceBasic.getControlSource().equals(dock.getControlSource())) { - dock.setControlSource(deviceBasic.getControlSource()); - deviceRedisService.setDeviceOnline(dock); - - sendMessageService.sendBatch(dock.getWorkspaceId(), UserTypeEnum.WEB.getVal(), - BizCodeEnum.CONTROL_SOURCE_CHANGE.getCode(), - DeviceAuthorityDTO.builder() - .controlSource(dock.getControlSource()) - .sn(dock.getDeviceSn()) - .type(DroneAuthorityEnum.FLIGHT) - .build()); - - } - return deviceBasic.getPayloads(); - } } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/service/impl/DockOSDServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DockOSDServiceImpl.java deleted file mode 100644 index afb9fc0..0000000 --- a/src/main/java/com/dji/sample/manage/service/impl/DockOSDServiceImpl.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.dji.sample.manage.service.impl; - -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.dto.DeviceDTO; -import com.dji.sample.manage.model.dto.TelemetryDTO; -import com.dji.sample.manage.model.enums.DeviceDomainEnum; -import com.dji.sample.manage.model.receiver.OsdDockReceiver; -import org.springframework.stereotype.Service; - -import java.util.Collection; -import java.util.Objects; - -/** - * @author sean - * @version 1.0 - * @date 2022/5/11 - */ -@Service -public class DockOSDServiceImpl extends AbstractTSAService { - - public DockOSDServiceImpl() { - super(null); - } - - @Override - public void pushTelemetryData(Collection sessions, - CustomWebSocketMessage message, Object Object) { - - } - - @Override - public void handleOSD(CommonTopicReceiver receiver, DeviceDTO device, - Collection webSessions, - CustomWebSocketMessage wsMessage) { - - if (DeviceDomainEnum.DOCK.getVal() == device.getDomain()) { - wsMessage.setBizCode(BizCodeEnum.DOCK_OSD.getCode()); - OsdDockReceiver data = mapper.convertValue(receiver.getData(), OsdDockReceiver.class); - wsMessage.getData().setHost(data); - sendMessageService.sendBatch(webSessions, wsMessage); - String key = RedisConst.OSD_PREFIX + device.getDeviceSn(); - OsdDockReceiver redisData = (OsdDockReceiver) RedisOpsUtils.get(key); - if (Objects.nonNull(data.getModeCode())) { - if (Objects.nonNull(redisData)) { - data.setDrcState(redisData.getDrcState()); - } - RedisOpsUtils.setWithExpire(key, data, RedisConst.DEVICE_ALIVE_SECOND); - return; - } - - if (Objects.nonNull(data.getDrcState()) && Objects.nonNull(redisData)) { - redisData.setDrcState(data.getDrcState()); - RedisOpsUtils.setWithExpire(key, redisData, RedisConst.DEVICE_ALIVE_SECOND); - } - } - } -} diff --git a/src/main/java/com/dji/sample/manage/service/impl/GatewayOSDServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/GatewayOSDServiceImpl.java deleted file mode 100644 index eb788b2..0000000 --- a/src/main/java/com/dji/sample/manage/service/impl/GatewayOSDServiceImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.dji.sample.manage.service.impl; - -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -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.dto.DeviceDTO; -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.receiver.OsdGatewayReceiver; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Service; - -import java.util.Collection; - -/** - * @author sean - * @version 0.3 - * @date 2022/2/21 - */ -@Service -public class GatewayOSDServiceImpl extends AbstractTSAService { - - public GatewayOSDServiceImpl(@Autowired @Qualifier("deviceOSDServiceImpl") AbstractTSAService tsaService) { - super(tsaService); - } - - @Override - public void pushTelemetryData(Collection sessions, - CustomWebSocketMessage message, Object osdData) { - if (osdData instanceof OsdGatewayReceiver) { - OsdGatewayReceiver data = (OsdGatewayReceiver) osdData; - TelemetryDTO telemetry = message.getData(); - telemetry.setHost(TelemetryDeviceDTO.builder() - .latitude(data.getLatitude()) - .longitude(data.getLongitude()) - .build()); - this.sendMessageService.sendBatch(sessions, message); - return; - } - tsaService.pushTelemetryData(sessions, message, osdData); - } - - @Override - public void handleOSD(CommonTopicReceiver receiver, DeviceDTO device, - Collection webSessions, - CustomWebSocketMessage wsMessage) { - if (DeviceDomainEnum.GATEWAY.getVal() == device.getDomain()) { - - wsMessage.setBizCode(BizCodeEnum.GATEWAY_OSD.getCode()); - OsdGatewayReceiver data = mapper.convertValue(receiver.getData(), OsdGatewayReceiver.class); - wsMessage.getData().setHost(data); - - this.sendMessageService.sendBatch(webSessions, wsMessage); - - this.pushTelemetryData(device.getWorkspaceId(), data, device.getDeviceSn()); - return; - } - - tsaService.handleOSD(receiver, device, webSessions, wsMessage); - } -} diff --git a/src/main/java/com/dji/sample/manage/service/impl/LiveStreamServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/LiveStreamServiceImpl.java index 5d2c8cd..2b1f590 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/LiveStreamServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/LiveStreamServiceImpl.java @@ -1,33 +1,27 @@ package com.dji.sample.manage.service.impl; -import com.dji.sample.common.error.LiveErrorEnum; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.CommonTopicResponse; -import com.dji.sample.component.mqtt.model.ServiceReply; -import com.dji.sample.component.mqtt.service.IMessageSenderService; -import com.dji.sample.component.redis.RedisConst; -import com.dji.sample.component.redis.RedisOpsUtils; import com.dji.sample.manage.model.dto.*; -import com.dji.sample.manage.model.enums.DeviceDomainEnum; -import com.dji.sample.manage.model.enums.LiveStreamMethodEnum; -import com.dji.sample.manage.model.enums.LiveUrlTypeEnum; -import com.dji.sample.manage.model.enums.LiveVideoQualityEnum; import com.dji.sample.manage.model.param.DeviceQueryParam; -import com.dji.sample.manage.model.receiver.CapacityDeviceReceiver; -import com.dji.sample.manage.model.receiver.LiveCapacityReceiver; import com.dji.sample.manage.service.*; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.device.VideoId; +import com.dji.sdk.cloudapi.livestream.*; +import com.dji.sdk.cloudapi.livestream.api.AbstractLivestreamService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.lang.reflect.Field; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; +import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; -import static com.dji.sample.component.mqtt.model.TopicConst.*; - /** * @author sean.zhou * @date 2021/11/22 @@ -47,10 +41,10 @@ public class LiveStreamServiceImpl implements ILiveStreamService { private IWorkspaceService workspaceService; @Autowired - private IMessageSenderService messageSender; + private IDeviceRedisService deviceRedisService; @Autowired - private IDeviceRedisService deviceRedisService; + private AbstractLivestreamService abstractLivestreamService; @Override public List getLiveCapacity(String workspaceId) { @@ -59,7 +53,7 @@ public class LiveStreamServiceImpl implements ILiveStreamService { List devicesList = deviceService.getDevicesByParams( DeviceQueryParam.builder() .workspaceId(workspaceId) - .domains(List.of(DeviceDomainEnum.SUB_DEVICE.getVal(), DeviceDomainEnum.DOCK.getVal())) + .domains(List.of(DeviceDomainEnum.DRONE.getDomain(), DeviceDomainEnum.DOCK.getDomain())) .build()); // Query the live capability of each drone. @@ -74,42 +68,29 @@ public class LiveStreamServiceImpl implements ILiveStreamService { } @Override - public void saveLiveCapacity(LiveCapacityReceiver liveCapacityReceiver, Long timestamp) { - // Solve timing problems - for (CapacityDeviceReceiver capacityDeviceReceiver : liveCapacityReceiver.getDeviceList()) { - long last = (long) Objects.requireNonNullElse( - RedisOpsUtils.get(RedisConst.LIVE_CAPACITY + capacityDeviceReceiver.getSn()), 0L); - if (last > timestamp) { - return; - } - capacityCameraService.saveCapacityCameraReceiverList( - capacityDeviceReceiver.getCameraList(), - capacityDeviceReceiver.getSn(), timestamp); - } - } - - @Override - public ResponseResult liveStart(LiveTypeDTO liveParam) { + public HttpResultResponse liveStart(LiveTypeDTO liveParam) { // Check if this lens is available live. - ResponseResult responseResult = this.checkBeforeLive(liveParam.getVideoId()); - if (ResponseResult.CODE_SUCCESS != responseResult.getCode()) { + HttpResultResponse responseResult = this.checkBeforeLive(liveParam.getVideoId()); + if (HttpResultResponse.CODE_SUCCESS != responseResult.getCode()) { return responseResult; } - DeviceDTO data = (DeviceDTO)responseResult.getData(); - // target topic - String respTopic = THING_MODEL_PRE + PRODUCT + - data.getDeviceSn() + SERVICES_SUF; - ServiceReply receiveReply = this.publishLiveStart(respTopic, liveParam); + TopicServicesResponse> response = abstractLivestreamService.liveStartPush( + SDKManager.getDeviceSDK(responseResult.getData().getDeviceSn()), new LiveStartPushRequest() + .setUrl(liveParam.getUrl()) + .setUrlType(liveParam.getUrlType()) + .setVideoId(new VideoId(liveParam.getVideoId())) + .setVideoQuality(liveParam.getVideoQuality())); - if (ResponseResult.CODE_SUCCESS != receiveReply.getResult()) { - return ResponseResult.error(LiveErrorEnum.find(receiveReply.getResult())); + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); } - LiveUrlTypeEnum urlType = LiveUrlTypeEnum.find(liveParam.getUrlType()); LiveDTO live = new LiveDTO(); - switch (urlType) { + switch (liveParam.getUrlType()) { + case AGORA: + break; case RTMP: live.setUrl(liveParam.getUrl().replace("rtmp", "webrtc")); break; @@ -125,89 +106,68 @@ public class LiveStreamServiceImpl implements ILiveStreamService { .toString()); break; case RTSP: - String url = receiveReply.getOutput().toString(); + String url = response.getData().getOutput(); this.resolveUrlUser(url, live); break; - case UNKNOWN: - return ResponseResult.error(LiveErrorEnum.URL_TYPE_NOT_SUPPORTED); + default: + return HttpResultResponse.error(LiveErrorCodeEnum.URL_TYPE_NOT_SUPPORTED); } - return ResponseResult.success(live); + return HttpResultResponse.success(live); } @Override - public ResponseResult liveStop(String videoId) { - ResponseResult responseResult = this.checkBeforeLive(videoId); - if (responseResult.getCode() != 0) { + public HttpResultResponse liveStop(String videoId) { + HttpResultResponse responseResult = this.checkBeforeLive(videoId); + if (HttpResultResponse.CODE_SUCCESS != responseResult.getCode()) { return responseResult; } - String respTopic = THING_MODEL_PRE + PRODUCT + responseResult.getData().getDeviceSn() + SERVICES_SUF; - - ServiceReply receiveReply = this.publishLiveStop(respTopic, videoId); - if (receiveReply.getResult() != 0) { - return ResponseResult.error(LiveErrorEnum.find(receiveReply.getResult())); + TopicServicesResponse response = abstractLivestreamService.liveStopPush( + SDKManager.getDeviceSDK(responseResult.getData().getDeviceSn()), new LiveStopPushRequest() + .setVideoId(new VideoId(videoId))); + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); } - return ResponseResult.success(); + return HttpResultResponse.success(); } @Override - public ResponseResult liveSetQuality(LiveTypeDTO liveParam) { - if (liveParam.getVideoQuality() == null || - LiveVideoQualityEnum.UNKNOWN == LiveVideoQualityEnum.find(liveParam.getVideoQuality())) { - return ResponseResult.error(LiveErrorEnum.ERROR_PARAMETERS); - } - - ResponseResult responseResult = this.checkBeforeLive(liveParam.getVideoId()); - + public HttpResultResponse liveSetQuality(LiveTypeDTO liveParam) { + HttpResultResponse responseResult = this.checkBeforeLive(liveParam.getVideoId()); if (responseResult.getCode() != 0) { return responseResult; } - String respTopic = THING_MODEL_PRE + PRODUCT + responseResult.getData().getDeviceSn() + SERVICES_SUF; - - ServiceReply receiveReply = this.publishLiveSetQuality(respTopic, liveParam); - if (ResponseResult.CODE_SUCCESS != receiveReply.getResult()) { - return ResponseResult.error(LiveErrorEnum.find(receiveReply.getResult())); + TopicServicesResponse response = abstractLivestreamService.liveSetQuality( + SDKManager.getDeviceSDK(responseResult.getData().getDeviceSn()), new LiveSetQualityRequest() + .setVideoQuality(liveParam.getVideoQuality()) + .setVideoId(new VideoId(liveParam.getVideoId()))); + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); } - return ResponseResult.success(); + return HttpResultResponse.success(); } @Override - public ResponseResult liveLensChange(LiveTypeDTO liveParam) { - if (!StringUtils.hasText(liveParam.getVideoType())) { - return ResponseResult.error(LiveErrorEnum.ERROR_PARAMETERS); - } - - ResponseResult responseResult = this.checkBeforeLive(liveParam.getVideoId()); - if (ResponseResult.CODE_SUCCESS != responseResult.getCode()) { + public HttpResultResponse liveLensChange(LiveTypeDTO liveParam) { + HttpResultResponse responseResult = this.checkBeforeLive(liveParam.getVideoId()); + if (HttpResultResponse.CODE_SUCCESS != responseResult.getCode()) { return responseResult; } - if (DeviceDomainEnum.GATEWAY.getVal() == responseResult.getData().getDomain()) { - return ResponseResult.error(LiveErrorEnum.FUNCTION_NOT_SUPPORT); - } - String respTopic = THING_MODEL_PRE + PRODUCT + responseResult.getData().getDeviceSn() + SERVICES_SUF; + TopicServicesResponse response = abstractLivestreamService.liveLensChange( + SDKManager.getDeviceSDK(responseResult.getData().getDeviceSn()), new LiveLensChangeRequest() + .setVideoType(liveParam.getVideoType()) + .setVideoId(new VideoId(liveParam.getVideoId()))); - ServiceReply receiveReply = this.publishLiveLensChange(respTopic, liveParam); - - if (ResponseResult.CODE_SUCCESS != receiveReply.getResult()) { - return ResponseResult.error(LiveErrorEnum.find(receiveReply.getResult())); + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); } - return ResponseResult.success(); - } - - private ServiceReply publishLiveLensChange(String respTopic, LiveTypeDTO liveParam) { - CommonTopicResponse response = new CommonTopicResponse<>(); - response.setTid(UUID.randomUUID().toString()); - response.setBid(UUID.randomUUID().toString()); - response.setMethod(LiveStreamMethodEnum.LIVE_LENS_CHANGE.getMethod()); - response.setData(liveParam); - - return messageSender.publishWithReply(ServiceReply.class, respTopic, response); + return HttpResultResponse.success(); } /** @@ -215,34 +175,34 @@ public class LiveStreamServiceImpl implements ILiveStreamService { * @param videoId * @return */ - private ResponseResult checkBeforeLive(String videoId) { + private HttpResultResponse checkBeforeLive(String videoId) { if (!StringUtils.hasText(videoId)) { - return ResponseResult.error(LiveErrorEnum.ERROR_PARAMETERS); + return HttpResultResponse.error(LiveErrorCodeEnum.ERROR_PARAMETERS); } String[] videoIdArr = videoId.split("/"); // drone sn / enumeration value of the location where the payload is mounted / payload lens if (videoIdArr.length != 3) { - return ResponseResult.error(LiveErrorEnum.ERROR_PARAMETERS); + return HttpResultResponse.error(LiveErrorCodeEnum.ERROR_PARAMETERS); } Optional deviceOpt = deviceService.getDeviceBySn(videoIdArr[0]); // Check if the gateway device connected to this drone exists if (deviceOpt.isEmpty()) { - return ResponseResult.error(LiveErrorEnum.NO_AIRCRAFT); + return HttpResultResponse.error(LiveErrorCodeEnum.NO_AIRCRAFT); } - if (DeviceDomainEnum.DOCK.getVal() == deviceOpt.get().getDomain()) { - return ResponseResult.success(deviceOpt.get()); + if (DeviceDomainEnum.DOCK == deviceOpt.get().getDomain()) { + return HttpResultResponse.success(deviceOpt.get()); } List gatewayList = deviceService.getDevicesByParams( DeviceQueryParam.builder() .childSn(videoIdArr[0]) .build()); if (gatewayList.isEmpty()) { - return ResponseResult.error(LiveErrorEnum.NO_FLIGHT_CONTROL); + return HttpResultResponse.error(LiveErrorCodeEnum.NO_FLIGHT_CONTROL); } - return ResponseResult.success(gatewayList.get(0)); + return HttpResultResponse.success(gatewayList.get(0)); } /** @@ -290,57 +250,4 @@ public class LiveStreamServiceImpl implements ILiveStreamService { } return gb28181; } - - /** - * Send a message to the pilot via mqtt to start the live streaming. - * @param topic - * @param liveParam - * @return - */ - private ServiceReply publishLiveStart(String topic, LiveTypeDTO liveParam) { - CommonTopicResponse response = new CommonTopicResponse<>(); - response.setTid(UUID.randomUUID().toString()); - response.setBid(UUID.randomUUID().toString()); - response.setData(liveParam); - response.setMethod(LiveStreamMethodEnum.LIVE_START_PUSH.getMethod()); - - return messageSender.publishWithReply(ServiceReply.class, topic, response); - } - - /** - * Send a message to the pilot via mqtt to set quality. - * @param respTopic - * @param liveParam - * @return - */ - private ServiceReply publishLiveSetQuality(String respTopic, LiveTypeDTO liveParam) { - Map data = new ConcurrentHashMap<>(Map.of( - "video_id", liveParam.getVideoId(), - "video_quality", liveParam.getVideoQuality())); - CommonTopicResponse> response = new CommonTopicResponse<>(); - response.setTid(UUID.randomUUID().toString()); - response.setBid(UUID.randomUUID().toString()); - response.setMethod(LiveStreamMethodEnum.LIVE_SET_QUALITY.getMethod()); - response.setData(data); - - return messageSender.publishWithReply(ServiceReply.class, respTopic, response); - } - - /** - * Send a message to the pilot via mqtt to stop the live streaming. - * @param topic - * @param videoId - * @return - */ - private ServiceReply publishLiveStop(String topic, String videoId) { - Map data = new ConcurrentHashMap<>(Map.of("video_id", videoId)); - CommonTopicResponse> response = new CommonTopicResponse<>(); - response.setTid(UUID.randomUUID().toString()); - response.setBid(UUID.randomUUID().toString()); - response.setData(data); - response.setMethod(LiveStreamMethodEnum.LIVE_STOP_PUSH.getMethod()); - - return messageSender.publishWithReply(ServiceReply.class, topic, response); - } - } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/service/impl/LogsFileIndexServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/LogsFileIndexServiceImpl.java index 5eeb5a1..22673f3 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/LogsFileIndexServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/LogsFileIndexServiceImpl.java @@ -4,10 +4,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.dji.sample.manage.dao.ILogsFileIndexMapper; import com.dji.sample.manage.model.dto.LogsFileDTO; +import com.dji.sample.manage.model.dto.LogsFileUploadDTO; import com.dji.sample.manage.model.entity.LogsFileIndexEntity; -import com.dji.sample.manage.model.receiver.LogsFile; -import com.dji.sample.manage.model.receiver.LogsFileUpload; import com.dji.sample.manage.service.ILogsFileIndexService; +import com.dji.sdk.cloudapi.log.LogFileIndex; +import com.dji.sdk.cloudapi.log.LogModuleEnum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -32,11 +33,11 @@ public class LogsFileIndexServiceImpl implements ILogsFileIndexService { private ILogsFileIndexMapper mapper; @Override - public Boolean insertFileIndex(LogsFile file, String deviceSn, Integer domain, String fileId) { - if (Objects.isNull(file)) { + public Boolean insertFileIndex(LogFileIndex file, String deviceSn, Integer domain, String fileId) { + LogsFileIndexEntity entity = this.logsFile2Entity(file); + if (Objects.isNull(entity)) { return false; } - LogsFileIndexEntity entity = this.logsFile2Entity(file); entity.setDomain(domain); entity.setDeviceSn(deviceSn); entity.setFileId(fileId); @@ -45,10 +46,10 @@ public class LogsFileIndexServiceImpl implements ILogsFileIndexService { } @Override - public List getFileIndexByFileIds(List files) { - List list = new ArrayList<>(); + public List getFileIndexByFileIds(List files) { + List list = new ArrayList<>(); files.forEach(file -> { - Optional fileOpt = this.getFileIndexByFileId(file.getFileId()); + Optional fileOpt = this.getFileIndexByFileId(file.getFileId()); fileOpt.ifPresent(fileUpload -> { fileUpload.setObjectKey(file.getStatus() ? file.getObjectKey() : null); list.add(fileUpload); @@ -64,37 +65,36 @@ public class LogsFileIndexServiceImpl implements ILogsFileIndexService { } @Override - public Optional getFileIndexByFileId(String fileId) { + public Optional getFileIndexByFileId(String fileId) { List logsFileIndexList = mapper.selectList( new LambdaQueryWrapper().eq(LogsFileIndexEntity::getFileId, fileId)); if (CollectionUtils.isEmpty(logsFileIndexList)) { return Optional.empty(); } LogsFileIndexEntity entity = logsFileIndexList.get(0); - List logsFileList = logsFileIndexList.stream().map(this::entity2LogsFile).collect(Collectors.toList()); - return Optional.of(LogsFileUpload.builder() + List logsFileList = logsFileIndexList.stream().map(this::entity2LogsFile).collect(Collectors.toList()); + return Optional.of(LogsFileUploadDTO.builder() .deviceSn(entity.getDeviceSn()) - .deviceModelDomain(String.valueOf(entity.getDomain())) + .deviceModelDomain(LogModuleEnum.find(String.valueOf(entity.getDomain()))) .list(logsFileList) .fileId(fileId) .build()); } - private LogsFile entity2LogsFile(LogsFileIndexEntity entity) { + private LogFileIndex entity2LogsFile(LogsFileIndexEntity entity) { if (Objects.isNull(entity)) { return null; } - return LogsFile.builder() - .bootIndex(entity.getBootIndex()) - .startTime(entity.getStartTime()) - .endTime(entity.getEndTime()) - .size(entity.getSize()) - .build(); + return new LogFileIndex() + .setBootIndex(entity.getBootIndex()) + .setStartTime(entity.getStartTime()) + .setEndTime(entity.getEndTime()) + .setSize(entity.getSize()); } - private LogsFileIndexEntity logsFile2Entity(LogsFile file) { + private LogsFileIndexEntity logsFile2Entity(LogFileIndex file) { if (Objects.isNull(file)) { return null; } diff --git a/src/main/java/com/dji/sample/manage/service/impl/LogsFileServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/LogsFileServiceImpl.java index 88bc2f4..4a839b9 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/LogsFileServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/LogsFileServiceImpl.java @@ -2,17 +2,18 @@ package com.dji.sample.manage.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import com.dji.sample.component.mqtt.model.EventsResultStatusEnum; import com.dji.sample.component.oss.model.OssConfiguration; import com.dji.sample.component.oss.service.impl.OssServiceContext; import com.dji.sample.manage.dao.ILogsFileMapper; import com.dji.sample.manage.model.dto.LogsFileDTO; +import com.dji.sample.manage.model.dto.LogsFileUploadDTO; import com.dji.sample.manage.model.entity.LogsFileEntity; -import com.dji.sample.manage.model.receiver.LogsExtFileReceiver; -import com.dji.sample.manage.model.receiver.LogsFile; -import com.dji.sample.manage.model.receiver.LogsFileUpload; import com.dji.sample.manage.service.ILogsFileIndexService; import com.dji.sample.manage.service.ILogsFileService; +import com.dji.sdk.cloudapi.log.FileUploadProgressFile; +import com.dji.sdk.cloudapi.log.FileUploadStartFile; +import com.dji.sdk.cloudapi.log.FileUploadStatusEnum; +import com.dji.sdk.cloudapi.log.LogFileIndex; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -71,7 +72,7 @@ public class LogsFileServiceImpl implements ILogsFileService { } @Override - public List getLogsFileByLogsId(String logsId) { + public List getLogsFileByLogsId(String logsId) { List logsFiles = this.getLogsFileInfoByLogsId(logsId); if (CollectionUtils.isEmpty(logsFiles)) { return new ArrayList<>(); @@ -80,7 +81,7 @@ public class LogsFileServiceImpl implements ILogsFileService { } @Override - public Boolean insertFile(LogsFileUpload file, String logsId) { + public Boolean insertFile(FileUploadStartFile file, String logsId) { LogsFileEntity entity = LogsFileEntity.builder() .logsId(logsId) .fileId(UUID.randomUUID().toString()) @@ -92,8 +93,8 @@ public class LogsFileServiceImpl implements ILogsFileService { if (!insert) { return false; } - for (LogsFile logsFile : file.getList()) { - insert = logsFileIndexService.insertFileIndex(logsFile, file.getDeviceSn(), Integer.valueOf(file.getDeviceModelDomain()), entity.getFileId()); + for (LogFileIndex logsFile : file.getList()) { + insert = logsFileIndexService.insertFileIndex(logsFile, file.getDeviceSn(), Integer.valueOf(file.getModule().getDomain()), entity.getFileId()); if (!insert) { return false; } @@ -120,7 +121,7 @@ public class LogsFileServiceImpl implements ILogsFileService { } @Override - public void updateFile(String logsId, LogsExtFileReceiver fileReceiver) { + public void updateFile(String logsId, FileUploadProgressFile fileReceiver) { List logsFiles = this.getLogsFileInfoByLogsId(logsId); if (CollectionUtils.isEmpty(logsFiles)) { return; @@ -146,15 +147,15 @@ public class LogsFileServiceImpl implements ILogsFileService { return ossService.getObjectUrl(OssConfiguration.bucket, logsFile.getObjectKey()); } - private LogsFileEntity receiver2Entity(LogsExtFileReceiver receiver) { + private LogsFileEntity receiver2Entity(FileUploadProgressFile receiver) { if (Objects.isNull(receiver)) { return null; } return LogsFileEntity.builder() .fingerprint(receiver.getFingerprint()) .size(receiver.getSize()) - .status(Objects.nonNull(receiver.getProgress()) && - EventsResultStatusEnum.OK.getDesc().equals(receiver.getProgress().getStatus())) + .status(Objects.nonNull(receiver.getProgress()) + && FileUploadStatusEnum.OK == receiver.getProgress().getStatus()) .name(receiver.getKey().substring(receiver.getKey().lastIndexOf("/") + 1)).build(); } } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/manage/service/impl/RequestConfigContext.java b/src/main/java/com/dji/sample/manage/service/impl/RequestConfigContext.java index 5665145..85c448e 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/RequestConfigContext.java +++ b/src/main/java/com/dji/sample/manage/service/impl/RequestConfigContext.java @@ -1,14 +1,15 @@ package com.dji.sample.manage.service.impl; -import com.dji.sample.common.util.SpringBeanUtils; -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.IMessageSenderService; -import com.dji.sample.manage.model.receiver.RequestConfigReceiver; -import com.dji.sample.manage.service.IRequestsConfigService; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.mqtt.support.MqttHeaders; +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.common.util.SpringBeanUtilsTest; +import com.dji.sample.manage.model.dto.ProductConfigDTO; +import com.dji.sample.manage.model.enums.CustomizeConfigScopeEnum; +import com.dji.sdk.cloudapi.config.ProductConfigResponse; +import com.dji.sdk.cloudapi.config.RequestsConfigRequest; +import com.dji.sdk.cloudapi.config.api.AbstractConfigService; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; import org.springframework.messaging.MessageHeaders; import org.springframework.stereotype.Service; @@ -20,37 +21,22 @@ import java.util.Optional; * @date 2022/11/10 */ @Service -public class RequestConfigContext { +public class RequestConfigContext extends AbstractConfigService { - @Autowired - private IMessageSenderService messageSenderService; - - @Autowired - private ObjectMapper objectMapper; - - - /** - * Handles the config method of the requests topic. - * @param receiver - * @param headers - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_CONFIG, outputChannel = ChannelName.OUTBOUND) - void handleConfig(CommonTopicReceiver receiver, MessageHeaders headers) { - RequestConfigReceiver configReceiver = objectMapper.convertValue(receiver.getData(), RequestConfigReceiver.class); - Optional scopeEnumOpt = ConfigScopeEnum.find(configReceiver.getConfigScope()); - String topic = headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF; - CommonTopicResponse.CommonTopicResponseBuilder build = CommonTopicResponse.builder() - .tid(receiver.getTid()) - .bid(receiver.getBid()) - .timestamp(System.currentTimeMillis()) - .method(receiver.getMethod()); + @Override + public TopicRequestsResponse requestsConfig(TopicRequestsRequest request, MessageHeaders headers) { + RequestsConfigRequest configReceiver = request.getData(); + Optional scopeEnumOpt = CustomizeConfigScopeEnum.find(configReceiver.getConfigScope().getScope()); if (scopeEnumOpt.isEmpty()) { - messageSenderService.publish(topic, build.build()); - return; + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); } - IRequestsConfigService requestsConfigService = SpringBeanUtils.getBean(scopeEnumOpt.get().getClazz()); - build.data(requestsConfigService.getConfig()); - messageSenderService.publish(topic, build.build()); + ProductConfigDTO config = (ProductConfigDTO) SpringBeanUtilsTest.getBean(scopeEnumOpt.get().getClazz()).getConfig(); + return new TopicRequestsResponse().setData( + new ProductConfigResponse() + .setNtpServerHost(config.getNtpServerHost()) + .setAppId(config.getAppId()) + .setAppKey(config.getAppKey()) + .setAppLicense(config.getAppLicense())); } } 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 new file mode 100644 index 0000000..81db422 --- /dev/null +++ b/src/main/java/com/dji/sample/manage/service/impl/SDKDeviceService.java @@ -0,0 +1,497 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.dto.DevicePayloadReceiver; +import com.dji.sample.manage.model.enums.DeviceFirmwareStatusEnum; +import com.dji.sample.manage.model.param.DeviceQueryParam; +import com.dji.sample.manage.service.IDeviceDictionaryService; +import com.dji.sample.manage.service.IDevicePayloadService; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.manage.service.IDeviceService; +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.common.SDKManager; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.osd.TopicOsdRequest; +import com.dji.sdk.mqtt.state.TopicStateRequest; +import com.dji.sdk.mqtt.status.TopicStatusRequest; +import com.dji.sdk.mqtt.status.TopicStatusResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/4 + */ +@Service +@Slf4j +public class SDKDeviceService extends AbstractDeviceService { + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IDeviceDictionaryService dictionaryService; + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IDevicePayloadService devicePayloadService; + + @Override + public TopicStatusResponse updateTopoOnline(TopicStatusRequest request, MessageHeaders headers) { + UpdateTopoSubDevice updateTopoSubDevice = request.getData().getSubDevices().get(0); + String deviceSn = updateTopoSubDevice.getSn(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(deviceSn); + Optional gatewayOpt = deviceRedisService.getDeviceOnline(request.getFrom()); + GatewayManager gatewayManager = SDKManager.registerDevice(request.getFrom(), deviceSn, + request.getData().getDomain(), request.getData().getType(), + request.getData().getSubType(), request.getData().getThingVersion(), updateTopoSubDevice.getThingVersion()); + + if (deviceOpt.isPresent() && gatewayOpt.isPresent()) { + deviceOnlineAgain(deviceOpt.get().getWorkspaceId(), request.getFrom(), deviceSn); + return new TopicStatusResponse().setData(MqttReply.success()); + } + + changeSubDeviceParent(deviceSn, request.getFrom()); + + DeviceDTO gateway = deviceGatewayConvertToDevice(request.getFrom(), request.getData()); + Optional gatewayEntityOpt = onlineSaveDevice(gateway, deviceSn, null); + if (gatewayEntityOpt.isEmpty()) { + log.error("Failed to go online, please check the status data or code logic."); + return null; + } + DeviceDTO subDevice = subDeviceConvertToDevice(updateTopoSubDevice); + Optional subDeviceEntityOpt = onlineSaveDevice(subDevice, null, gateway.getDeviceSn()); + if (subDeviceEntityOpt.isEmpty()) { + log.error("Failed to go online, please check the status data or code logic."); + return null; + } + subDevice = subDeviceEntityOpt.get(); + gateway = gatewayEntityOpt.get(); + dockGoOnline(gateway, subDevice); + deviceService.gatewayOnlineSubscribeTopic(gatewayManager); + + if (!StringUtils.hasText(subDevice.getWorkspaceId())) { + return new TopicStatusResponse().setData(MqttReply.success()); + } + + // 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()); + } + + @Override + public TopicStatusResponse updateTopoOffline(TopicStatusRequest request, MessageHeaders headers) { + GatewayManager gatewayManager = SDKManager.registerDevice(request.getFrom(), null, + request.getData().getDomain(), request.getData().getType(), + request.getData().getSubType(), request.getData().getThingVersion(), null); + deviceService.gatewayOnlineSubscribeTopic(gatewayManager); + // Only the remote controller is logged in and the aircraft is not connected. + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getFrom()); + if (deviceOpt.isEmpty()) { + // When connecting for the first time + DeviceDTO gatewayDevice = deviceGatewayConvertToDevice(request.getFrom(), request.getData()); + Optional gatewayDeviceOpt = onlineSaveDevice(gatewayDevice, null, null); + if (gatewayDeviceOpt.isEmpty()) { + return null; + } + deviceService.pushDeviceOnlineTopo(gatewayDeviceOpt.get().getWorkspaceId(), request.getFrom(), null); + return new TopicStatusResponse().setData(MqttReply.success()); + } + + String deviceSn = deviceOpt.get().getChildDeviceSn(); + if (!StringUtils.hasText(deviceSn)) { + return new TopicStatusResponse().setData(MqttReply.success()); + } + + deviceService.subDeviceOffline(deviceSn); + return new TopicStatusResponse().setData(MqttReply.success()); + } + + @Override + public void osdDock(TopicOsdRequest request, MessageHeaders headers) { + String from = request.getFrom(); + Optional deviceOpt = deviceRedisService.getDeviceOnline(from); + if (deviceOpt.isEmpty()) { + deviceOpt = deviceService.getDeviceBySn(from); + if (deviceOpt.isEmpty()) { + 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(); + deviceRedisService.setDeviceOnline(device); + fillDockOsd(from, request.getData()); + + deviceService.pushOsdDataToWeb(device.getWorkspaceId(), BizCodeEnum.DOCK_OSD, from, request.getData()); + } + + @Override + public void osdDockDrone(TopicOsdRequest request, MessageHeaders headers) { + String from = request.getFrom(); + Optional deviceOpt = deviceRedisService.getDeviceOnline(from); + if (deviceOpt.isEmpty()) { + deviceOpt = deviceService.getDeviceBySn(from); + if (deviceOpt.isEmpty()) { + log.error("Please restart the drone."); + return; + } + } + + if (!StringUtils.hasText(deviceOpt.get().getWorkspaceId())) { + log.error("Please restart the drone."); + return; + } + + DeviceDTO device = deviceOpt.get(); + deviceRedisService.setDeviceOnline(device); + deviceRedisService.setDeviceOsd(from, request.getData()); + + deviceService.pushOsdDataToWeb(device.getWorkspaceId(), BizCodeEnum.DEVICE_OSD, from, request.getData()); + } + + @Override + public void osdRemoteControl(TopicOsdRequest request, MessageHeaders headers) { + String from = request.getFrom(); + Optional deviceOpt = deviceRedisService.getDeviceOnline(from); + if (deviceOpt.isEmpty()) { + deviceOpt = deviceService.getDeviceBySn(from); + if (deviceOpt.isEmpty()) { + log.error("Please restart the drone."); + return; + } + } + DeviceDTO device = deviceOpt.get(); + deviceRedisService.setDeviceOnline(device); + + OsdRemoteControl data = request.getData(); + deviceService.pushOsdDataToPilot(device.getWorkspaceId(), from, + new DeviceOsdHost() + .setLatitude(data.getLatitude()) + .setLongitude(data.getLongitude()) + .setHeight(data.getHeight())); + deviceService.pushOsdDataToWeb(device.getWorkspaceId(), BizCodeEnum.RC_OSD, from, data); + + } + + @Override + public void osdRcDrone(TopicOsdRequest request, MessageHeaders headers) { + String from = request.getFrom(); + Optional deviceOpt = deviceRedisService.getDeviceOnline(from); + if (deviceOpt.isEmpty()) { + deviceOpt = deviceService.getDeviceBySn(from); + if (deviceOpt.isEmpty()) { + log.error("Please restart the drone."); + return; + } + } + if (!StringUtils.hasText(deviceOpt.get().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() + .setLatitude(data.getLatitude()) + .setLongitude(data.getLongitude()) + .setElevation(data.getElevation()) + .setHeight(data.getHeight()) + .setAttitudeHead(data.getAttitudeHead()) + .setElevation(data.getElevation()) + .setHorizontalSpeed(data.getHorizontalSpeed()) + .setVerticalSpeed(data.getVerticalSpeed())); + deviceService.pushOsdDataToWeb(device.getWorkspaceId(), BizCodeEnum.DEVICE_OSD, from, data); + } + + @Override + public void dockFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + // If the reported version is empty, it will not be processed to prevent misleading page. + if (!StringUtils.hasText(request.getData().getFirmwareVersion())) { + return; + } + + DeviceDTO device = DeviceDTO.builder() + .deviceSn(request.getFrom()) + .firmwareVersion(request.getData().getFirmwareVersion()) + .firmwareStatus(request.getData().getNeedCompatibleStatus() ? + DeviceFirmwareStatusEnum.UNKNOWN : DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE) + .build(); + boolean isUpd = deviceService.updateDevice(device); + if (!isUpd) { + log.error("Data update of firmware version failed. SN: {}", request.getFrom()); + } + } + + @Override + public void rcFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + // If the reported version is empty, it will not be processed to prevent misleading page. + if (!StringUtils.hasText(request.getData().getFirmwareVersion())) { + return; + } + + DeviceDTO device = DeviceDTO.builder() + .deviceSn(request.getFrom()) + .firmwareVersion(request.getData().getFirmwareVersion()) + .build(); + boolean isUpd = deviceService.updateDevice(device); + if (!isUpd) { + log.error("Data update of firmware version failed. SN: {}", request.getFrom()); + } + } + + @Override + public void rcPayloadFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + // If the reported version is empty, it will not be processed to prevent misleading page. + if (!StringUtils.hasText(request.getData().getFirmwareVersion())) { + return; + } + + boolean isUpd = devicePayloadService.updateFirmwareVersion(request.getFrom(), request.getData()); + if (!isUpd) { + log.error("Data update of payload firmware version failed. SN: {}", request.getFrom()); + } + } + + @Override + public void dockControlSourceUpdate(TopicStateRequest request, MessageHeaders headers) { + // If the control source is empty, it will not be processed. + if (ControlSourceEnum.UNKNOWN == request.getData().getControlSource()) { + return; + } + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getFrom()); + if (deviceOpt.isEmpty()) { + return; + } + Optional dockOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + if (dockOpt.isEmpty()) { + return; + } + + deviceService.updateFlightControl(dockOpt.get(), request.getData().getControlSource()); + devicePayloadService.updatePayloadControl(deviceOpt.get(), + request.getData().getPayloads().stream() + .map(p -> DevicePayloadReceiver.builder() + .controlSource(p.getControlSource()) + .payloadIndex(p.getPayloadIndex()) + .sn(p.getSn()) + .deviceSn(request.getFrom()) + .build()).collect(Collectors.toList())); + } + + @Override + public void rcControlSourceUpdate(TopicStateRequest request, MessageHeaders headers) { + // If the control source is empty, it will not be processed. + if (ControlSourceEnum.UNKNOWN == request.getData().getControlSource()) { + return; + } + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getFrom()); + if (deviceOpt.isEmpty()) { + return; + } + Optional dockOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + if (dockOpt.isEmpty()) { + return; + } + + deviceService.updateFlightControl(dockOpt.get(), request.getData().getControlSource()); + devicePayloadService.updatePayloadControl(deviceOpt.get(), + request.getData().getPayloads().stream() + .map(p -> DevicePayloadReceiver.builder() + .controlSource(p.getControlSource()) + .payloadIndex(p.getPayloadIndex()) + .sn(p.getSn()) + .deviceSn(request.getFrom()) + .build()).collect(Collectors.toList())); + } + + private void dockGoOnline(DeviceDTO gateway, DeviceDTO subDevice) { + if (DeviceDomainEnum.DOCK != gateway.getDomain()) { + return; + } + if (!StringUtils.hasText(gateway.getWorkspaceId())) { + log.error("The dock is not bound, please bind it first and then go online."); + return; + } + 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()); + subDevice.setWorkspaceId(gateway.getWorkspaceId()); + } + } + + private void changeSubDeviceParent(String deviceSn, String gatewaySn) { + List gatewaysList = deviceService.getDevicesByParams( + DeviceQueryParam.builder() + .childSn(deviceSn) + .build()); + gatewaysList.stream() + .filter(gateway -> !gateway.getDeviceSn().equals(gatewaySn)) + .forEach(gateway -> { + gateway.setChildDeviceSn(""); + deviceService.updateDevice(gateway); + deviceRedisService.getDeviceOnline(gateway.getDeviceSn()) + .ifPresent(device -> { + device.setChildDeviceSn(null); + deviceRedisService.setDeviceOnline(device); + }); + }); + } + + + public void deviceOnlineAgain(String workspaceId, String gatewaySn, String deviceSn) { + DeviceDTO device = DeviceDTO.builder().loginTime(LocalDateTime.now()).deviceSn(deviceSn).build(); + DeviceDTO gateway = DeviceDTO.builder() + .loginTime(LocalDateTime.now()) + .deviceSn(gatewaySn) + .childDeviceSn(deviceSn).build(); + deviceService.updateDevice(gateway); + deviceService.updateDevice(device); + gateway = deviceRedisService.getDeviceOnline(gatewaySn).map(g -> { + g.setChildDeviceSn(deviceSn); + return g; + }).get(); + device = deviceRedisService.getDeviceOnline(deviceSn).map(d -> { + d.setParentSn(gatewaySn); + return d; + }).get(); + deviceRedisService.setDeviceOnline(gateway); + deviceRedisService.setDeviceOnline(device); + if (StringUtils.hasText(workspaceId)) { + deviceService.subDeviceOnlineSubscribeTopic(SDKManager.getDeviceSDK(gatewaySn)); + } + + log.warn("{} is already online.", deviceSn); + } + + /** + * Convert the received gateway device object into a database entity object. + * @param gateway + * @return + */ + private DeviceDTO deviceGatewayConvertToDevice(String gatewaySn, UpdateTopo gateway) { + if (null == gateway) { + throw new IllegalArgumentException(); + } + return DeviceDTO.builder() + .deviceSn(gatewaySn) + .subType(gateway.getSubType()) + .type(gateway.getType()) + .thingVersion(gateway.getThingVersion()) + .domain(gateway.getDomain()) + .controlSource(gateway.getSubDevices().isEmpty() ? null : + ControlSourceEnum.find(gateway.getSubDevices().get(0).getIndex().getControlSource())) + .build(); + } + + /** + * Convert the received drone device object into a database entity object. + * @param device + * @return + */ + private DeviceDTO subDeviceConvertToDevice(UpdateTopoSubDevice device) { + if (null == device) { + throw new IllegalArgumentException(); + } + return DeviceDTO.builder() + .deviceSn(device.getSn()) + .type(device.getType()) + .subType(device.getSubType()) + .thingVersion(device.getThingVersion()) + .domain(device.getDomain()) + .build(); + } + + private Optional onlineSaveDevice(DeviceDTO device, String childSn, String parentSn) { + + device.setChildDeviceSn(childSn); + device.setLoginTime(LocalDateTime.now()); + + Optional deviceOpt = deviceService.getDeviceBySn(device.getDeviceSn()); + + if (deviceOpt.isEmpty()) { + device.setIconUrl(new DeviceIconUrl()); + // Set the icon of the gateway device displayed in the pilot's map, required in the TSA module. + device.getIconUrl().setNormalIconUrl(IconUrlEnum.NORMAL_PERSON.getUrl()); + // Set the icon of the gateway device displayed in the pilot's map when it is selected, required in the TSA module. + device.getIconUrl().setSelectIconUrl(IconUrlEnum.SELECT_PERSON.getUrl()); + device.setBoundStatus(false); + + // Query the model information of this gateway device. + dictionaryService.getOneDictionaryInfoByTypeSubType( + device.getDomain().getDomain(), device.getType().getType(), device.getSubType().getSubType()) + .ifPresent(entity -> { + device.setDeviceName(entity.getDeviceName()); + device.setNickname(entity.getDeviceName()); + device.setDeviceDesc(entity.getDeviceDesc()); + }); + } + boolean success = deviceService.saveOrUpdateDevice(device); + if (!success) { + return Optional.empty(); + } + + deviceOpt = deviceService.getDeviceBySn(device.getDeviceSn()); + DeviceDTO redisDevice = deviceOpt.get(); + redisDevice.setStatus(true); + redisDevice.setParentSn(parentSn); + + deviceRedisService.setDeviceOnline(redisDevice); + return deviceOpt; + } + + private void fillDockOsd(String dockSn, OsdDock dock) { + Optional oldDockOpt = deviceRedisService.getDeviceOsd(dockSn, OsdDock.class); + if (Objects.nonNull(dock.getJobNumber())) { + return; + } + if (oldDockOpt.isEmpty()) { + deviceRedisService.setDeviceOsd(dockSn, dock); + return; + } + OsdDock oldDock = oldDockOpt.get(); + if (Objects.nonNull(dock.getModeCode())) { + dock.setDrcState(oldDock.getDrcState()); + deviceRedisService.setDeviceOsd(dockSn, dock); + return; + } + if (Objects.nonNull(dock.getDrcState()) ) { + oldDock.setDrcState(dock.getDrcState()); + deviceRedisService.setDeviceOsd(dockSn, oldDock); + } + } +} diff --git a/src/main/java/com/dji/sample/manage/service/impl/SDKLivestreamService.java b/src/main/java/com/dji/sample/manage/service/impl/SDKLivestreamService.java new file mode 100644 index 0000000..d19e61d --- /dev/null +++ b/src/main/java/com/dji/sample/manage/service/impl/SDKLivestreamService.java @@ -0,0 +1,49 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.manage.model.receiver.CapacityDeviceReceiver; +import com.dji.sample.manage.service.ICapacityCameraService; +import com.dji.sdk.cloudapi.livestream.DockLivestreamAbilityUpdate; +import com.dji.sdk.cloudapi.livestream.RcLivestreamAbilityUpdate; +import com.dji.sdk.cloudapi.livestream.api.AbstractLivestreamService; +import com.dji.sdk.mqtt.state.TopicStateRequest; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/6 + */ +@Service +public class SDKLivestreamService extends AbstractLivestreamService { + + @Autowired + private ICapacityCameraService capacityCameraService; + + @Autowired + private ObjectMapper objectMapper; + + @Override + public void dockLivestreamAbilityUpdate(TopicStateRequest request, MessageHeaders headers) { + saveLiveCapacity(request.getData().getLiveCapacity().getDeviceList()); + } + + @Override + public void rcLivestreamAbilityUpdate(TopicStateRequest request, MessageHeaders headers) { + saveLiveCapacity(request.getData().getLiveCapacity().getDeviceList()); + } + + private void saveLiveCapacity(Object data) { + List devices = objectMapper.convertValue( + data, new TypeReference>() {}); + for (CapacityDeviceReceiver capacityDeviceReceiver : devices) { + capacityCameraService.saveCapacityCameraReceiverList( + capacityDeviceReceiver.getCameraList(), capacityDeviceReceiver.getSn()); + } + } +} diff --git a/src/main/java/com/dji/sample/manage/service/impl/SDKLogService.java b/src/main/java/com/dji/sample/manage/service/impl/SDKLogService.java new file mode 100644 index 0000000..7edd96e --- /dev/null +++ b/src/main/java/com/dji/sample/manage/service/impl/SDKLogService.java @@ -0,0 +1,14 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sdk.cloudapi.log.api.AbstractLogService; +import org.springframework.stereotype.Service; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/6 + */ +@Service +public class SDKLogService extends AbstractLogService { + +} diff --git a/src/main/java/com/dji/sample/manage/service/impl/SDKOrganizationService.java b/src/main/java/com/dji/sample/manage/service/impl/SDKOrganizationService.java new file mode 100644 index 0000000..5d019f4 --- /dev/null +++ b/src/main/java/com/dji/sample/manage/service/impl/SDKOrganizationService.java @@ -0,0 +1,177 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.dto.DeviceDictionaryDTO; +import com.dji.sample.manage.model.dto.WorkspaceDTO; +import com.dji.sample.manage.service.IDeviceDictionaryService; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sample.manage.service.IWorkspaceService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.dji.sdk.cloudapi.organization.*; +import com.dji.sdk.cloudapi.organization.api.AbstractOrganizationService; +import com.dji.sdk.cloudapi.tsa.DeviceIconUrl; +import com.dji.sdk.cloudapi.tsa.IconUrlEnum; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/7 + */ +@Service +public class SDKOrganizationService extends AbstractOrganizationService { + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IDeviceDictionaryService dictionaryService; + + @Autowired + private IWorkspaceService workspaceService; + + @Override + public TopicRequestsResponse> airportBindStatus(TopicRequestsRequest request, MessageHeaders headers) { + List data = request.getData().getDevices(); + + List bindStatusResult = new ArrayList<>(); + for (BindStatusResponseDevice bindStatus : data) { + Optional deviceOpt = deviceService.getDeviceBySn(bindStatus.getSn()); + bindStatusResult.add(deviceOpt.isPresent() ? dto2BindStatus(deviceOpt.get()) : + new BindStatusRequestDevice().setSn(bindStatus.getSn()).setDeviceBindOrganization(false)); + } + return new TopicRequestsResponse>() + .setData(MqttReply.success(new AirportBindStatusResponse().setBindStatus(bindStatusResult))); + } + + @Override + public TopicRequestsResponse> airportOrganizationGet(TopicRequestsRequest request, MessageHeaders headers) { + AirportOrganizationGetRequest organizationGet = request.getData(); + if (!StringUtils.hasText(organizationGet.getDeviceBindingCode())) { + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); + } + + Optional workspace = workspaceService.getWorkspaceNameByBindCode(organizationGet.getDeviceBindingCode()); + if (workspace.isEmpty()) { + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.GET_ORGANIZATION_FAILED)); + } + + return new TopicRequestsResponse>() + .setData(MqttReply.success(new AirportOrganizationGetResponse() + .setOrganizationName(workspace.get().getWorkspaceName()))); + } + + @Override + public TopicRequestsResponse> airportOrganizationBind(TopicRequestsRequest request, MessageHeaders headers) { + List devices = request.getData().getBindDevices(); + OrganizationBindDevice dock = null; + OrganizationBindDevice drone = null; + for (OrganizationBindDevice device : devices) { + DeviceDomainEnum val = device.getDeviceModelKey().getDomain(); + if (val == DeviceDomainEnum.DOCK) { + dock = device; + } + if (val == DeviceDomainEnum.DRONE) { + drone = device; + } + } + + Optional dockOpt = bindDevice2Dto(dock); + Optional droneOpt = bindDevice2Dto(drone); + List bindResult = new ArrayList<>(); + + droneOpt.ifPresent(droneDto -> { + dockOpt.get().setChildDeviceSn(droneDto.getDeviceSn()); + boolean success = deviceService.saveOrUpdateDevice(droneDto); + bindResult.add(success ? + OrganizationBindInfo.success(droneDto.getDeviceSn()) : + new OrganizationBindInfo(droneDto.getDeviceSn(), + CommonErrorEnum.DEVICE_BINDING_FAILED.getCode()) + ); + }); + boolean success = deviceService.saveOrUpdateDevice(dockOpt.get()); + + bindResult.add(success ? + OrganizationBindInfo.success(dock.getSn()) : + new OrganizationBindInfo(dock.getSn(), + CommonErrorEnum.DEVICE_BINDING_FAILED.getCode())); + + return new TopicRequestsResponse>() + .setData(MqttReply.success(new AirportOrganizationBindResponse().setErrInfos(bindResult))); + } + + /** + * Convert device binding data object into database entity object. + * + * @param receiver + * @return + */ + public Optional bindDevice2Dto(OrganizationBindDevice receiver) { + if (receiver == null) { + return Optional.empty(); + } + + DeviceEnum deviceModelKey = receiver.getDeviceModelKey(); + Optional dictionaryOpt = dictionaryService.getOneDictionaryInfoByTypeSubType( + deviceModelKey.getDomain().getDomain(), deviceModelKey.getType().getType(), + deviceModelKey.getSubType().getSubType()); + DeviceDTO.DeviceDTOBuilder builder = DeviceDTO.builder(); + + dictionaryOpt.ifPresent(entity -> + builder.deviceName(entity.getDeviceName()) + .nickname(entity.getDeviceName()) + .deviceDesc(entity.getDeviceDesc())); + Optional workspace = workspaceService.getWorkspaceNameByBindCode(receiver.getDeviceBindingCode()); + + DeviceDTO dto = builder + .workspaceId(workspace.map(WorkspaceDTO::getWorkspaceId).orElse(receiver.getOrganizationId())) + .domain(deviceModelKey.getDomain()) + .type(deviceModelKey.getType()) + .subType(deviceModelKey.getSubType()) + .deviceSn(receiver.getSn()) + .boundStatus(true) + .loginTime(LocalDateTime.now()) + .boundTime(LocalDateTime.now()) + .iconUrl(new DeviceIconUrl() + .setSelectIconUrl(IconUrlEnum.SELECT_EQUIPMENT.getUrl()) + .setNormalIconUrl(IconUrlEnum.NORMAL_EQUIPMENT.getUrl())) + .build(); + if (StringUtils.hasText(receiver.getDeviceCallsign())) { + dto.setNickname(receiver.getDeviceCallsign()); + } else { + Optional deviceOpt = deviceService.getDeviceBySn(receiver.getSn()); + dto.setNickname(deviceOpt.map(DeviceDTO::getNickname).orElse(dto.getNickname())); + } + return Optional.of(dto); + } + + /** + * Convert device data transfer object into device binding status data object. + * @param device + * @return + */ + private BindStatusRequestDevice dto2BindStatus(DeviceDTO device) { + if (device == null) { + return null; + } + return new BindStatusRequestDevice() + .setSn(device.getDeviceSn()) + .setDeviceCallsign(device.getNickname()) + .setDeviceBindOrganization(device.getBoundStatus()) + .setOrganizationId(device.getWorkspaceId()) + .setOrganizationName(device.getWorkspaceName()); + } +} diff --git a/src/main/java/com/dji/sample/manage/service/impl/SDKPropertySetService.java b/src/main/java/com/dji/sample/manage/service/impl/SDKPropertySetService.java new file mode 100644 index 0000000..73ce404 --- /dev/null +++ b/src/main/java/com/dji/sample/manage/service/impl/SDKPropertySetService.java @@ -0,0 +1,14 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sdk.cloudapi.property.api.AbstractPropertyService; +import org.springframework.stereotype.Service; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/6 + */ +@Service +public class SDKPropertySetService extends AbstractPropertyService { + +} diff --git a/src/main/java/com/dji/sample/manage/service/impl/TopologyServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/TopologyServiceImpl.java index a255068..2a37485 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/TopologyServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/TopologyServiceImpl.java @@ -1,12 +1,13 @@ package com.dji.sample.manage.service.impl; import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.dto.TopologyDTO; import com.dji.sample.manage.model.dto.TopologyDeviceDTO; -import com.dji.sample.manage.model.enums.DeviceDomainEnum; import com.dji.sample.manage.model.param.DeviceQueryParam; import com.dji.sample.manage.service.IDeviceService; import com.dji.sample.manage.service.ITopologyService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.tsa.DeviceTopology; +import com.dji.sdk.cloudapi.tsa.TopologyList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -26,15 +27,15 @@ public class TopologyServiceImpl implements ITopologyService { private IDeviceService deviceService; @Override - public List getDeviceTopology(String workspaceId) { + public List getDeviceTopology(String workspaceId) { // Query the information of all gateway devices in the workspace. List gatewayList = deviceService.getDevicesByParams( DeviceQueryParam.builder() .workspaceId(workspaceId) - .domains(List.of(DeviceDomainEnum.GATEWAY.getVal())) + .domains(List.of(DeviceDomainEnum.REMOTER_CONTROL.getDomain())) .build()); - List topologyList = new ArrayList<>(); + List topologyList = new ArrayList<>(); gatewayList.forEach(device -> this.getDeviceTopologyByGatewaySn(device.getDeviceSn()) .ifPresent(topologyList::add)); @@ -42,21 +43,22 @@ public class TopologyServiceImpl implements ITopologyService { return topologyList; } - public Optional getDeviceTopologyByGatewaySn(String gatewaySn) { + public Optional getDeviceTopologyByGatewaySn(String gatewaySn) { Optional dtoOptional = deviceService.getDeviceBySn(gatewaySn); if (dtoOptional.isEmpty()) { return Optional.empty(); } - List parents = new ArrayList<>(); + List parents = new ArrayList<>(); DeviceDTO device = dtoOptional.get(); - TopologyDeviceDTO gateway = deviceService.deviceConvertToTopologyDTO(device); + DeviceTopology gateway = deviceService.deviceConvertToTopologyDTO(device); parents.add(gateway); // Query the topology data of the drone based on the drone sn. Optional deviceTopo = deviceService.getDeviceTopoForPilot(device.getChildDeviceSn()); - List deviceTopoList = new ArrayList<>(); + List deviceTopoList = new ArrayList<>(); deviceTopo.ifPresent(deviceTopoList::add); - return Optional.ofNullable(TopologyDTO.builder().parents(parents).hosts(deviceTopoList).build()); + return Optional.ofNullable(new TopologyList().setParents(parents).setHosts(deviceTopoList)); } + } diff --git a/src/main/java/com/dji/sample/manage/service/impl/UserServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/UserServiceImpl.java index d754831..d466897 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/UserServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/UserServiceImpl.java @@ -8,11 +8,8 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.Pagination; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.common.util.JwtUtil; -import com.dji.sample.component.mqtt.config.MqttConfiguration; +import com.dji.sample.component.mqtt.config.MqttPropertyConfiguration; import com.dji.sample.manage.dao.IUserMapper; import com.dji.sample.manage.model.dto.UserDTO; import com.dji.sample.manage.model.dto.UserListDTO; @@ -21,6 +18,9 @@ import com.dji.sample.manage.model.entity.UserEntity; import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.service.IUserService; import com.dji.sample.manage.service.IWorkspaceService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @@ -43,54 +43,50 @@ public class UserServiceImpl implements IUserService { private IUserMapper mapper; @Autowired - private MqttConfiguration mqttConfiguration; + private MqttPropertyConfiguration mqttPropertyConfiguration; @Autowired private IWorkspaceService workspaceService; @Override - public ResponseResult getUserByUsername(String username, String workspaceId) { + public HttpResultResponse getUserByUsername(String username, String workspaceId) { UserEntity userEntity = this.getUserByUsername(username); if (userEntity == null) { - return ResponseResult.builder() - .code(HttpStatus.UNAUTHORIZED.value()) - .message("invalid username") - .build(); + return new HttpResultResponse() + .setCode(HttpStatus.UNAUTHORIZED.value()) + .setMessage("invalid username"); } UserDTO user = this.entityConvertToDTO(userEntity); user.setWorkspaceId(workspaceId); - return ResponseResult.success(user); + return HttpResultResponse.success(user); } @Override - public ResponseResult userLogin(String username, String password, Integer flag) { + public HttpResultResponse userLogin(String username, String password, Integer flag) { // check user UserEntity userEntity = this.getUserByUsername(username); if (userEntity == null) { - return ResponseResult.builder() - .code(HttpStatus.UNAUTHORIZED.value()) - .message("invalid username") - .build(); + return new HttpResultResponse() + .setCode(HttpStatus.UNAUTHORIZED.value()) + .setMessage("invalid username"); } if (flag.intValue() != userEntity.getUserType().intValue()) { - return ResponseResult.error("The account type does not match."); + return HttpResultResponse.error("The account type does not match."); } if (!password.equals(userEntity.getPassword())) { - return ResponseResult.builder() - .code(HttpStatus.UNAUTHORIZED.value()) - .message("invalid password") - .build(); + return new HttpResultResponse() + .setCode(HttpStatus.UNAUTHORIZED.value()) + .setMessage("invalid password"); } Optional workspaceOpt = workspaceService.getWorkspaceByWorkspaceId(userEntity.getWorkspaceId()); if (workspaceOpt.isEmpty()) { - return ResponseResult.builder() - .code(HttpStatus.UNAUTHORIZED.value()) - .message("invalid workspace id") - .build(); + return new HttpResultResponse() + .setCode(HttpStatus.UNAUTHORIZED.value()) + .setMessage("invalid workspace id"); } CustomClaim customClaim = new CustomClaim(userEntity.getUserId(), @@ -101,10 +97,10 @@ public class UserServiceImpl implements IUserService { String token = JwtUtil.createToken(customClaim.convertToMap()); UserDTO userDTO = entityConvertToDTO(userEntity); - userDTO.setMqttAddr(MqttConfiguration.getBasicMqttAddress()); + userDTO.setMqttAddr(MqttPropertyConfiguration.getBasicMqttAddress()); userDTO.setAccessToken(token); userDTO.setWorkspaceId(workspaceOpt.get().getWorkspaceId()); - return ResponseResult.success(userDTO); + return HttpResultResponse.success(userDTO); } @Override @@ -212,7 +208,7 @@ public class UserServiceImpl implements IUserService { .userType(entity.getUserType()) .mqttUsername(entity.getMqttUsername()) .mqttPassword(entity.getMqttPassword()) - .mqttAddr(MqttConfiguration.getBasicMqttAddress()) + .mqttAddr(MqttPropertyConfiguration.getBasicMqttAddress()) .build(); } } diff --git a/src/main/java/com/dji/sample/manage/service/impl/WorkspaceServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/WorkspaceServiceImpl.java index b90d262..ff492b2 100644 --- a/src/main/java/com/dji/sample/manage/service/impl/WorkspaceServiceImpl.java +++ b/src/main/java/com/dji/sample/manage/service/impl/WorkspaceServiceImpl.java @@ -1,24 +1,15 @@ package com.dji.sample.manage.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.dji.sample.common.error.CommonErrorEnum; -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.IMessageSenderService; import com.dji.sample.manage.dao.IWorkspaceMapper; import com.dji.sample.manage.model.dto.WorkspaceDTO; import com.dji.sample.manage.model.entity.WorkspaceEntity; -import com.dji.sample.manage.model.receiver.OrganizationGetReceiver; import com.dji.sample.manage.service.IWorkspaceService; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.mqtt.support.MqttHeaders; -import org.springframework.messaging.MessageHeaders; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.StringUtils; -import java.util.Map; import java.util.Optional; @Service @@ -31,9 +22,6 @@ public class WorkspaceServiceImpl implements IWorkspaceService { @Autowired private ObjectMapper objectMapper; - @Autowired - private IMessageSenderService messageSenderService; - @Override public Optional getWorkspaceByWorkspaceId(String workspaceId) { return Optional.ofNullable(entityConvertToDto( @@ -48,35 +36,6 @@ public class WorkspaceServiceImpl implements IWorkspaceService { mapper.selectOne(new LambdaQueryWrapper().eq(WorkspaceEntity::getBindCode, bindCode)))); } - @Override - @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET, outputChannel = ChannelName.OUTBOUND) - public void replyOrganizationGet(CommonTopicReceiver receiver, MessageHeaders headers) { - OrganizationGetReceiver organizationGet = objectMapper.convertValue(receiver.getData(), OrganizationGetReceiver.class); - CommonTopicResponse.CommonTopicResponseBuilder builder = CommonTopicResponse.builder() - .tid(receiver.getTid()) - .bid(receiver.getBid()) - .method(RequestsMethodEnum.AIRPORT_ORGANIZATION_GET.getMethod()) - .timestamp(System.currentTimeMillis()); - - String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString() + TopicConst._REPLY_SUF; - - if (!StringUtils.hasText(organizationGet.getDeviceBindingCode())) { - builder.data(RequestsReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); - messageSenderService.publish(topic, builder.build()); - return; - } - - Optional workspace = this.getWorkspaceNameByBindCode(organizationGet.getDeviceBindingCode()); - if (workspace.isEmpty()) { - builder.data(RequestsReply.error(CommonErrorEnum.GET_ORGANIZATION_FAILED)); - messageSenderService.publish(topic, builder.build()); - return; - } - - builder.data(RequestsReply.success(Map.of(MapKeyConst.ORGANIZATION_NAME, workspace.get().getWorkspaceName()))); - messageSenderService.publish(topic, builder.build()); - } - /** * Convert database entity objects into workspace data transfer object. * @param entity diff --git a/src/main/java/com/dji/sample/map/controller/WorkspaceElementController.java b/src/main/java/com/dji/sample/map/controller/WorkspaceElementController.java index 1970479..ce65c19 100644 --- a/src/main/java/com/dji/sample/map/controller/WorkspaceElementController.java +++ b/src/main/java/com/dji/sample/map/controller/WorkspaceElementController.java @@ -1,19 +1,23 @@ package com.dji.sample.map.controller; import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.websocket.model.BizCodeEnum; -import com.dji.sample.component.websocket.service.ISendMessageService; -import com.dji.sample.map.model.dto.*; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; import com.dji.sample.map.service.IWorkspaceElementService; +import com.dji.sdk.cloudapi.map.CreateMapElementRequest; +import com.dji.sdk.cloudapi.map.CreateMapElementResponse; +import com.dji.sdk.cloudapi.map.GetMapElementsResponse; +import com.dji.sdk.cloudapi.map.UpdateMapElementRequest; +import com.dji.sdk.cloudapi.map.api.IHttpMapService; +import com.dji.sdk.common.HttpResultResponse; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; @@ -23,14 +27,26 @@ import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; * @date 2021/11/29 */ @RestController -@RequestMapping("${url.map.prefix}${url.map.version}/workspaces") -public class WorkspaceElementController { +public class WorkspaceElementController implements IHttpMapService { @Autowired private IWorkspaceElementService elementService; @Autowired - private ISendMessageService sendMessageService; + private IWebSocketMessageService sendMessageService; + + /** + * Delete all the element information in this group based on the group id. + * @param workspaceId + * @param groupId + * @return + */ + @DeleteMapping("${url.map.prefix}${url.map.version}/workspaces/{workspace_id}/element-groups/{group_id}/elements") + public HttpResultResponse deleteAllElementByGroupId(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "group_id") String groupId) { + + return elementService.deleteAllElementByGroupId(workspaceId, groupId); + } /** * In the first connection, pilot will send out this http request to obtain the group element list. @@ -41,71 +57,52 @@ public class WorkspaceElementController { * @param isDistributed * @return */ - @GetMapping("/{workspace_id}/element-groups") - public ResponseResult> getAllElements(@PathVariable(name = "workspace_id") String workspaceId, - @RequestParam(name = "group_id", required = false) String groupId, - @RequestParam(name = "is_distributed", required = false) Boolean isDistributed) { - List groupsList = elementService.getAllGroupsByWorkspaceId(workspaceId, groupId, isDistributed); - return ResponseResult.success(groupsList); + @Override + public HttpResultResponse> getMapElements(String workspaceId, String groupId, Boolean isDistributed, HttpServletRequest req, HttpServletResponse rsp) { + List groupsList = elementService.getAllGroupsByWorkspaceId(workspaceId, groupId, isDistributed); + return HttpResultResponse.>success(groupsList); } /** * When user draws a point, line or polygon on the PILOT/Web side. * Save the element information to the database. - * @param request * @param workspaceId * @param groupId * @param elementCreate * @return */ - @PostMapping("/{workspace_id}/element-groups/{group_id}/elements") - public ResponseResult saveElement(HttpServletRequest request, - @PathVariable(name = "workspace_id") String workspaceId, - @PathVariable(name = "group_id") String groupId, - @RequestBody ElementCreateDTO elementCreate) { - CustomClaim claims = (CustomClaim) request.getAttribute(TOKEN_CLAIM); + @Override + public HttpResultResponse createMapElement(String workspaceId, String groupId, + @Valid CreateMapElementRequest elementCreate, HttpServletRequest req, HttpServletResponse rsp) { + CustomClaim claims = (CustomClaim) req.getAttribute(TOKEN_CLAIM); // Set the creator of the element elementCreate.getResource().setUsername(claims.getUsername()); - ResponseResult response = elementService.saveElement(groupId, elementCreate); - if (response.getCode() != ResponseResult.CODE_SUCCESS) { + HttpResultResponse response = elementService.saveElement(workspaceId, groupId, elementCreate); + if (response.getCode() != HttpResultResponse.CODE_SUCCESS) { return response; } - // Notify all WebSocket connections in this workspace to be updated when an element is created. - elementService.getElementByElementId(elementCreate.getId()) - .ifPresent(groupElement -> sendMessageService.sendBatch( - workspaceId, BizCodeEnum.MAP_ELEMENT_CREATE.getCode(), groupElement)); - - return ResponseResult.success(new ConcurrentHashMap<>(Map.of("id", elementCreate.getId()))); + return HttpResultResponse.success(new CreateMapElementResponse().setId(elementCreate.getId())); } /** * When user edits a point, line or polygon on the PILOT/Web side. * Update the element information to the database. - * @param request * @param workspaceId * @param elementId * @param elementUpdate * @return */ - @PutMapping("/{workspace_id}/elements/{element_id}") - public ResponseResult updateElement(HttpServletRequest request, - @PathVariable(name = "workspace_id") String workspaceId, - @PathVariable(name = "element_id") String elementId, - @RequestBody ElementUpdateDTO elementUpdate) { + @Override + public HttpResultResponse updateMapElement(String workspaceId, String elementId, @Valid UpdateMapElementRequest elementUpdate, HttpServletRequest req, HttpServletResponse rsp) { + CustomClaim claims = (CustomClaim) req.getAttribute(TOKEN_CLAIM); - CustomClaim claims = (CustomClaim) request.getAttribute(TOKEN_CLAIM); - - ResponseResult response = elementService.updateElement(elementId, elementUpdate, claims.getUsername()); - if (response.getCode() != ResponseResult.CODE_SUCCESS) { + HttpResultResponse response = elementService.updateElement(workspaceId, elementId, elementUpdate, claims.getUsername()); + if (response.getCode() != HttpResultResponse.CODE_SUCCESS) { return response; } - // Notify all WebSocket connections in this workspace to update when there is an element update. - elementService.getElementByElementId(elementId) - .ifPresent(groupElement -> sendMessageService.sendBatch( - workspaceId, BizCodeEnum.MAP_ELEMENT_UPDATE.getCode(), groupElement)); return response; } @@ -116,45 +113,9 @@ public class WorkspaceElementController { * @param elementId * @return */ - @DeleteMapping("/{workspace_id}/elements/{element_id}") - public ResponseResult deleteElement(@PathVariable(name = "workspace_id") String workspaceId, - @PathVariable(name = "element_id") String elementId) { - - Optional elementOpt = elementService.getElementByElementId(elementId); - - ResponseResult response = elementService.deleteElement(elementId); - - // Notify all WebSocket connections in this workspace to update when an element is deleted. - if (ResponseResult.CODE_SUCCESS == response.getCode()) { - elementOpt.ifPresent(element -> - sendMessageService.sendBatch(workspaceId, BizCodeEnum.MAP_ELEMENT_DELETE.getCode(), - WebSocketElementDelDTO.builder() - .elementId(elementId) - .groupId(element.getGroupId()) - .build())); - } - return response; - } - - /** - * Delete all the element information in this group based on the group id. - * @param workspaceId - * @param groupId - * @return - */ - @DeleteMapping("/{workspace_id}/element-groups/{group_id}/elements") - public ResponseResult deleteAllElementByGroupId(@PathVariable(name = "workspace_id") String workspaceId, - @PathVariable(name = "group_id") String groupId) { - - ResponseResult response = elementService.deleteAllElementByGroupId(groupId); + @Override + public HttpResultResponse deleteMapElement(String workspaceId, String elementId, HttpServletRequest req, HttpServletResponse rsp) { - // Notify all WebSocket connections in this workspace to update when elements are deleted. - if (ResponseResult.CODE_SUCCESS == response.getCode()) { - - sendMessageService.sendBatch(workspaceId, BizCodeEnum.MAP_GROUP_REFRESH.getCode(), - // Group ids that need to re-request data - new ConcurrentHashMap(Map.of("ids", new String[]{groupId}))); - } - return response; + return elementService.deleteElement(workspaceId, elementId); } } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/map/model/dto/ContentPropertyDTO.java b/src/main/java/com/dji/sample/map/model/dto/ContentPropertyDTO.java deleted file mode 100644 index e8fe1d2..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/ContentPropertyDTO.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.dji.sample.map.model.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 0.2 - * @date 2021/11/30 - */ -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Data -public class ContentPropertyDTO { - - private String color; - - @JsonProperty("clampToGround") - private Boolean clampToGround; - -} diff --git a/src/main/java/com/dji/sample/map/model/dto/ElementCoordinateDTO.java b/src/main/java/com/dji/sample/map/model/dto/ElementCoordinateDTO.java deleted file mode 100644 index e0799c4..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/ElementCoordinateDTO.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.dji.sample.map.model.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 0.2 - * @date 2021/11/30 - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class ElementCoordinateDTO { - - private Double longitude; - - private Double latitude; - - private Double altitude; - -} diff --git a/src/main/java/com/dji/sample/map/model/dto/ElementCreateDTO.java b/src/main/java/com/dji/sample/map/model/dto/ElementCreateDTO.java deleted file mode 100644 index a594bba..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/ElementCreateDTO.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.dji.sample.map.model.dto; - -import lombok.Data; - -/** - * @author sean - * @version 0.2 - * @date 2021/11/30 - */ -@Data -public class ElementCreateDTO { - - private String id; - - private String name; - - private ElementResourceDTO resource; -} diff --git a/src/main/java/com/dji/sample/map/model/dto/ElementLineStringDTO.java b/src/main/java/com/dji/sample/map/model/dto/ElementLineStringDTO.java deleted file mode 100644 index 117790b..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/ElementLineStringDTO.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.dji.sample.map.model.dto; - -import com.dji.sample.map.model.enums.ElementTypeEnum; -import lombok.Data; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author sean - * @version 0.2 - * @date 2021/11/30 - */ -@Data -public class ElementLineStringDTO extends ElementType { - - private Double[][] coordinates; - - public ElementLineStringDTO() { - super(ElementTypeEnum.LINE_STRING.getDesc()); - } - - @Override - public List convertToList() { - List coordinateList = new ArrayList<>(); - for (Double[] coordinate : this.coordinates) { - coordinateList.add(ElementCoordinateDTO.builder() - .longitude(coordinate[0]) - .latitude(coordinate[1]) - .build()); - } - return coordinateList; - } - - @Override - public void adapterCoordinateType(List coordinateList) { - if (CollectionUtils.isEmpty(coordinateList)) { - return; - } - this.coordinates = new Double[coordinateList.size()][2]; - for (int i = 0; i < this.coordinates.length; i++) { - this.coordinates[i][0] = coordinateList.get(i).getLongitude(); - this.coordinates[i][1] = coordinateList.get(i).getLatitude(); - } - } -} diff --git a/src/main/java/com/dji/sample/map/model/dto/ElementPointDTO.java b/src/main/java/com/dji/sample/map/model/dto/ElementPointDTO.java deleted file mode 100644 index 3eeee7d..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/ElementPointDTO.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.dji.sample.map.model.dto; - -import com.dji.sample.map.model.enums.ElementTypeEnum; -import lombok.Data; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author sean - * @version 0.2 - * @date 2021/11/30 - */ -@Data -public class ElementPointDTO extends ElementType { - - private Double[] coordinates; - - public ElementPointDTO() { - super(ElementTypeEnum.POINT.getDesc()); - } - - @Override - public List convertToList() { - List coordinateList = new ArrayList<>(); - coordinateList.add(ElementCoordinateDTO.builder() - .longitude(this.coordinates[0]) - .latitude(this.coordinates[1]) - .altitude(this.coordinates.length == 3 ? this.coordinates[2] : null) - .build()); - return coordinateList; - } - - @Override - public void adapterCoordinateType(List coordinateList) { - if (CollectionUtils.isEmpty(coordinateList)) { - return; - } - this.coordinates = new Double[]{ - coordinateList.get(0).getLongitude(), - coordinateList.get(0).getLatitude(), - coordinateList.get(0).getAltitude() - }; - } -} diff --git a/src/main/java/com/dji/sample/map/model/dto/ElementPolygonDTO.java b/src/main/java/com/dji/sample/map/model/dto/ElementPolygonDTO.java deleted file mode 100644 index 35a8d35..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/ElementPolygonDTO.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.dji.sample.map.model.dto; - -import com.dji.sample.map.model.enums.ElementTypeEnum; -import lombok.Data; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author sean - * @version 0.2 - * @date 2021/11/30 - */ -@Data -public class ElementPolygonDTO extends ElementType { - - private Double[][][] coordinates; - - public ElementPolygonDTO() { - super(ElementTypeEnum.POLYGON.getDesc()); - } - - @Override - public List convertToList() { - List coordinateList = new ArrayList<>(); - - for (Double[] coordinate : this.coordinates[0]) { - coordinateList.add(ElementCoordinateDTO.builder() - .longitude(coordinate[0]) - .latitude(coordinate[1]) - .build()); - } - return coordinateList; - } - - @Override - public void adapterCoordinateType(List coordinateList) { - if (CollectionUtils.isEmpty(coordinateList)) { - return; - } - this.coordinates = new Double[1][coordinateList.size()][2]; - for (int i = 0; i < this.coordinates[0].length; i++) { - this.coordinates[0][i][0] = coordinateList.get(i).getLongitude(); - this.coordinates[0][i][1] = coordinateList.get(i).getLatitude(); - } - } -} diff --git a/src/main/java/com/dji/sample/map/model/dto/ElementResourceDTO.java b/src/main/java/com/dji/sample/map/model/dto/ElementResourceDTO.java deleted file mode 100644 index b89df70..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/ElementResourceDTO.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.map.model.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 0.2 - * @date 2021/11/29 - */ -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Data -public class ElementResourceDTO { - - private Integer type; - - @JsonProperty(value = "user_name") - private String username; - - private ResourceContentDTO content; -} diff --git a/src/main/java/com/dji/sample/map/model/dto/ElementType.java b/src/main/java/com/dji/sample/map/model/dto/ElementType.java deleted file mode 100644 index 1fdf3f6..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/ElementType.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.dji.sample.map.model.dto; - -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -/** - * @author sean - * @version 0.2 - * @date 2021/11/30 - */ -@Data -@NoArgsConstructor -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", - include = JsonTypeInfo.As.EXISTING_PROPERTY, defaultImpl = ElementType.class) -@JsonSubTypes({ - @JsonSubTypes.Type(value = ElementPointDTO.class, name = "Point"), - @JsonSubTypes.Type(value = ElementLineStringDTO.class, name = "LineString"), - @JsonSubTypes.Type(value = ElementPolygonDTO.class, name = "Polygon") -}) -public abstract class ElementType { - - private String type; - - ElementType(String type) { - this.type = type; - } - - /** - * Convert coordinate data into objects and then add them to the collection. - * @return - */ - public abstract List convertToList(); - - /** - * Converts coordinates in a collection of objects to a specific type. - * @param coordinateList - */ - public abstract void adapterCoordinateType(List coordinateList); -} diff --git a/src/main/java/com/dji/sample/map/model/dto/ElementUpdateDTO.java b/src/main/java/com/dji/sample/map/model/dto/ElementUpdateDTO.java deleted file mode 100644 index 58897e2..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/ElementUpdateDTO.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.dji.sample.map.model.dto; - -import lombok.Data; - -/** - * @author sean - * @version 0.2 - * @date 2021/12/1 - */ -@Data -public class ElementUpdateDTO { - - private String name; - - private ResourceContentDTO content; - -} diff --git a/src/main/java/com/dji/sample/map/model/dto/GroupDTO.java b/src/main/java/com/dji/sample/map/model/dto/GroupDTO.java deleted file mode 100644 index 1c75e67..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/GroupDTO.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.dji.sample.map.model.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -/** - * @author sean - * @version 0.2 - * @date 2021/11/29 - */ -@AllArgsConstructor -@NoArgsConstructor -@Builder -@Data -public class GroupDTO { - - private String id; - - private String name; - - private Integer type; - - private List elements; - - @JsonProperty(value = "is_distributed") - private Boolean isDistributed; - - @JsonProperty(value = "is_lock") - private Boolean isLock; - - @JsonProperty(value = "create_time") - private Long createTime; -} diff --git a/src/main/java/com/dji/sample/map/model/dto/GroupElementDTO.java b/src/main/java/com/dji/sample/map/model/dto/GroupElementDTO.java index b48d1b6..70ff1e4 100644 --- a/src/main/java/com/dji/sample/map/model/dto/GroupElementDTO.java +++ b/src/main/java/com/dji/sample/map/model/dto/GroupElementDTO.java @@ -1,5 +1,6 @@ package com.dji.sample.map.model.dto; +import com.dji.sdk.cloudapi.map.ElementResource; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; @@ -18,7 +19,6 @@ import lombok.NoArgsConstructor; @Builder @JsonInclude(JsonInclude.Include.NON_NULL) public class GroupElementDTO { - private Integer display; @JsonProperty("id") private String elementId; @@ -31,7 +31,7 @@ public class GroupElementDTO { @JsonProperty(value = "update_time") private Long updateTime; - private ElementResourceDTO resource; + private ElementResource resource; @JsonProperty("group_id") private String groupId; diff --git a/src/main/java/com/dji/sample/map/model/dto/ResourceContentDTO.java b/src/main/java/com/dji/sample/map/model/dto/ResourceContentDTO.java deleted file mode 100644 index 6ae3c9a..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/ResourceContentDTO.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.dji.sample.map.model.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 0.2 - * @date 2021/11/30 - */ -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Data -public class ResourceContentDTO { - - @Builder.Default - private String type = "Feature"; - - private ContentPropertyDTO properties; - - private ElementType geometry; -} diff --git a/src/main/java/com/dji/sample/map/model/dto/WebSocketElementDelDTO.java b/src/main/java/com/dji/sample/map/model/dto/WebSocketElementDelDTO.java deleted file mode 100644 index 5d99272..0000000 --- a/src/main/java/com/dji/sample/map/model/dto/WebSocketElementDelDTO.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.dji.sample.map.model.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 0.2 - * @date 2021/12/2 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class WebSocketElementDelDTO { - - @JsonProperty("id") - private String elementId; - - @JsonProperty("group_id") - private String groupId; -} diff --git a/src/main/java/com/dji/sample/map/model/enums/ElementTypeEnum.java b/src/main/java/com/dji/sample/map/model/enums/ElementTypeEnum.java index 886ebe2..0b91b61 100644 --- a/src/main/java/com/dji/sample/map/model/enums/ElementTypeEnum.java +++ b/src/main/java/com/dji/sample/map/model/enums/ElementTypeEnum.java @@ -1,9 +1,6 @@ package com.dji.sample.map.model.enums; -import com.dji.sample.map.model.dto.ElementLineStringDTO; -import com.dji.sample.map.model.dto.ElementPointDTO; -import com.dji.sample.map.model.dto.ElementPolygonDTO; -import com.dji.sample.map.model.dto.ElementType; +import com.dji.sdk.cloudapi.map.*; import java.util.Optional; @@ -14,56 +11,51 @@ import java.util.Optional; */ public enum ElementTypeEnum { - POINT(0, "Point"), + POINT(ElementResourceTypeEnum.POINT), - LINE_STRING(1, "LineString"), + LINE_STRING(ElementResourceTypeEnum.LINE_STRING), - POLYGON(2, "Polygon"), + POLYGON(ElementResourceTypeEnum.POLYGON); - UNKNOWN(-1, "Unknown"); + private ElementResourceTypeEnum typeEnum; - private int val; - - private String desc; - - ElementTypeEnum(int val, String desc) { - this.val = val; - this.desc = desc; + ElementTypeEnum(ElementResourceTypeEnum typeEnum) { + this.typeEnum = typeEnum; } - public static Optional findType(int val) { - if (POINT.val == val) { - return Optional.of(new ElementPointDTO()); + public static Optional findType(int val) { + if (POINT.typeEnum.getType() == val) { + return Optional.of(new ElementPointGeometry()); } - if (LINE_STRING.val == val) { - return Optional.of(new ElementLineStringDTO()); + if (LINE_STRING.typeEnum.getType() == val) { + return Optional.of(new ElementLineStringGeometry()); } - if (POLYGON.val == val) { - return Optional.of(new ElementPolygonDTO()); + if (POLYGON.typeEnum.getType() == val) { + return Optional.of(new ElementPolygonGeometry()); } return Optional.empty(); } public String getDesc() { - return desc; + return typeEnum.getTypeName(); } public static int findVal(String desc) { - if (POINT.desc.equals(desc)) { - return POINT.val; + if (POINT.typeEnum.getTypeName().equals(desc)) { + return POINT.typeEnum.getType(); } - if (LINE_STRING.desc.equals(desc)) { - return LINE_STRING.val; + if (LINE_STRING.typeEnum.getTypeName().equals(desc)) { + return LINE_STRING.typeEnum.getType(); } - if (POLYGON.desc.equals(desc)) { - return POLYGON.val; + if (POLYGON.typeEnum.getTypeName().equals(desc)) { + return POLYGON.typeEnum.getType(); } - return UNKNOWN.val; + throw new RuntimeException("unknown type:" + desc); } } diff --git a/src/main/java/com/dji/sample/map/service/IElementCoordinateService.java b/src/main/java/com/dji/sample/map/service/IElementCoordinateService.java index 7668205..5764729 100644 --- a/src/main/java/com/dji/sample/map/service/IElementCoordinateService.java +++ b/src/main/java/com/dji/sample/map/service/IElementCoordinateService.java @@ -1,6 +1,6 @@ package com.dji.sample.map.service; -import com.dji.sample.map.model.dto.ElementCoordinateDTO; +import com.dji.sdk.cloudapi.map.ElementCoordinate; import java.util.List; @@ -16,7 +16,7 @@ public interface IElementCoordinateService { * @param elementId * @return */ - List getCoordinateByElementId(String elementId); + List getCoordinateByElementId(String elementId); /** * Save all the coordinate data of this element. @@ -24,7 +24,7 @@ public interface IElementCoordinateService { * @param elementId * @return */ - Boolean saveCoordinate(List coordinate, String elementId); + Boolean saveCoordinate(List coordinate, String elementId); /** * Delete all the coordinates of the element according to its id. diff --git a/src/main/java/com/dji/sample/map/service/IGroupElementService.java b/src/main/java/com/dji/sample/map/service/IGroupElementService.java index d6513fa..47097aa 100644 --- a/src/main/java/com/dji/sample/map/service/IGroupElementService.java +++ b/src/main/java/com/dji/sample/map/service/IGroupElementService.java @@ -1,8 +1,9 @@ package com.dji.sample.map.service; -import com.dji.sample.map.model.dto.ElementCreateDTO; -import com.dji.sample.map.model.dto.ElementUpdateDTO; import com.dji.sample.map.model.dto.GroupElementDTO; +import com.dji.sdk.cloudapi.map.CreateMapElementRequest; +import com.dji.sdk.cloudapi.map.MapGroupElement; +import com.dji.sdk.cloudapi.map.UpdateMapElementRequest; import java.util.List; import java.util.Optional; @@ -19,7 +20,7 @@ public interface IGroupElementService { * @param groupId * @return */ - List getElementsByGroupId(String groupId); + List getElementsByGroupId(String groupId); /** * Save all the elements. @@ -27,7 +28,7 @@ public interface IGroupElementService { * @param elementCreate * @return */ - Boolean saveElement(String groupId, ElementCreateDTO elementCreate); + Boolean saveElement(String groupId, CreateMapElementRequest elementCreate); /** * Query the element information based on the element id and update element. @@ -36,7 +37,7 @@ public interface IGroupElementService { * @param username * @return */ - Boolean updateElement(String elementId, ElementUpdateDTO elementUpdate, String username); + Boolean updateElement(String elementId, UpdateMapElementRequest elementUpdate, String username); /** * Delete the element based on the element id. diff --git a/src/main/java/com/dji/sample/map/service/IGroupService.java b/src/main/java/com/dji/sample/map/service/IGroupService.java index bead14b..14cefd8 100644 --- a/src/main/java/com/dji/sample/map/service/IGroupService.java +++ b/src/main/java/com/dji/sample/map/service/IGroupService.java @@ -1,6 +1,6 @@ package com.dji.sample.map.service; -import com.dji.sample.map.model.dto.GroupDTO; +import com.dji.sdk.cloudapi.map.GetMapElementsResponse; import java.util.List; @@ -19,6 +19,6 @@ public interface IGroupService { * @param isDistributed Used to define if the group needs to be distributed. Default is true. * @return */ - List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed); + List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed); } diff --git a/src/main/java/com/dji/sample/map/service/IWorkspaceElementService.java b/src/main/java/com/dji/sample/map/service/IWorkspaceElementService.java index 4d24769..2d4699f 100644 --- a/src/main/java/com/dji/sample/map/service/IWorkspaceElementService.java +++ b/src/main/java/com/dji/sample/map/service/IWorkspaceElementService.java @@ -1,10 +1,8 @@ package com.dji.sample.map.service; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.map.model.dto.ElementCreateDTO; -import com.dji.sample.map.model.dto.ElementUpdateDTO; -import com.dji.sample.map.model.dto.GroupDTO; import com.dji.sample.map.model.dto.GroupElementDTO; +import com.dji.sdk.cloudapi.map.*; +import com.dji.sdk.common.HttpResultResponse; import java.util.List; import java.util.Optional; @@ -24,34 +22,40 @@ public interface IWorkspaceElementService { * @param isDistributed * @return */ - List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed); + List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed); /** * Save all the elements, including the information of the elements in the group, * and the coordinate information in the elements. + * + * @param workspaceId * @param groupId * @param elementCreate * @return */ - ResponseResult saveElement(String groupId, ElementCreateDTO elementCreate); + HttpResultResponse saveElement(String workspaceId, String groupId, CreateMapElementRequest elementCreate); /** * Update the element information based on the element id, * including the information of the elements in the group, and the coordinate information in the elements. + * + * @param workspaceId * @param elementId * @param elementUpdate * @param username * @return */ - ResponseResult updateElement(String elementId, ElementUpdateDTO elementUpdate, String username); + HttpResultResponse updateElement(String workspaceId, String elementId, UpdateMapElementRequest elementUpdate, String username); /** * Delete the element information based on the element id, * including the information of the elements in the group, and the coordinate information in the elements. + * + * @param workspaceId * @param elementId * @return */ - ResponseResult deleteElement(String elementId); + HttpResultResponse deleteElement(String workspaceId, String elementId); /** * Query an element based on the element id, @@ -64,8 +68,14 @@ public interface IWorkspaceElementService { /** * Delete all the elements information based on the group id, * including the information of the elements in the group, and the coordinate information in the elements. + * + * @param workspaceId * @param groupId * @return */ - ResponseResult deleteAllElementByGroupId(String groupId); + HttpResultResponse deleteAllElementByGroupId(String workspaceId, String groupId); + + MapElementCreateWsResponse element2CreateWsElement(GroupElementDTO element); + + MapElementUpdateWsResponse element2UpdateWsElement(GroupElementDTO element); } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/map/service/impl/ElementCoordinateServiceImpl.java b/src/main/java/com/dji/sample/map/service/impl/ElementCoordinateServiceImpl.java index bab9775..beff134 100644 --- a/src/main/java/com/dji/sample/map/service/impl/ElementCoordinateServiceImpl.java +++ b/src/main/java/com/dji/sample/map/service/impl/ElementCoordinateServiceImpl.java @@ -3,9 +3,9 @@ package com.dji.sample.map.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.dji.sample.map.dao.IElementCoordinateMapper; -import com.dji.sample.map.model.dto.ElementCoordinateDTO; import com.dji.sample.map.model.entity.ElementCoordinateEntity; import com.dji.sample.map.service.IElementCoordinateService; +import com.dji.sdk.cloudapi.map.ElementCoordinate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -26,7 +26,7 @@ public class ElementCoordinateServiceImpl implements IElementCoordinateService { private IElementCoordinateMapper mapper; @Override - public List getCoordinateByElementId(String elementId) { + public List getCoordinateByElementId(String elementId) { return mapper.selectList( new LambdaQueryWrapper() .eq(ElementCoordinateEntity::getElementId, elementId)) @@ -36,8 +36,8 @@ public class ElementCoordinateServiceImpl implements IElementCoordinateService { } @Override - public Boolean saveCoordinate(List coordinateList, String elementId) { - for (ElementCoordinateDTO coordinate : coordinateList) { + public Boolean saveCoordinate(List coordinateList, String elementId) { + for (ElementCoordinate coordinate : coordinateList) { ElementCoordinateEntity entity = this.dtoConvertToEntity(coordinate); entity.setElementId(elementId); @@ -60,17 +60,15 @@ public class ElementCoordinateServiceImpl implements IElementCoordinateService { * @param entity * @return */ - private ElementCoordinateDTO entityConvertToDto(ElementCoordinateEntity entity) { - ElementCoordinateDTO.ElementCoordinateDTOBuilder builder = ElementCoordinateDTO.builder(); + private ElementCoordinate entityConvertToDto(ElementCoordinateEntity entity) { if (entity == null) { - return builder.build(); + return null; } - return builder - .longitude(entity.getLongitude()) - .latitude(entity.getLatitude()) - .altitude(entity.getAltitude()) - .build(); + return new ElementCoordinate() + .setLongitude(entity.getLongitude()) + .setLatitude(entity.getLatitude()) + .setAltitude(entity.getAltitude()); } /** @@ -78,9 +76,8 @@ public class ElementCoordinateServiceImpl implements IElementCoordinateService { * @param coordinate * @return */ - private ElementCoordinateEntity dtoConvertToEntity(ElementCoordinateDTO coordinate) { + private ElementCoordinateEntity dtoConvertToEntity(ElementCoordinate coordinate) { ElementCoordinateEntity.ElementCoordinateEntityBuilder builder = ElementCoordinateEntity.builder(); - if (coordinate == null) { return builder.build(); } diff --git a/src/main/java/com/dji/sample/map/service/impl/GroupElementServiceImpl.java b/src/main/java/com/dji/sample/map/service/impl/GroupElementServiceImpl.java index f516f04..675a0f7 100644 --- a/src/main/java/com/dji/sample/map/service/impl/GroupElementServiceImpl.java +++ b/src/main/java/com/dji/sample/map/service/impl/GroupElementServiceImpl.java @@ -2,11 +2,12 @@ package com.dji.sample.map.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.dji.sample.map.dao.IGroupElementMapper; -import com.dji.sample.map.model.dto.*; +import com.dji.sample.map.model.dto.GroupElementDTO; import com.dji.sample.map.model.entity.GroupElementEntity; import com.dji.sample.map.model.enums.ElementTypeEnum; import com.dji.sample.map.service.IElementCoordinateService; import com.dji.sample.map.service.IGroupElementService; +import com.dji.sdk.cloudapi.map.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -31,15 +32,14 @@ public class GroupElementServiceImpl implements IGroupElementService { private IElementCoordinateService elementCoordinateService; @Override - public List getElementsByGroupId(String groupId) { + public List getElementsByGroupId(String groupId) { List elementList = mapper.selectList( new LambdaQueryWrapper() .eq(GroupElementEntity::getGroupId, groupId)); - List groupElementList = new ArrayList<>(); + List groupElementList = new ArrayList<>(); for (GroupElementEntity elementEntity : elementList) { - - GroupElementDTO groupElement = this.entityConvertToDto(elementEntity); + MapGroupElement groupElement = this.entityConvertToDto(elementEntity); groupElementList.add(groupElement); this.addCoordinateToElement(groupElement, elementEntity); @@ -48,7 +48,7 @@ public class GroupElementServiceImpl implements IGroupElementService { } @Override - public Boolean saveElement(String groupId, ElementCreateDTO elementCreate) { + public Boolean saveElement(String groupId, CreateMapElementRequest elementCreate) { Optional groupElementOpt = this.getEntityByElementId(elementCreate.getId()); if (groupElementOpt.isPresent()) { @@ -57,11 +57,17 @@ public class GroupElementServiceImpl implements IGroupElementService { GroupElementEntity groupElement = this.createDtoConvertToEntity(elementCreate); groupElement.setGroupId(groupId); - return mapper.insert(groupElement) > 0; + boolean saveElement = mapper.insert(groupElement) > 0; + if (!saveElement) { + return false; + } + // save coordinate + return elementCoordinateService.saveCoordinate( + elementCreate.getResource().getContent().getGeometry().convertToList(), elementCreate.getId()); } @Override - public Boolean updateElement(String elementId, ElementUpdateDTO elementUpdate, String username) { + public Boolean updateElement(String elementId, UpdateMapElementRequest elementUpdate, String username) { Optional groupElementOpt = this.getEntityByElementId(elementId); if (groupElementOpt.isEmpty()) { return false; @@ -70,8 +76,16 @@ public class GroupElementServiceImpl implements IGroupElementService { GroupElementEntity groupElement = groupElementOpt.get(); groupElement.setUsername(username); this.updateEntityWithDto(elementUpdate, groupElement); - - return mapper.updateById(groupElement) > 0; + boolean update = mapper.updateById(groupElement) > 0; + if (!update) { + return false; + } + // delete all coordinates according to element id. + boolean delCoordinate = elementCoordinateService.deleteCoordinateByElementId(elementId); + // save coordinate + boolean saveCoordinate = elementCoordinateService.saveCoordinate( + elementUpdate.getContent().getGeometry().convertToList(), elementId); + return delCoordinate & saveCoordinate; } @Override @@ -93,11 +107,24 @@ public class GroupElementServiceImpl implements IGroupElementService { return Optional.empty(); } GroupElementEntity elementEntity = elementEntityOpt.get(); - GroupElementDTO groupElement = this.entityConvertToDto(elementEntity); + MapGroupElement groupElement = this.entityConvertToDto(elementEntity); this.addCoordinateToElement(groupElement, elementEntity); + return Optional.ofNullable(groupElement2Dto(groupElement, elementEntity.getGroupId())); + } - return Optional.ofNullable(groupElement); + private GroupElementDTO groupElement2Dto(MapGroupElement element, String groupId) { + if (null == element) { + return null; + } + return GroupElementDTO.builder() + .elementId(element.getId()) + .groupId(groupId) + .updateTime(element.getUpdateTime()) + .createTime(element.getCreateTime()) + .name(element.getName()) + .resource(element.getResource()) + .build(); } /** @@ -105,24 +132,19 @@ public class GroupElementServiceImpl implements IGroupElementService { * @param element * @param elementEntity */ - private void addCoordinateToElement(GroupElementDTO element, GroupElementEntity elementEntity) { - Optional coordinateOpt = ElementTypeEnum.findType(elementEntity.getElementType()); + private void addCoordinateToElement(MapGroupElement element, GroupElementEntity elementEntity) { + Optional coordinateOpt = ElementTypeEnum.findType(elementEntity.getElementType()); if (coordinateOpt.isEmpty()) { return; } - - ElementType elementType = coordinateOpt.get(); - - element.getResource().setContent( - ResourceContentDTO.builder() - .properties(ContentPropertyDTO.builder() - .clampToGround(elementEntity.getClampToGround()) - .color(elementEntity.getColor()) - .build()) - .geometry(elementType) - .build()); - - elementType.adapterCoordinateType( + element.getResource() + .setContent(new ElementContent() + .setProperties(new ElementProperty() + .setClampToGround(elementEntity.getClampToGround()) + .setColor(elementEntity.getColor())) + .setGeometry(coordinateOpt.get())); + + coordinateOpt.get().adapterCoordinateType( elementCoordinateService.getCoordinateByElementId(elementEntity.getElementId())); } @@ -142,24 +164,19 @@ public class GroupElementServiceImpl implements IGroupElementService { * @param entity * @return */ - private GroupElementDTO entityConvertToDto(GroupElementEntity entity) { - GroupElementDTO.GroupElementDTOBuilder builder = GroupElementDTO.builder(); + private MapGroupElement entityConvertToDto(GroupElementEntity entity) { if (entity == null) { - return builder.build(); + return null; } - return builder - .display(entity.getDisplay()) - .groupId(entity.getGroupId()) - .elementId(entity.getElementId()) - .name(entity.getElementName()) - .createTime(entity.getCreateTime()) - .updateTime(entity.getUpdateTime()) - .resource(ElementResourceDTO.builder() - .type(entity.getElementType()) - .username(entity.getUsername()) - .build()) - .build(); + return new MapGroupElement() + .setId(entity.getElementId()) + .setName(entity.getElementName()) + .setCreateTime(entity.getCreateTime()) + .setUpdateTime(entity.getUpdateTime()) + .setResource(new ElementResource() + .setType(ElementResourceTypeEnum.find(entity.getElementType())) + .setUsername(entity.getUsername())); } /** @@ -167,8 +184,8 @@ public class GroupElementServiceImpl implements IGroupElementService { * @param elementCreate * @return */ - private GroupElementEntity createDtoConvertToEntity(ElementCreateDTO elementCreate) { - ContentPropertyDTO properties = elementCreate.getResource().getContent().getProperties(); + private GroupElementEntity createDtoConvertToEntity(CreateMapElementRequest elementCreate) { + ElementProperty properties = elementCreate.getResource().getContent().getProperties(); return GroupElementEntity.builder() .elementId(elementCreate.getId()) .elementName(elementCreate.getName()) @@ -184,7 +201,7 @@ public class GroupElementServiceImpl implements IGroupElementService { * @param elementUpdate * @param groupElement */ - private void updateEntityWithDto(ElementUpdateDTO elementUpdate, GroupElementEntity groupElement) { + private void updateEntityWithDto(UpdateMapElementRequest elementUpdate, GroupElementEntity groupElement) { if (elementUpdate == null || groupElement == null) { return; } diff --git a/src/main/java/com/dji/sample/map/service/impl/GroupServiceImpl.java b/src/main/java/com/dji/sample/map/service/impl/GroupServiceImpl.java index 07ac7f1..5c3e913 100644 --- a/src/main/java/com/dji/sample/map/service/impl/GroupServiceImpl.java +++ b/src/main/java/com/dji/sample/map/service/impl/GroupServiceImpl.java @@ -2,10 +2,11 @@ package com.dji.sample.map.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.dji.sample.map.dao.IGroupMapper; -import com.dji.sample.map.model.dto.GroupDTO; import com.dji.sample.map.model.entity.GroupEntity; import com.dji.sample.map.service.IGroupElementService; import com.dji.sample.map.service.IGroupService; +import com.dji.sdk.cloudapi.map.GetMapElementsResponse; +import com.dji.sdk.cloudapi.map.GroupTypeEnum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -30,7 +31,7 @@ public class GroupServiceImpl implements IGroupService { private IGroupElementService groupElementService; @Override - public List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed) { + public List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed) { return mapper.selectList( new LambdaQueryWrapper() @@ -47,20 +48,15 @@ public class GroupServiceImpl implements IGroupService { * @param entity * @return */ - private GroupDTO entityConvertToDto(GroupEntity entity) { - GroupDTO.GroupDTOBuilder builder = GroupDTO.builder(); - + private GetMapElementsResponse entityConvertToDto(GroupEntity entity) { if (entity == null) { - return builder.build(); + return null; } - return builder - .id(entity.getGroupId()) - .name(entity.getGroupName()) - .type(entity.getGroupType()) - .isLock(entity.getIsLock()) - .isDistributed(entity.getIsDistributed()) - .createTime(entity.getCreateTime()) - .build(); + return new GetMapElementsResponse() + .setId(entity.getGroupId()) + .setName(entity.getGroupName()) + .setType(GroupTypeEnum.find(entity.getGroupType())) + .setLock(entity.getIsLock()); } } diff --git a/src/main/java/com/dji/sample/map/service/impl/WorkspaceElementServiceImpl.java b/src/main/java/com/dji/sample/map/service/impl/WorkspaceElementServiceImpl.java index 49b5805..7b6c134 100644 --- a/src/main/java/com/dji/sample/map/service/impl/WorkspaceElementServiceImpl.java +++ b/src/main/java/com/dji/sample/map/service/impl/WorkspaceElementServiceImpl.java @@ -1,14 +1,14 @@ package com.dji.sample.map.service.impl; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.map.model.dto.ElementCreateDTO; -import com.dji.sample.map.model.dto.ElementUpdateDTO; -import com.dji.sample.map.model.dto.GroupDTO; +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; import com.dji.sample.map.model.dto.GroupElementDTO; import com.dji.sample.map.service.IElementCoordinateService; import com.dji.sample.map.service.IGroupElementService; import com.dji.sample.map.service.IGroupService; import com.dji.sample.map.service.IWorkspaceElementService; +import com.dji.sdk.cloudapi.map.*; +import com.dji.sdk.common.HttpResultResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -34,60 +34,67 @@ public class WorkspaceElementServiceImpl implements IWorkspaceElementService { @Autowired private IElementCoordinateService elementCoordinateService; + @Autowired + private IWebSocketMessageService webSocketMessageService; + @Override - public List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed) { - List groupList = groupService.getAllGroupsByWorkspaceId(workspaceId, groupId, isDistributed); - groupList.forEach(group -> group.setElements( - groupElementService.getElementsByGroupId(group.getId()) - )); + public List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed) { + List groupList = groupService.getAllGroupsByWorkspaceId(workspaceId, groupId, isDistributed); + groupList.forEach(group -> group.setElements(groupElementService.getElementsByGroupId(group.getId()))); return groupList; } @Override - public ResponseResult saveElement(String groupId, ElementCreateDTO elementCreate) { + public HttpResultResponse saveElement(String workspaceId, String groupId, CreateMapElementRequest elementCreate) { boolean saveElement = groupElementService.saveElement(groupId, elementCreate); if (!saveElement) { - return ResponseResult.error("Failed to save the element."); + return HttpResultResponse.error("Failed to save the element."); } - - // save coordinate - boolean saveCoordinate = elementCoordinateService.saveCoordinate( - elementCreate.getResource().getContent().getGeometry().convertToList(), elementCreate.getId()); - - return saveCoordinate ? - ResponseResult.success() : ResponseResult.error("Failed to save the coordinate."); + // Notify all WebSocket connections in this workspace to be updated when an element is created. + getElementByElementId(elementCreate.getId()) + .ifPresent(groupElement -> webSocketMessageService.sendBatch( + workspaceId, BizCodeEnum.MAP_ELEMENT_CREATE.getCode(), + element2CreateWsElement(groupElement))); + return HttpResultResponse.success(); } - @Override - public ResponseResult updateElement(String elementId, ElementUpdateDTO elementUpdate, String username) { + public HttpResultResponse updateElement(String workspaceId, String elementId, UpdateMapElementRequest elementUpdate, String username) { boolean updElement = groupElementService.updateElement(elementId, elementUpdate, username); if (!updElement) { - return ResponseResult.error("Failed to update the element."); + return HttpResultResponse.error("Failed to update the element."); } - // delete all coordinates according to element id. - boolean delCoordinate = elementCoordinateService.deleteCoordinateByElementId(elementId); - // save coordinate - boolean saveCoordinate = elementCoordinateService.saveCoordinate( - elementUpdate.getContent().getGeometry().convertToList(), elementId); - - return delCoordinate && saveCoordinate ? - ResponseResult.success() : ResponseResult.error("Failed to update the coordinate."); + // Notify all WebSocket connections in this workspace to update when there is an element update. + getElementByElementId(elementId) + .ifPresent(groupElement -> webSocketMessageService.sendBatch( + workspaceId, BizCodeEnum.MAP_ELEMENT_UPDATE.getCode(), + element2UpdateWsElement(groupElement))); + return HttpResultResponse.success(); } @Override - public ResponseResult deleteElement(String elementId) { + public HttpResultResponse deleteElement(String workspaceId, String elementId) { + Optional elementOpt = getElementByElementId(elementId); boolean delElement = groupElementService.deleteElement(elementId); if (!delElement) { - return ResponseResult.error("Failed to delete the element."); + return HttpResultResponse.error("Failed to delete the element."); } // delete all coordinates according to element id. boolean delCoordinate = elementCoordinateService.deleteCoordinateByElementId(elementId); + if (!delCoordinate) { + return HttpResultResponse.error("Failed to delete the coordinate."); + } - return delCoordinate ? - ResponseResult.success() : ResponseResult.error("Failed to delete the coordinate."); + // Notify all WebSocket connections in this workspace to update when an element is deleted. + elementOpt.ifPresent(element -> + webSocketMessageService.sendBatch(workspaceId, BizCodeEnum.MAP_ELEMENT_DELETE.getCode(), + new MapElementDeleteWsResponse() + .setGroupId(element.getGroupId()) + .setId(elementId))); + + return HttpResultResponse.success(); } @Override @@ -96,14 +103,41 @@ public class WorkspaceElementServiceImpl implements IWorkspaceElementService { } @Override - public ResponseResult deleteAllElementByGroupId(String groupId) { - List groupElementList = groupElementService.getElementsByGroupId(groupId); - for (GroupElementDTO groupElement : groupElementList) { - ResponseResult response = this.deleteElement(groupElement.getElementId()); - if (ResponseResult.CODE_SUCCESS != response.getCode()) { + public HttpResultResponse deleteAllElementByGroupId(String workspaceId, String groupId) { + List groupElementList = groupElementService.getElementsByGroupId(groupId); + for (MapGroupElement groupElement : groupElementList) { + HttpResultResponse response = this.deleteElement(workspaceId, groupElement.getId()); + if (HttpResultResponse.CODE_SUCCESS != response.getCode()) { return response; } } - return ResponseResult.success(); + + return HttpResultResponse.success(); + } + + public MapElementCreateWsResponse element2CreateWsElement(GroupElementDTO element) { + if (element == null) { + return null; + } + return new MapElementCreateWsResponse() + .setId(element.getElementId()) + .setGroupId(element.getGroupId()) + .setName(element.getName()) + .setResource(element.getResource()) + .setUpdateTime(element.getUpdateTime()) + .setCreateTime(element.getCreateTime()); + } + + public MapElementUpdateWsResponse element2UpdateWsElement(GroupElementDTO element) { + if (element == null) { + return null; + } + return new MapElementUpdateWsResponse() + .setId(element.getElementId()) + .setGroupId(element.getGroupId()) + .setName(element.getName()) + .setResource(element.getResource()) + .setUpdateTime(element.getUpdateTime()) + .setCreateTime(element.getCreateTime()); } } diff --git a/src/main/java/com/dji/sample/media/controller/FileController.java b/src/main/java/com/dji/sample/media/controller/FileController.java index 8a378f5..3934014 100644 --- a/src/main/java/com/dji/sample/media/controller/FileController.java +++ b/src/main/java/com/dji/sample/media/controller/FileController.java @@ -1,9 +1,9 @@ package com.dji.sample.media.controller; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.media.model.MediaFileDTO; import com.dji.sample.media.service.IFileService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -29,11 +29,11 @@ public class FileController { * @return */ @GetMapping("/{workspace_id}/files") - public ResponseResult> getFilesList(@RequestParam(defaultValue = "1") Long page, - @RequestParam(name = "page_size", defaultValue = "10") Long pageSize, - @PathVariable(name = "workspace_id") String workspaceId) { + public HttpResultResponse> getFilesList(@RequestParam(defaultValue = "1") Long page, + @RequestParam(name = "page_size", defaultValue = "10") Long pageSize, + @PathVariable(name = "workspace_id") String workspaceId) { PaginationData filesList = fileService.getMediaFilesPaginationByWorkspaceId(workspaceId, page, pageSize); - return ResponseResult.success(filesList); + return HttpResultResponse.success(filesList); } /** diff --git a/src/main/java/com/dji/sample/media/controller/MediaController.java b/src/main/java/com/dji/sample/media/controller/MediaController.java index b02f8ad..ec21a54 100644 --- a/src/main/java/com/dji/sample/media/controller/MediaController.java +++ b/src/main/java/com/dji/sample/media/controller/MediaController.java @@ -1,17 +1,17 @@ package com.dji.sample.media.controller; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.MapKeyConst; -import com.dji.sample.media.model.FileUploadDTO; import com.dji.sample.media.service.IMediaService; -import com.fasterxml.jackson.core.JsonProcessingException; +import com.dji.sdk.cloudapi.media.*; +import com.dji.sdk.cloudapi.media.api.IHttpMediaService; +import com.dji.sdk.common.HttpResultResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.RestController; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * @author sean @@ -20,8 +20,7 @@ import java.util.concurrent.ConcurrentHashMap; */ @Slf4j @RestController -@RequestMapping("${url.media.prefix}${url.media.version}/workspaces") -public class MediaController { +public class MediaController implements IHttpMediaService { @Autowired private IMediaService mediaService; @@ -29,45 +28,44 @@ public class MediaController { /** * Check if the file has been uploaded by the fingerprint. * @param workspaceId - * @param file + * @param request * @return */ - @PostMapping("/{workspace_id}/fast-upload") - public ResponseResult fastUpload(@PathVariable(name = "workspace_id") String workspaceId, @RequestBody FileUploadDTO file) { + @Override + public HttpResultResponse mediaFastUpload(String workspaceId, @Valid MediaFastUploadRequest request, HttpServletRequest req, HttpServletResponse rsp) { + boolean isExist = mediaService.fastUpload(workspaceId, request.getFingerprint()); - boolean isExist = mediaService.fastUpload(workspaceId, file.getFingerprint()); - - return isExist ? ResponseResult.success() : ResponseResult.error(file.getFingerprint() + "don't exist."); + return isExist ? HttpResultResponse.success() : HttpResultResponse.error(request.getFingerprint() + "don't exist."); } /** * When the file is uploaded to the storage server by pilot, * the basic information of the file is reported through this interface. * @param workspaceId - * @param file + * @param request * @return */ - @PostMapping("/{workspace_id}/upload-callback") - public ResponseResult uploadCallback(@PathVariable(name = "workspace_id") String workspaceId, @RequestBody FileUploadDTO file) { - mediaService.saveMediaFile(workspaceId, file); - return ResponseResult.success(file.getObjectKey()); - + @Override + public HttpResultResponse mediaUploadCallback(String workspaceId, @Valid MediaUploadCallbackRequest request, HttpServletRequest req, HttpServletResponse rsp) { + mediaService.saveMediaFile(workspaceId, request); + return HttpResultResponse.success(request.getObjectKey()); } /** * Query the files that already exist in this workspace based on the workspace id and the collection of tiny fingerprints. * @param workspaceId - * @param tinyFingerprints There is only one tiny_fingerprint parameter in the body. + * @param request There is only one tiny_fingerprint parameter in the body. * But it is not recommended to use Map to receive the parameter. * @return */ - @PostMapping("/{workspace_id}/files/tiny-fingerprints") - public ResponseResult>> uploadCallback( - @PathVariable(name = "workspace_id") String workspaceId, - @RequestBody Map> tinyFingerprints) throws JsonProcessingException { - - List existingList = mediaService.getExistTinyFingerprints(workspaceId, tinyFingerprints.get(MapKeyConst.TINY_FINGERPRINTS)); - return ResponseResult.success(new ConcurrentHashMap<>(Map.of(MapKeyConst.TINY_FINGERPRINTS, existingList))); + @Override + public HttpResultResponse getExistFileTinyFingerprint(String workspaceId, @Valid GetFileFingerprintRequest request, HttpServletRequest req, HttpServletResponse rsp) { + List existingList = mediaService.getExistTinyFingerprints(workspaceId, request.getTinyFingerprints()); + return HttpResultResponse.success(new GetFileFingerprintResponse().setTinyFingerprints(existingList)); } + @Override + public HttpResultResponse folderUploadCallback(String workspaceId, @Valid FolderUploadCallbackRequest request, HttpServletRequest req, HttpServletResponse rsp) { + return null; + } } \ No newline at end of file diff --git a/src/main/java/com/dji/sample/media/model/CredentialsDTO.java b/src/main/java/com/dji/sample/media/model/CredentialsDTO.java deleted file mode 100644 index d00e953..0000000 --- a/src/main/java/com/dji/sample/media/model/CredentialsDTO.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.dji.sample.media.model; - -import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse; -import io.minio.credentials.Credentials; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - - -/** - * @author sean - * @version 0.2 - * @date 2021/12/7 - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CredentialsDTO { - - private static final int DELAY = 300; - - private String accessKeyId; - - private String accessKeySecret; - - private Long expire; - - private String securityToken; - - public CredentialsDTO(Credentials credentials, long expire) { - this.accessKeyId = credentials.accessKey(); - this.accessKeySecret = credentials.secretKey(); - this.securityToken = credentials.sessionToken(); - this.expire = expire - DELAY; - } - - public CredentialsDTO(AssumeRoleResponse.Credentials credentials, long expire) { - this.accessKeyId = credentials.getAccessKeyId(); - this.accessKeySecret = credentials.getAccessKeySecret(); - this.securityToken = credentials.getSecurityToken(); - this.expire = expire - DELAY; - } - - public CredentialsDTO(com.amazonaws.services.securitytoken.model.Credentials credentials) { - this.accessKeyId = credentials.getAccessKeyId(); - this.accessKeySecret = credentials.getSecretAccessKey(); - this.securityToken = credentials.getSessionToken(); - this.expire = (credentials.getExpiration().getTime() - System.currentTimeMillis()) / 1000 - DELAY; - } -} diff --git a/src/main/java/com/dji/sample/media/model/FileExtensionDTO.java b/src/main/java/com/dji/sample/media/model/FileExtensionDTO.java deleted file mode 100644 index c1f96b7..0000000 --- a/src/main/java/com/dji/sample/media/model/FileExtensionDTO.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.dji.sample.media.model; - -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.Data; - -/** - * @author sean - * @version 0.2 - * @date 2021/12/7 - */ -@Data -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) -public class FileExtensionDTO { - - private String droneModelKey; - - private Boolean isOriginal; - - private String payloadModelKey; - - private String tinnyFingerprint; - - private String sn; - - private String flightId; - -} diff --git a/src/main/java/com/dji/sample/media/model/FileMetadataDTO.java b/src/main/java/com/dji/sample/media/model/FileMetadataDTO.java deleted file mode 100644 index bab4b5a..0000000 --- a/src/main/java/com/dji/sample/media/model/FileMetadataDTO.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.dji.sample.media.model; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.Data; - -import java.util.Date; - -/** - * @author sean - * @version 0.2 - * @date 2021/12/7 - */ -@Data -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) -public class FileMetadataDTO { - - private Double absoluteAltitude; - - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssX") - private Date createdTime; - - private Double gimbalYawDegree; - - private PositionDTO photoedPosition; - - private PositionDTO shootPosition; - - private Double relativeAltitude; -} diff --git a/src/main/java/com/dji/sample/media/model/FileUploadCallback.java b/src/main/java/com/dji/sample/media/model/FileUploadCallback.java deleted file mode 100644 index 62bbcc7..0000000 --- a/src/main/java/com/dji/sample/media/model/FileUploadCallback.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.dji.sample.media.model; - -import lombok.Data; - -/** - * @author sean - * @version 1.1 - * @date 2022/6/9 - */ -@Data -public class FileUploadCallback { - - private Integer result; - - private Integer progress; - - private FileUploadDTO file; -} diff --git a/src/main/java/com/dji/sample/media/model/FileUploadDTO.java b/src/main/java/com/dji/sample/media/model/FileUploadDTO.java deleted file mode 100644 index acfa910..0000000 --- a/src/main/java/com/dji/sample/media/model/FileUploadDTO.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dji.sample.media.model; - -import lombok.Data; - -/** - * @author sean - * @version 0.2 - * @date 2021/12/7 - */ -@Data -public class FileUploadDTO { - - private FileExtensionDTO ext; - - private String fingerprint; - - private String name; - - private String path; - - private FileMetadataDTO metadata; - - private String objectKey; - - private Integer subFileType; -} diff --git a/src/main/java/com/dji/sample/media/model/MediaFileCountDTO.java b/src/main/java/com/dji/sample/media/model/MediaFileCountDTO.java index ac804c6..2aa952a 100644 --- a/src/main/java/com/dji/sample/media/model/MediaFileCountDTO.java +++ b/src/main/java/com/dji/sample/media/model/MediaFileCountDTO.java @@ -27,4 +27,6 @@ public class MediaFileCountDTO { private Integer mediaCount; private Integer uploadedCount; + + private String deviceSn; } diff --git a/src/main/java/com/dji/sample/media/model/PositionDTO.java b/src/main/java/com/dji/sample/media/model/PositionDTO.java deleted file mode 100644 index 1b5cda4..0000000 --- a/src/main/java/com/dji/sample/media/model/PositionDTO.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.dji.sample.media.model; - -import lombok.Data; - -/** - * @author sean - * @version 0.2 - * @date 2021/12/7 - */ -@Data -public class PositionDTO { - - private Double lat; - - private Double lng; -} diff --git a/src/main/java/com/dji/sample/media/model/StsCredentialsDTO.java b/src/main/java/com/dji/sample/media/model/StsCredentialsDTO.java deleted file mode 100644 index a4da2ab..0000000 --- a/src/main/java/com/dji/sample/media/model/StsCredentialsDTO.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.dji.sample.media.model; - -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author sean - * @version 0.2 - * @date 2021/12/7 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) -public class StsCredentialsDTO { - - private String bucket; - - private CredentialsDTO credentials; - - private String endpoint; - - private String objectKeyPrefix; - - private String provider; - - private String region; -} diff --git a/src/main/java/com/dji/sample/media/service/IFileService.java b/src/main/java/com/dji/sample/media/service/IFileService.java index d3fd9c8..72f41a1 100644 --- a/src/main/java/com/dji/sample/media/service/IFileService.java +++ b/src/main/java/com/dji/sample/media/service/IFileService.java @@ -1,8 +1,8 @@ package com.dji.sample.media.service; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.media.model.FileUploadDTO; import com.dji.sample.media.model.MediaFileDTO; +import com.dji.sdk.cloudapi.media.MediaUploadCallbackRequest; +import com.dji.sdk.common.PaginationData; import java.net.URL; import java.util.List; @@ -28,7 +28,7 @@ public interface IFileService { * @param file * @return */ - Integer saveFile(String workspaceId, FileUploadDTO file); + Integer saveFile(String workspaceId, MediaUploadCallbackRequest file); /** * Query information about all files in this workspace based on the workspace id. diff --git a/src/main/java/com/dji/sample/media/service/IMediaRedisService.java b/src/main/java/com/dji/sample/media/service/IMediaRedisService.java new file mode 100644 index 0000000..03fc446 --- /dev/null +++ b/src/main/java/com/dji/sample/media/service/IMediaRedisService.java @@ -0,0 +1,26 @@ +package com.dji.sample.media.service; + +import com.dji.sample.media.model.MediaFileCountDTO; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +public interface IMediaRedisService { + + void setMediaCount(String gatewaySn, String jobId, MediaFileCountDTO mediaFile); + + MediaFileCountDTO getMediaCount(String gatewaySn, String jobId); + + boolean delMediaCount(String gatewaySn, String jobId); + + boolean detMediaCountByDeviceSn(String gatewaySn); + + void setMediaHighestPriority(String gatewaySn, MediaFileCountDTO mediaFile); + + MediaFileCountDTO getMediaHighestPriority(String gatewaySn); + + boolean delMediaHighestPriority(String gatewaySn); + +} diff --git a/src/main/java/com/dji/sample/media/service/IMediaService.java b/src/main/java/com/dji/sample/media/service/IMediaService.java index 15a80cc..4b55d2f 100644 --- a/src/main/java/com/dji/sample/media/service/IMediaService.java +++ b/src/main/java/com/dji/sample/media/service/IMediaService.java @@ -1,6 +1,6 @@ package com.dji.sample.media.service; -import com.dji.sample.media.model.FileUploadDTO; +import com.dji.sdk.cloudapi.media.MediaUploadCallbackRequest; import java.util.List; @@ -25,7 +25,7 @@ public interface IMediaService { * @param file * @return */ - Integer saveMediaFile(String workspaceId, FileUploadDTO file); + Integer saveMediaFile(String workspaceId, MediaUploadCallbackRequest file); /** * Query tiny fingerprints about all files in this workspace based on the workspace id. diff --git a/src/main/java/com/dji/sample/media/service/impl/FileServiceImpl.java b/src/main/java/com/dji/sample/media/service/impl/FileServiceImpl.java index 6d73a24..de82e5e 100644 --- a/src/main/java/com/dji/sample/media/service/impl/FileServiceImpl.java +++ b/src/main/java/com/dji/sample/media/service/impl/FileServiceImpl.java @@ -2,18 +2,19 @@ package com.dji.sample.media.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.dji.sample.common.model.Pagination; -import com.dji.sample.common.model.PaginationData; import com.dji.sample.component.oss.model.OssConfiguration; import com.dji.sample.component.oss.service.impl.OssServiceContext; import com.dji.sample.manage.model.dto.DeviceDictionaryDTO; -import com.dji.sample.manage.model.enums.DeviceDomainEnum; import com.dji.sample.manage.service.IDeviceDictionaryService; import com.dji.sample.media.dao.IFileMapper; -import com.dji.sample.media.model.FileUploadDTO; import com.dji.sample.media.model.MediaFileDTO; import com.dji.sample.media.model.MediaFileEntity; import com.dji.sample.media.service.IFileService; +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.dji.sdk.cloudapi.media.MediaSubFileTypeEnum; +import com.dji.sdk.cloudapi.media.MediaUploadCallbackRequest; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -22,7 +23,6 @@ import java.net.URL; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; -import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -66,7 +66,7 @@ public class FileServiceImpl implements IFileService { } @Override - public Integer saveFile(String workspaceId, FileUploadDTO file) { + public Integer saveFile(String workspaceId, MediaUploadCallbackRequest file) { MediaFileEntity fileEntity = this.fileUploadConvertToEntity(file); fileEntity.setWorkspaceId(workspaceId); fileEntity.setFileId(UUID.randomUUID().toString()); @@ -121,7 +121,7 @@ public class FileServiceImpl implements IFileService { * @param file * @return */ - private MediaFileEntity fileUploadConvertToEntity(FileUploadDTO file) { + private MediaFileEntity fileUploadConvertToEntity(MediaUploadCallbackRequest file) { MediaFileEntity.MediaFileEntityBuilder builder = MediaFileEntity.builder(); if (file != null) { @@ -129,19 +129,18 @@ public class FileServiceImpl implements IFileService { .filePath(file.getPath()) .fingerprint(file.getFingerprint()) .objectKey(file.getObjectKey()) - .subFileType(file.getSubFileType()) - .isOriginal(file.getExt().getIsOriginal()) - .jobId(file.getExt().getFlightId()) + .subFileType(Optional.ofNullable(file.getSubFileType()).map(MediaSubFileTypeEnum::getType).orElse(null)) + .isOriginal(file.getExt().getOriginal()) + .jobId(file.getExt().getFileGroupId()) .drone(file.getExt().getSn()) - .tinnyFingerprint(file.getExt().getTinnyFingerprint()); + .tinnyFingerprint(file.getExt().getTinnyFingerprint()) + .payload(file.getExt().getPayloadModelKey().getDevice()); // domain-type-subType - int[] payloadModel = Arrays.stream(file.getExt().getPayloadModelKey().split("-")) - .map(Integer::valueOf) - .mapToInt(Integer::intValue) - .toArray(); + DeviceEnum payloadModelKey = file.getExt().getPayloadModelKey(); Optional payloadDict = deviceDictionaryService - .getOneDictionaryInfoByTypeSubType(DeviceDomainEnum.PAYLOAD.getVal(), payloadModel[1], payloadModel[2]); + .getOneDictionaryInfoByTypeSubType(payloadModelKey.getDomain().getDomain(), + payloadModelKey.getType().getType(), payloadModelKey.getSubType().getSubType()); payloadDict.ifPresent(payload -> builder.payload(payload.getDeviceName())); } return builder.build(); diff --git a/src/main/java/com/dji/sample/media/service/impl/MediaRedisServiceImpl.java b/src/main/java/com/dji/sample/media/service/impl/MediaRedisServiceImpl.java new file mode 100644 index 0000000..9090d75 --- /dev/null +++ b/src/main/java/com/dji/sample/media/service/impl/MediaRedisServiceImpl.java @@ -0,0 +1,54 @@ +package com.dji.sample.media.service.impl; + +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.media.model.MediaFileCountDTO; +import com.dji.sample.media.service.IMediaRedisService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +@Service +@Slf4j +public class MediaRedisServiceImpl implements IMediaRedisService { + + + @Override + public void setMediaCount(String gatewaySn, String jobId, MediaFileCountDTO mediaFile) { + RedisOpsUtils.hashSet(RedisConst.MEDIA_FILE_PREFIX + gatewaySn, jobId, mediaFile); + } + + @Override + public MediaFileCountDTO getMediaCount(String gatewaySn, String jobId) { + return (MediaFileCountDTO) RedisOpsUtils.hashGet(RedisConst.MEDIA_FILE_PREFIX + gatewaySn, jobId); + } + + @Override + public boolean delMediaCount(String gatewaySn, String jobId) { + return RedisOpsUtils.hashDel(RedisConst.MEDIA_FILE_PREFIX + gatewaySn, new String[]{jobId}); + } + + @Override + public boolean detMediaCountByDeviceSn(String gatewaySn) { + return RedisOpsUtils.del(RedisConst.MEDIA_FILE_PREFIX + gatewaySn); + } + + @Override + public void setMediaHighestPriority(String gatewaySn, MediaFileCountDTO mediaFile) { + RedisOpsUtils.setWithExpire(RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + gatewaySn, mediaFile, RedisConst.DEVICE_ALIVE_SECOND * 5); + } + + @Override + public MediaFileCountDTO getMediaHighestPriority(String gatewaySn) { + return (MediaFileCountDTO) RedisOpsUtils.get(RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + gatewaySn); + } + + @Override + public boolean delMediaHighestPriority(String gatewaySn) { + return RedisOpsUtils.del(RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + gatewaySn); + } +} diff --git a/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java b/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java index 5a75fa0..2437008 100644 --- a/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java @@ -1,35 +1,31 @@ package com.dji.sample.media.service.impl; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.ChannelName; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.component.mqtt.model.MapKeyConst; -import com.dji.sample.component.mqtt.service.IMessageSenderService; -import com.dji.sample.component.redis.RedisConst; -import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.component.oss.model.OssConfiguration; import com.dji.sample.component.websocket.model.BizCodeEnum; -import com.dji.sample.component.websocket.service.ISendMessageService; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; import com.dji.sample.manage.model.dto.DeviceDTO; import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.service.IDeviceRedisService; import com.dji.sample.manage.service.IDeviceService; -import com.dji.sample.media.model.FileUploadCallback; -import com.dji.sample.media.model.FileUploadDTO; import com.dji.sample.media.model.MediaFileCountDTO; import com.dji.sample.media.model.MediaFileDTO; import com.dji.sample.media.service.IFileService; +import com.dji.sample.media.service.IMediaRedisService; import com.dji.sample.media.service.IMediaService; -import com.dji.sample.wayline.model.dto.WaylineJobDTO; import com.dji.sample.wayline.service.IWaylineJobService; +import com.dji.sdk.cloudapi.media.*; +import com.dji.sdk.cloudapi.media.api.AbstractMediaService; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; import com.fasterxml.jackson.databind.ObjectMapper; 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.util.StringUtils; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -41,7 +37,7 @@ import java.util.stream.Collectors; */ @Service @Slf4j -public class MediaServiceImpl implements IMediaService { +public class MediaServiceImpl extends AbstractMediaService implements IMediaService { @Autowired private IFileService fileService; @@ -52,25 +48,25 @@ public class MediaServiceImpl implements IMediaService { @Autowired private ObjectMapper objectMapper; - @Autowired - private IMessageSenderService messageSenderService; - @Autowired private IDeviceService deviceService; @Autowired - private ISendMessageService sendMessageService; + private IWebSocketMessageService webSocketMessageService; @Autowired private IDeviceRedisService deviceRedisService; + @Autowired + private IMediaRedisService mediaRedisService; + @Override public Boolean fastUpload(String workspaceId, String fingerprint) { return fileService.checkExist(workspaceId, fingerprint); } @Override - public Integer saveMediaFile(String workspaceId, FileUploadDTO file) { + public Integer saveMediaFile(String workspaceId, MediaUploadCallbackRequest file) { return fileService.saveFile(workspaceId, file); } @@ -92,133 +88,129 @@ public class MediaServiceImpl implements IMediaService { } - /** - * Handle media files messages reported by dock. - * @param receiver - * @return - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FILE_UPLOAD_CALLBACK, outputChannel = ChannelName.OUTBOUND_EVENTS) - public CommonTopicReceiver handleFileUploadCallBack(CommonTopicReceiver receiver) { - FileUploadCallback callback = objectMapper.convertValue(receiver.getData(), FileUploadCallback.class); + @Override + public TopicEventsResponse fileUploadCallback(TopicEventsRequest request, MessageHeaders headers) { + FileUploadCallback callback = request.getData(); - if (callback.getResult() != ResponseResult.CODE_SUCCESS) { + if (MqttReply.CODE_SUCCESS != callback.getResult()) { log.error("Media file upload failed!"); return null; } String jobId = callback.getFile().getExt().getFlightId(); - Optional deviceOpt = deviceRedisService.getDeviceOnline(receiver.getGateway()); - MediaFileCountDTO mediaFileCount = (MediaFileCountDTO) RedisOpsUtils.hashGet(RedisConst.MEDIA_FILE_PREFIX + receiver.getGateway(), jobId); + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + MediaFileCountDTO mediaFileCount = mediaRedisService.getMediaCount(request.getGateway(), jobId); // duplicate data if (deviceOpt.isEmpty() - || (Objects.nonNull(mediaFileCount) && receiver.getBid().equals(mediaFileCount.getBid()) - && receiver.getTid().equals(mediaFileCount.getTid()))) { - return receiver; + || (Objects.nonNull(mediaFileCount) && request.getBid().equals(mediaFileCount.getBid()) + && request.getTid().equals(mediaFileCount.getTid()))) { + return new TopicEventsResponse().setData(MqttReply.success()); } - DeviceDTO device = deviceOpt.get(); - Optional jobOpt = waylineJobService.getJobByJobId(device.getWorkspaceId(), jobId); - if (jobOpt.isPresent()) { - boolean isSave = parseMediaFile(callback, jobOpt.get()); - if (!isSave) { - log.error("Failed to save the file to the database, please check the data manually."); - return null; - } + boolean isSave = parseMediaFile(callback, device); + if (!isSave) { + log.error("Failed to save the file to the database, please check the data manually."); + return null; } - notifyUploadedCount(mediaFileCount, receiver, jobId, device); - return receiver; + notifyUploadedCount(mediaFileCount, request, jobId, device); + return new TopicEventsResponse().setData(MqttReply.success()); } - /** - * update the uploaded count and notify web side - * @param mediaFileCount - * @param receiver - * @param jobId - */ - private void notifyUploadedCount(MediaFileCountDTO mediaFileCount, CommonTopicReceiver receiver, String jobId, DeviceDTO dock) { - // Do not notify when files that do not belong to the route are uploaded. - if (Objects.isNull(mediaFileCount)) { - return; + @Override + public TopicEventsResponse highestPriorityUploadFlightTaskMedia( + TopicEventsRequest request, MessageHeaders headers) { + String jobId = request.getData().getFlightId(); + if (!StringUtils.hasText(jobId)) { + return null; } - mediaFileCount.setBid(receiver.getBid()); - mediaFileCount.setTid(receiver.getTid()); - mediaFileCount.setUploadedCount(mediaFileCount.getUploadedCount() + 1); - - String key = RedisConst.MEDIA_FILE_PREFIX + receiver.getGateway(); - // After all the files of the job are uploaded, delete the media file key. - if (mediaFileCount.getUploadedCount() >= mediaFileCount.getMediaCount()) { - RedisOpsUtils.hashDel(key, new String[]{jobId}); - // After uploading, delete the key with the highest priority. - String highestKey = RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + receiver.getGateway(); - if (RedisOpsUtils.checkExist(highestKey) && - jobId.equals(((MediaFileCountDTO) RedisOpsUtils.get(highestKey)).getJobId())) { - RedisOpsUtils.del(highestKey); + MediaFileCountDTO countDTO = mediaRedisService.getMediaHighestPriority(request.getGateway()); + if (Objects.nonNull(countDTO)) { + if (jobId.equals(countDTO.getJobId())) { + mediaRedisService.setMediaHighestPriority(request.getGateway(), countDTO); + return new TopicEventsResponse().setData(MqttReply.success()); } + countDTO.setPreJobId(countDTO.getJobId()); + } + countDTO.setJobId(jobId); + mediaRedisService.setMediaHighestPriority(request.getGateway(), countDTO); - if (RedisOpsUtils.hashLen(key) == 0) { - RedisOpsUtils.del(key); - } - } else { - RedisOpsUtils.hashSet(key, jobId, mediaFileCount); + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + if (deviceOpt.isEmpty()) { + return null; } - sendMessageService.sendBatch(dock.getWorkspaceId(), UserTypeEnum.WEB.getVal(), - BizCodeEnum.FILE_UPLOAD_CALLBACK.getCode(), mediaFileCount); + webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA.getCode(), countDTO); + + return new TopicEventsResponse().setData(MqttReply.success()); } - private Boolean parseMediaFile(FileUploadCallback callback, WaylineJobDTO job) { + private Boolean parseMediaFile(FileUploadCallback callback, DeviceDTO device) { + MediaUploadCallbackRequest file = convert2callbackRequest(callback.getFile()); // Set the drone sn that shoots the media - Optional dockDTO = deviceService.getDeviceBySn(job.getDockSn()); - dockDTO.ifPresent(dock -> callback.getFile().getExt().setSn(dock.getChildDeviceSn())); + file.getExt().setSn(device.getChildDeviceSn()); // set path - String objectKey = callback.getFile().getObjectKey(); - callback.getFile().setPath(objectKey.substring(objectKey.indexOf("/") + 1, objectKey.lastIndexOf("/"))); + String objectKey = file.getObjectKey(); + file.setPath(objectKey.substring(Optional.of(objectKey.indexOf(OssConfiguration.objectDirPrefix)) + .filter(index -> index > 0).map(index -> index++).orElse(0), + objectKey.lastIndexOf("/"))); - return fileService.saveFile(job.getWorkspaceId(), callback.getFile()) > 0; + return fileService.saveFile(device.getWorkspaceId(), file) > 0; } - /** - * Handles the highest priority message about media uploads. - * @param receiver - * @param headers - * @return - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA, outputChannel = ChannelName.OUTBOUND_EVENTS) - public CommonTopicReceiver handleHighestPriorityUploadFlightTaskMedia(CommonTopicReceiver receiver, MessageHeaders headers) { - Map map = objectMapper.convertValue(receiver.getData(), Map.class); - if (map.isEmpty() || !map.containsKey(MapKeyConst.FLIGHT_ID)) { - return null; + private void notifyUploadedCount(MediaFileCountDTO mediaFileCount, TopicEventsRequest request, String jobId, DeviceDTO dock) { + // Do not notify when files that do not belong to the route are uploaded. + if (Objects.isNull(mediaFileCount)) { + return; } + mediaFileCount.setBid(request.getBid()); + mediaFileCount.setTid(request.getTid()); + mediaFileCount.setUploadedCount(mediaFileCount.getUploadedCount() + 1); - String dockSn = receiver.getGateway(); - String jobId = map.get(MapKeyConst.FLIGHT_ID).toString(); - String key = RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + dockSn; - MediaFileCountDTO countDTO = new MediaFileCountDTO(); - if (RedisOpsUtils.checkExist(key)) { - countDTO = (MediaFileCountDTO) RedisOpsUtils.get(key); - if (jobId.equals(countDTO.getJobId())) { - RedisOpsUtils.setWithExpire(key, countDTO, RedisConst.DEVICE_ALIVE_SECOND * 5); - return null; - } + // After all the files of the job are uploaded, delete the media file key. + if (mediaFileCount.getUploadedCount() >= mediaFileCount.getMediaCount()) { + mediaRedisService.delMediaCount(request.getGateway(), jobId); - countDTO.setPreJobId(countDTO.getJobId()); + // After uploading, delete the key with the highest priority. + MediaFileCountDTO fileCount = mediaRedisService.getMediaHighestPriority(request.getGateway()); + if (Objects.nonNull(fileCount) && jobId.equals(fileCount.getJobId())) { + mediaRedisService.delMediaHighestPriority(request.getGateway()); + } + } else { + mediaRedisService.setMediaCount(request.getGateway(), jobId, mediaFileCount); } - countDTO.setJobId(jobId); - RedisOpsUtils.setWithExpire(key, countDTO, RedisConst.DEVICE_ALIVE_SECOND * 5); + webSocketMessageService.sendBatch(dock.getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.FILE_UPLOAD_CALLBACK.getCode(), mediaFileCount); + } - Optional deviceOpt = deviceRedisService.getDeviceOnline(receiver.getGateway()); - if (deviceOpt.isEmpty()) { + private MediaUploadCallbackRequest convert2callbackRequest(FileUploadCallbackFile file) { + if (Objects.isNull(file)) { return null; } - sendMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), - BizCodeEnum.HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA.getCode(), countDTO); - - return receiver; + return new MediaUploadCallbackRequest() + .setExt(Optional.ofNullable(file.getExt()) + .map(ext -> new MediaFileExtension() + .setDroneModelKey(ext.getDroneModelKey()) + .setFileGroupId(ext.getFlightId()) + .setOriginal(ext.getOriginal()) + .setPayloadModelKey(ext.getPayloadModelKey())) + .orElse(new MediaFileExtension())) + .setMetadata(Optional.ofNullable(file.getMetadata()) + .map(data -> new MediaFileMetadata() + .setAbsoluteAltitude(data.getAbsoluteAltitude()) + .setGimbalYawDegree(data.getGimbalYawDegree()) + .setRelativeAltitude(data.getRelativeAltitude()) + .setShootPosition(data.getShootPosition()) + .setCreatedTime(data.getCreatedTime())) + .get()) + .setName(file.getName()) + .setObjectKey(file.getObjectKey()) + .setPath(file.getPath()); } } diff --git a/src/main/java/com/dji/sample/storage/controller/StorageController.java b/src/main/java/com/dji/sample/storage/controller/StorageController.java index 01147e7..1097cb1 100644 --- a/src/main/java/com/dji/sample/storage/controller/StorageController.java +++ b/src/main/java/com/dji/sample/storage/controller/StorageController.java @@ -1,22 +1,22 @@ package com.dji.sample.storage.controller; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.media.model.StsCredentialsDTO; import com.dji.sample.storage.service.IStorageService; +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; +import com.dji.sdk.cloudapi.storage.api.IHttpStorageService; +import com.dji.sdk.common.HttpResultResponse; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + /** * @author sean * @version 0.3 * @date 2021/12/29 */ @RestController -@RequestMapping("${url.storage.prefix}${url.storage.version}/workspaces/") -public class StorageController { +public class StorageController implements IHttpStorageService { @Autowired private IStorageService storageService; @@ -26,11 +26,9 @@ public class StorageController { * @param workspaceId * @return */ - @PostMapping("/{workspace_id}/sts") - public ResponseResult getSTSCredentials(@PathVariable(name = "workspace_id") String workspaceId) { - - StsCredentialsDTO stsCredentials = storageService.getSTSCredentials(); - return ResponseResult.success(stsCredentials); + @Override + public HttpResultResponse getTemporaryCredential(String workspaceId, HttpServletRequest req, HttpServletResponse rsp) { + StsCredentialsResponse stsCredentials = storageService.getSTSCredentials(); + return HttpResultResponse.success(stsCredentials); } - } diff --git a/src/main/java/com/dji/sample/storage/service/IStorageService.java b/src/main/java/com/dji/sample/storage/service/IStorageService.java index 9bca0ef..4d86788 100644 --- a/src/main/java/com/dji/sample/storage/service/IStorageService.java +++ b/src/main/java/com/dji/sample/storage/service/IStorageService.java @@ -1,8 +1,6 @@ package com.dji.sample.storage.service; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; -import com.dji.sample.media.model.StsCredentialsDTO; -import org.springframework.messaging.MessageHeaders; +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; /** * @author sean @@ -15,12 +13,6 @@ public interface IStorageService { * Get custom temporary credentials object for uploading the media and wayline. * @return temporary credentials object */ - StsCredentialsDTO getSTSCredentials(); + StsCredentialsResponse getSTSCredentials(); - /** - * Handles requests from the dock to obtain temporary credentials. - * @param receiver - * @param headers - */ - void replyConfigGet(CommonTopicReceiver receiver, MessageHeaders headers); } diff --git a/src/main/java/com/dji/sample/storage/service/impl/StorageServiceImpl.java b/src/main/java/com/dji/sample/storage/service/impl/StorageServiceImpl.java index 8c02072..6295400 100644 --- a/src/main/java/com/dji/sample/storage/service/impl/StorageServiceImpl.java +++ b/src/main/java/com/dji/sample/storage/service/impl/StorageServiceImpl.java @@ -1,14 +1,15 @@ package com.dji.sample.storage.service.impl; -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.IMessageSenderService; import com.dji.sample.component.oss.model.OssConfiguration; import com.dji.sample.component.oss.service.impl.OssServiceContext; -import com.dji.sample.media.model.StsCredentialsDTO; import com.dji.sample.storage.service.IStorageService; +import com.dji.sdk.cloudapi.media.StorageConfigGet; +import com.dji.sdk.cloudapi.media.api.AbstractMediaService; +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.MessageHeaders; import org.springframework.stereotype.Service; @@ -18,36 +19,24 @@ import org.springframework.stereotype.Service; * @date 2022/3/9 */ @Service -public class StorageServiceImpl implements IStorageService { - - @Autowired - private IMessageSenderService messageSender; +public class StorageServiceImpl extends AbstractMediaService implements IStorageService { @Autowired private OssServiceContext ossService; @Override - public StsCredentialsDTO getSTSCredentials() { - return StsCredentialsDTO.builder() - .endpoint(OssConfiguration.endpoint) - .bucket(OssConfiguration.bucket) - .credentials(ossService.getCredentials()) - .provider(OssConfiguration.provider) - .objectKeyPrefix(OssConfiguration.objectDirPrefix) - .region(OssConfiguration.region) - .build(); + public StsCredentialsResponse getSTSCredentials() { + return new StsCredentialsResponse() + .setEndpoint(OssConfiguration.endpoint) + .setBucket(OssConfiguration.bucket) + .setCredentials(ossService.getCredentials()) + .setProvider(OssConfiguration.provider) + .setObjectKeyPrefix(OssConfiguration.objectDirPrefix) + .setRegion(OssConfiguration.region); } @Override - @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_STORAGE_CONFIG_GET, outputChannel = ChannelName.OUTBOUND) - public void replyConfigGet(CommonTopicReceiver receiver, MessageHeaders headers) { - CommonTopicResponse response = CommonTopicResponse.builder() - .tid(receiver.getTid()) - .bid(receiver.getBid()) - .data(RequestsReply.success(this.getSTSCredentials())) - .timestamp(System.currentTimeMillis()) - .method(receiver.getMethod()) - .build(); - messageSender.publish(headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF, response); + public TopicRequestsResponse> storageConfigGet(TopicRequestsRequest response, MessageHeaders headers) { + return new TopicRequestsResponse>().setData(MqttReply.success(getSTSCredentials())); } } diff --git a/src/main/java/com/dji/sample/wayline/controller/WaylineFileController.java b/src/main/java/com/dji/sample/wayline/controller/WaylineFileController.java index 918835e..7b877f4 100644 --- a/src/main/java/com/dji/sample/wayline/controller/WaylineFileController.java +++ b/src/main/java/com/dji/sample/wayline/controller/WaylineFileController.java @@ -1,23 +1,31 @@ package com.dji.sample.wayline.controller; import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.wayline.model.dto.WaylineFileDTO; -import com.dji.sample.wayline.model.dto.WaylineFileUploadDTO; -import com.dji.sample.wayline.model.param.WaylineQueryParam; import com.dji.sample.wayline.service.IWaylineFileService; +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.dji.sdk.cloudapi.wayline.*; +import com.dji.sdk.cloudapi.wayline.api.IHttpWaylineService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; import java.io.IOException; import java.net.URL; import java.sql.SQLException; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; @@ -27,38 +35,52 @@ import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; * @date 2021/12/22 */ @RestController -@RequestMapping("${url.wayline.prefix}${url.wayline.version}/workspaces") -public class WaylineFileController { +public class WaylineFileController implements IHttpWaylineService { @Autowired private IWaylineFileService waylineFileService; + /** + * Delete the wayline file in the workspace according to the wayline id. + * @param workspaceId + * @param waylineId + * @return + */ + @DeleteMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/{wayline_id}") + public HttpResultResponse deleteWayline(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "wayline_id") String waylineId) { + boolean isDel = waylineFileService.deleteByWaylineId(workspaceId, waylineId); + return isDel ? HttpResultResponse.success() : HttpResultResponse.error("Failed to delete wayline."); + } + + /** + * Import kmz wayline files. + * @param file + * @return + */ + @PostMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/file/upload") + public HttpResultResponse importKmzFile(HttpServletRequest request, MultipartFile file) { + if (Objects.isNull(file)) { + return HttpResultResponse.error("No file received."); + } + CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); + String workspaceId = customClaim.getWorkspaceId(); + String creator = customClaim.getUsername(); + waylineFileService.importKmzFile(file, workspaceId, creator); + return HttpResultResponse.success(); + } + /** * Query the basic data of the wayline file according to the query conditions. * The query condition field in pilot is fixed. - * @param orderBy Sorted fields. Spliced at the end of the sql statement. - * @param favorited Whether the wayline file is favorited or not. - * @param page - * @param pageSize - * @param templateType + * @param request * @param workspaceId * @return */ - @GetMapping("/{workspace_id}/waylines") - public ResponseResult> getWaylinesPagination(@RequestParam(name = "order_by") String orderBy, - @RequestParam(required = false) boolean favorited, @RequestParam Integer page, - @RequestParam(name = "page_size", defaultValue = "10") Integer pageSize, - @RequestParam(name = "template_type", required = false) Integer[] templateType, - @PathVariable(name = "workspace_id") String workspaceId) { - WaylineQueryParam param = WaylineQueryParam.builder() - .favorited(favorited) - .page(page) - .pageSize(pageSize) - .orderBy(orderBy) - .templateType(templateType) - .build(); - PaginationData data = waylineFileService.getWaylinesByParam(workspaceId, param); - return ResponseResult.success(data); + @Override + public HttpResultResponse> getWaylineList(@Valid GetWaylineListRequest request, String workspaceId, HttpServletRequest req, HttpServletResponse rsp) { + PaginationData data = waylineFileService.getWaylinesByParam(workspaceId, request); + return HttpResultResponse.success(data); } /** @@ -66,44 +88,59 @@ public class WaylineFileController { * and redirect to this address directly for download. * @param workspaceId * @param waylineId - * @param response + * @param req + * @param rsp */ - @GetMapping("/{workspace_id}/waylines/{wayline_id}/url") - public void getFileUrl(@PathVariable(name = "workspace_id") String workspaceId, - @PathVariable(name = "wayline_id") String waylineId, HttpServletResponse response) { - + @Override + public void getWaylineFileDownloadAddress(String workspaceId, String waylineId, HttpServletRequest req, HttpServletResponse rsp) { try { URL url = waylineFileService.getObjectUrl(workspaceId, waylineId); - response.sendRedirect(url.toString()); + rsp.sendRedirect(url.toString()); } catch (IOException | SQLException e) { e.printStackTrace(); } } + /** + * Checking whether the name already exists according to the wayline name must ensure the uniqueness of the wayline name. + * This interface will be called when uploading waylines and must be available. + * @param workspaceId + * @param names + * @return + */ + @Override + public HttpResultResponse> getDuplicatedWaylineName(String workspaceId, @NotNull @Size(min = 1) List names, HttpServletRequest req, HttpServletResponse rsp) { + List existNamesList = waylineFileService.getDuplicateNames(workspaceId, names); + + return HttpResultResponse.success(existNamesList); + } + /** * When the wayline file is uploaded to the storage server by pilot, * the basic information of the file is reported through this interface. * @param request * @param workspaceId - * @param uploadFile * @return */ - @PostMapping("/{workspace_id}/upload-callback") - public ResponseResult uploadCallBack(HttpServletRequest request, - @PathVariable(name = "workspace_id") String workspaceId, - @RequestBody WaylineFileUploadDTO uploadFile) { - - CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); - - WaylineFileDTO metadata = uploadFile.getMetadata(); - metadata.setUsername(customClaim.getUsername()); - metadata.setObjectKey(uploadFile.getObjectKey()); - metadata.setName(uploadFile.getName()); + @Override + public HttpResultResponse fileUploadResultReport(String workspaceId, @Valid WaylineUploadCallbackRequest request, HttpServletRequest req, HttpServletResponse rsp) { + CustomClaim customClaim = (CustomClaim)req.getAttribute(TOKEN_CLAIM); + + WaylineUploadCallbackMetadata metadata = request.getMetadata(); + + WaylineFileDTO file = WaylineFileDTO.builder() + .username(customClaim.getUsername()) + .objectKey(request.getObjectKey()) + .name(request.getName()) + .templateTypes(metadata.getTemplateTypes().stream().map(WaylineTypeEnum::getValue).collect(Collectors.toList())) + .payloadModelKeys(metadata.getPayloadModelKeys().stream().map(DeviceEnum::getDevice).collect(Collectors.toList())) + .droneModelKey(metadata.getDroneModelKey().getDevice()) + .build(); - int id = waylineFileService.saveWaylineFile(workspaceId, metadata); + int id = waylineFileService.saveWaylineFile(workspaceId, file); - return id <= 0 ? ResponseResult.error() : ResponseResult.success(); + return id <= 0 ? HttpResultResponse.error() : HttpResultResponse.success(); } /** @@ -112,12 +149,11 @@ public class WaylineFileController { * @param ids wayline file id * @return */ - @PostMapping("/{workspace_id}/favorites") - public ResponseResult markFavorite(@PathVariable(name = "workspace_id") String workspaceId, - @RequestParam(name = "id") List ids) { + @Override + public HttpResultResponse batchFavoritesWayline(String workspaceId, @NotNull @Size(min = 1) List ids, HttpServletRequest req, HttpServletResponse rsp) { boolean isMark = waylineFileService.markFavorite(workspaceId, ids, true); - return isMark ? ResponseResult.success() : ResponseResult.error(); + return isMark ? HttpResultResponse.success() : HttpResultResponse.error(); } /** @@ -126,56 +162,10 @@ public class WaylineFileController { * @param ids wayline file id * @return */ - @DeleteMapping("/{workspace_id}/favorites") - public ResponseResult unmarkFavorite(@PathVariable(name = "workspace_id") String workspaceId, - @RequestParam(name = "id") List ids) { + @Override + public HttpResultResponse batchUnfavoritesWayline(String workspaceId, @NotNull @Size(min = 1) List ids, HttpServletRequest req, HttpServletResponse rsp) { boolean isMark = waylineFileService.markFavorite(workspaceId, ids, false); - return isMark ? ResponseResult.success() : ResponseResult.error(); - } - - /** - * Checking whether the name already exists according to the wayline name must ensure the uniqueness of the wayline name. - * This interface will be called when uploading waylines and must be available. - * @param workspaceId - * @param names - * @return - */ - @GetMapping("/{workspace_id}/waylines/duplicate-names") - public ResponseResult checkDuplicateNames(@PathVariable(name = "workspace_id") String workspaceId, - @RequestParam(name = "name") List names) { - List existNamesList = waylineFileService.getDuplicateNames(workspaceId, names); - - return ResponseResult.success(existNamesList); - } - - /** - * Delete the wayline file in the workspace according to the wayline id. - * @param workspaceId - * @param waylineId - * @return - */ - @DeleteMapping("/{workspace_id}/waylines/{wayline_id}") - public ResponseResult deleteWayline(@PathVariable(name = "workspace_id") String workspaceId, - @PathVariable(name = "wayline_id") String waylineId) { - boolean isDel = waylineFileService.deleteByWaylineId(workspaceId, waylineId); - return isDel ? ResponseResult.success() : ResponseResult.error("Failed to delete wayline."); - } - - /** - * Import kmz wayline files. - * @param file - * @return - */ - @PostMapping("/{workspace_id}/waylines/file/upload") - public ResponseResult importKmzFile(HttpServletRequest request, MultipartFile file) { - if (Objects.isNull(file)) { - return ResponseResult.error("No file received."); - } - CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); - String workspaceId = customClaim.getWorkspaceId(); - String creator = customClaim.getUsername(); - waylineFileService.importKmzFile(file, workspaceId, creator); - return ResponseResult.success(); + return isMark ? HttpResultResponse.success() : HttpResultResponse.error(); } } diff --git a/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java b/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java index 481b6a2..5d8c259 100644 --- a/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java +++ b/src/main/java/com/dji/sample/wayline/controller/WaylineJobController.java @@ -1,12 +1,13 @@ package com.dji.sample.wayline.controller; import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; import com.dji.sample.wayline.model.dto.WaylineJobDTO; import com.dji.sample.wayline.model.param.CreateJobParam; import com.dji.sample.wayline.model.param.UpdateJobParam; +import com.dji.sample.wayline.service.IFlightTaskService; import com.dji.sample.wayline.service.IWaylineJobService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -29,6 +30,9 @@ public class WaylineJobController { @Autowired private IWaylineJobService waylineJobService; + @Autowired + private IFlightTaskService flighttaskService; + /** * Create a wayline task for the Dock. * @param request @@ -38,12 +42,12 @@ public class WaylineJobController { * @throws SQLException */ @PostMapping("/{workspace_id}/flight-tasks") - public ResponseResult createJob(HttpServletRequest request, @Valid @RequestBody CreateJobParam param, - @PathVariable(name = "workspace_id") String workspaceId) throws SQLException { + public HttpResultResponse createJob(HttpServletRequest request, @Valid @RequestBody CreateJobParam param, + @PathVariable(name = "workspace_id") String workspaceId) throws SQLException { CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); customClaim.setWorkspaceId(workspaceId); - return waylineJobService.publishFlightTask(param, customClaim); + return flighttaskService.publishFlightTask(param, customClaim); } /** @@ -54,11 +58,11 @@ public class WaylineJobController { * @return */ @GetMapping("/{workspace_id}/jobs") - public ResponseResult> getJobs(@RequestParam(defaultValue = "1") Long page, - @RequestParam(name = "page_size", defaultValue = "10") Long pageSize, - @PathVariable(name = "workspace_id") String workspaceId) { + public HttpResultResponse> getJobs(@RequestParam(defaultValue = "1") Long page, + @RequestParam(name = "page_size", defaultValue = "10") Long pageSize, + @PathVariable(name = "workspace_id") String workspaceId) { PaginationData data = waylineJobService.getJobsByWorkspaceId(workspaceId, page, pageSize); - return ResponseResult.success(data); + return HttpResultResponse.success(data); } /** @@ -69,10 +73,10 @@ public class WaylineJobController { * @throws SQLException */ @DeleteMapping("/{workspace_id}/jobs") - public ResponseResult publishCancelJob(@RequestParam(name = "job_id") Set jobIds, - @PathVariable(name = "workspace_id") String workspaceId) throws SQLException { - waylineJobService.cancelFlightTask(workspaceId, jobIds); - return ResponseResult.success(); + public HttpResultResponse publishCancelJob(@RequestParam(name = "job_id") Set jobIds, + @PathVariable(name = "workspace_id") String workspaceId) throws SQLException { + flighttaskService.cancelFlightTask(workspaceId, jobIds); + return HttpResultResponse.success(); } /** @@ -82,17 +86,17 @@ public class WaylineJobController { * @return */ @PostMapping("/{workspace_id}/jobs/{job_id}/media-highest") - public ResponseResult uploadMediaHighestPriority(@PathVariable(name = "workspace_id") String workspaceId, - @PathVariable(name = "job_id") String jobId) { - waylineJobService.uploadMediaHighestPriority(workspaceId, jobId); - return ResponseResult.success(); + public HttpResultResponse uploadMediaHighestPriority(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "job_id") String jobId) { + flighttaskService.uploadMediaHighestPriority(workspaceId, jobId); + return HttpResultResponse.success(); } @PutMapping("/{workspace_id}/jobs/{job_id}") - public ResponseResult updateJobStatus(@PathVariable(name = "workspace_id") String workspaceId, - @PathVariable(name = "job_id") String jobId, - @Valid @RequestBody UpdateJobParam param) { - waylineJobService.updateJobStatus(workspaceId, jobId, param); - return ResponseResult.success(); + public HttpResultResponse updateJobStatus(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "job_id") String jobId, + @Valid @RequestBody UpdateJobParam param) { + flighttaskService.updateJobStatus(workspaceId, jobId, param); + return HttpResultResponse.success(); } } diff --git a/src/main/java/com/dji/sample/wayline/model/dto/WaylineJobKey.java b/src/main/java/com/dji/sample/wayline/model/dto/ConditionalWaylineJobKey.java similarity index 55% rename from src/main/java/com/dji/sample/wayline/model/dto/WaylineJobKey.java rename to src/main/java/com/dji/sample/wayline/model/dto/ConditionalWaylineJobKey.java index f19ed93..2dd1ca2 100644 --- a/src/main/java/com/dji/sample/wayline/model/dto/WaylineJobKey.java +++ b/src/main/java/com/dji/sample/wayline/model/dto/ConditionalWaylineJobKey.java @@ -3,13 +3,15 @@ package com.dji.sample.wayline.model.dto; import com.dji.sample.component.redis.RedisConst; import lombok.Data; +import java.util.Objects; + /** * @author sean * @version 1.4 * @date 2023/3/28 */ @Data -public class WaylineJobKey { +public class ConditionalWaylineJobKey { private String workspaceId; @@ -17,17 +19,18 @@ public class WaylineJobKey { private String jobId; - public WaylineJobKey(String workspaceId, String dockSn, String jobId) { + public ConditionalWaylineJobKey(String workspaceId, String dockSn, String jobId) { this.workspaceId = workspaceId; this.dockSn = dockSn; this.jobId = jobId; } - private WaylineJobKey(String[] keyArr) { - this(keyArr[0], keyArr[1], keyArr[2]); - } - public WaylineJobKey(String key) { - this(key.split(RedisConst.DELIMITER)); + public ConditionalWaylineJobKey(String key) { + if (Objects.isNull(key)) { + return; + } + String[] keyArr = key.split(RedisConst.DELIMITER); + new ConditionalWaylineJobKey(keyArr[0], keyArr[1], keyArr[2]); } public String getKey() { diff --git a/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressExt.java b/src/main/java/com/dji/sample/wayline/model/dto/FlighttaskProgressExt.java similarity index 87% rename from src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressExt.java rename to src/main/java/com/dji/sample/wayline/model/dto/FlighttaskProgressExt.java index bec5eaa..a04ea45 100644 --- a/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressExt.java +++ b/src/main/java/com/dji/sample/wayline/model/dto/FlighttaskProgressExt.java @@ -8,7 +8,7 @@ import lombok.Data; * @date 2022/6/9 */ @Data -public class WaylineTaskProgressExt { +public class FlighttaskProgressExt { private Integer currentWaypointIndex; diff --git a/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgress.java b/src/main/java/com/dji/sample/wayline/model/dto/FlighttaskProgressProgress.java similarity index 82% rename from src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgress.java rename to src/main/java/com/dji/sample/wayline/model/dto/FlighttaskProgressProgress.java index fa814e7..46e525d 100644 --- a/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgress.java +++ b/src/main/java/com/dji/sample/wayline/model/dto/FlighttaskProgressProgress.java @@ -8,7 +8,7 @@ import lombok.Data; * @date 2022/6/9 */ @Data -public class WaylineTaskProgress { +public class FlighttaskProgressProgress { private Integer currentStep; diff --git a/src/main/java/com/dji/sample/wayline/model/dto/WaylineFileUploadDTO.java b/src/main/java/com/dji/sample/wayline/model/dto/WaylineFileUploadDTO.java deleted file mode 100644 index 61f7d01..0000000 --- a/src/main/java/com/dji/sample/wayline/model/dto/WaylineFileUploadDTO.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.dji.sample.wayline.model.dto; - -import lombok.Data; - -/** - * @author sean - * @version 0.3 - * @date 2021/12/23 - */ -@Data -public class WaylineFileUploadDTO { - - private String objectKey; - - private String name; - - private WaylineFileDTO metadata; -} diff --git a/src/main/java/com/dji/sample/wayline/model/dto/WaylineJobDTO.java b/src/main/java/com/dji/sample/wayline/model/dto/WaylineJobDTO.java index 4f36608..83b6b0a 100644 --- a/src/main/java/com/dji/sample/wayline/model/dto/WaylineJobDTO.java +++ b/src/main/java/com/dji/sample/wayline/model/dto/WaylineJobDTO.java @@ -1,7 +1,8 @@ package com.dji.sample.wayline.model.dto; -import com.dji.sample.wayline.model.enums.WaylineTaskTypeEnum; -import com.dji.sample.wayline.model.enums.WaylineTemplateTypeEnum; +import com.dji.sdk.cloudapi.wayline.OutOfControlActionEnum; +import com.dji.sdk.cloudapi.wayline.TaskTypeEnum; +import com.dji.sdk.cloudapi.wayline.WaylineTypeEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -34,9 +35,9 @@ public class WaylineJobDTO { private String workspaceId; - private WaylineTemplateTypeEnum waylineType; + private WaylineTypeEnum waylineType; - private WaylineTaskTypeEnum taskType; + private TaskTypeEnum taskType; private LocalDateTime executeTime; @@ -56,7 +57,7 @@ public class WaylineJobDTO { private Integer rthAltitude; - private Integer outOfControlAction; + private OutOfControlActionEnum outOfControlAction; private Integer mediaCount; diff --git a/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskConditionDTO.java b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskConditionDTO.java index 6a1dc18..c924b07 100644 --- a/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskConditionDTO.java +++ b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskConditionDTO.java @@ -1,5 +1,7 @@ package com.dji.sample.wayline.model.dto; +import com.dji.sdk.cloudapi.wayline.ExecutableConditions; +import com.dji.sdk.cloudapi.wayline.ReadyConditions; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -16,7 +18,7 @@ import lombok.NoArgsConstructor; @AllArgsConstructor public class WaylineTaskConditionDTO { - private WaylineTaskReadyConditionDTO readyConditions; + private ReadyConditions readyConditions; - private WaylineTaskExecutableConditionDTO executableConditions; + private ExecutableConditions executableConditions; } diff --git a/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskCreateDTO.java b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskCreateDTO.java index 04cde89..3297a08 100644 --- a/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskCreateDTO.java +++ b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskCreateDTO.java @@ -1,7 +1,5 @@ package com.dji.sample.wayline.model.dto; -import com.dji.sample.wayline.model.enums.WaylineTaskTypeEnum; -import com.dji.sample.wayline.model.enums.WaylineTemplateTypeEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -20,9 +18,9 @@ public class WaylineTaskCreateDTO { private String flightId; - private WaylineTaskTypeEnum taskType; + private Integer taskType; - private WaylineTemplateTypeEnum waylineType; + private Integer waylineType; private Long executeTime; diff --git a/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressReceiver.java b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressReceiver.java index b86bc9b..75671c4 100644 --- a/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressReceiver.java +++ b/src/main/java/com/dji/sample/wayline/model/dto/WaylineTaskProgressReceiver.java @@ -10,9 +10,9 @@ import lombok.Data; @Data public class WaylineTaskProgressReceiver { - private WaylineTaskProgressExt ext; + private FlighttaskProgressExt ext; - private WaylineTaskProgress progress; + private FlighttaskProgressProgress progress; private String status; diff --git a/src/main/java/com/dji/sample/wayline/model/enums/WaylineErrorCodeEnum.java b/src/main/java/com/dji/sample/wayline/model/enums/WaylineErrorCodeEnum.java index 8643380..162c939 100644 --- a/src/main/java/com/dji/sample/wayline/model/enums/WaylineErrorCodeEnum.java +++ b/src/main/java/com/dji/sample/wayline/model/enums/WaylineErrorCodeEnum.java @@ -1,6 +1,6 @@ package com.dji.sample.wayline.model.enums; -import com.dji.sample.common.error.IErrorInfo; +import com.dji.sdk.common.IErrorInfo; import com.fasterxml.jackson.annotation.JsonCreator; import java.util.Arrays; @@ -63,12 +63,12 @@ public enum WaylineErrorCodeEnum implements IErrorInfo { } @Override - public String getErrorMsg() { + public String getMessage() { return msg; } @Override - public Integer getErrorCode() { + public Integer getCode() { return code; } diff --git a/src/main/java/com/dji/sample/wayline/model/enums/WaylineTaskTypeEnum.java b/src/main/java/com/dji/sample/wayline/model/enums/WaylineTaskTypeEnum.java deleted file mode 100644 index db81356..0000000 --- a/src/main/java/com/dji/sample/wayline/model/enums/WaylineTaskTypeEnum.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.dji.sample.wayline.model.enums; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -import java.util.Arrays; - -/** - * @author sean - * @version 1.3 - * @date 2022/9/26 - */ -public enum WaylineTaskTypeEnum { - - IMMEDIATE(0), - - TIMED(1), - - CONDITION(2); - - int val; - - WaylineTaskTypeEnum(int val) { - this.val = val; - } - - @JsonValue - public int getVal() { - return val; - } - - @JsonCreator - public static WaylineTaskTypeEnum find(Integer val) { - return Arrays.stream(values()).filter(taskTypeEnum -> taskTypeEnum.val == val).findAny().get(); - } -} diff --git a/src/main/java/com/dji/sample/wayline/model/param/CreateJobParam.java b/src/main/java/com/dji/sample/wayline/model/param/CreateJobParam.java index 558a9d2..f1cdedd 100644 --- a/src/main/java/com/dji/sample/wayline/model/param/CreateJobParam.java +++ b/src/main/java/com/dji/sample/wayline/model/param/CreateJobParam.java @@ -1,7 +1,8 @@ package com.dji.sample.wayline.model.param; -import com.dji.sample.wayline.model.enums.WaylineTaskTypeEnum; -import com.dji.sample.wayline.model.enums.WaylineTemplateTypeEnum; +import com.dji.sdk.cloudapi.wayline.OutOfControlActionEnum; +import com.dji.sdk.cloudapi.wayline.TaskTypeEnum; +import com.dji.sdk.cloudapi.wayline.WaylineTypeEnum; import lombok.Data; import org.hibernate.validator.constraints.Range; @@ -27,18 +28,17 @@ public class CreateJobParam { private String dockSn; @NotNull - private WaylineTemplateTypeEnum waylineType; + private WaylineTypeEnum waylineType; @NotNull - private WaylineTaskTypeEnum taskType; + private TaskTypeEnum taskType; @Range(min = 20, max = 500) @NotNull private Integer rthAltitude; @NotNull - @Range(max = 2) - private Integer outOfControlAction; + private OutOfControlActionEnum outOfControlAction; @Range(min = 50, max = 90) private Integer minBatteryCapacity; diff --git a/src/main/java/com/dji/sample/wayline/service/IFlightTaskService.java b/src/main/java/com/dji/sample/wayline/service/IFlightTaskService.java index 1b0f4e2..79c4857 100644 --- a/src/main/java/com/dji/sample/wayline/service/IFlightTaskService.java +++ b/src/main/java/com/dji/sample/wayline/service/IFlightTaskService.java @@ -1,5 +1,16 @@ package com.dji.sample.wayline.service; +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.wayline.model.dto.ConditionalWaylineJobKey; +import com.dji.sample.wayline.model.dto.WaylineJobDTO; +import com.dji.sample.wayline.model.param.CreateJobParam; +import com.dji.sample.wayline.model.param.UpdateJobParam; +import com.dji.sdk.common.HttpResultResponse; + +import java.sql.SQLException; +import java.util.Collection; +import java.util.List; + /** * @author sean * @version 1.1 @@ -8,4 +19,60 @@ package com.dji.sample.wayline.service; public interface IFlightTaskService { + /** + * Issue wayline mission to the dock. + * @param param + * @param customClaim user info + * @return + */ + HttpResultResponse publishFlightTask(CreateJobParam param, CustomClaim customClaim) throws SQLException; + + /** + * Issue wayline mission to the dock. + * @param waylineJob + * @return + * @throws SQLException + */ + HttpResultResponse publishOneFlightTask(WaylineJobDTO waylineJob) throws SQLException; + + /** + * Execute the task immediately. + * @param jobId + * @throws SQLException + * @return + */ + Boolean executeFlightTask(String workspaceId, String jobId); + + /** + * Cancel the task Base on job Ids. + * @param workspaceId + * @param jobIds + * @throws SQLException + */ + void cancelFlightTask(String workspaceId, Collection jobIds); + + /** + * Cancel the dock tasks that have been issued but have not yet been executed. + * @param workspaceId + * @param dockSn + * @param jobIds + */ + void publishCancelTask(String workspaceId, String dockSn, List jobIds); + + /** + * Set the media files for this job to upload immediately. + * @param workspaceId + * @param jobId + */ + void uploadMediaHighestPriority(String workspaceId, String jobId); + + /** + * Manually control the execution status of wayline job. + * @param workspaceId + * @param jobId + * @param param + */ + void updateJobStatus(String workspaceId, String jobId, UpdateJobParam param); + + void retryPrepareJob(ConditionalWaylineJobKey jobKey, WaylineJobDTO waylineJob); } diff --git a/src/main/java/com/dji/sample/wayline/service/IWaylineFileService.java b/src/main/java/com/dji/sample/wayline/service/IWaylineFileService.java index 4a722c8..03c74ef 100644 --- a/src/main/java/com/dji/sample/wayline/service/IWaylineFileService.java +++ b/src/main/java/com/dji/sample/wayline/service/IWaylineFileService.java @@ -1,8 +1,9 @@ package com.dji.sample.wayline.service; -import com.dji.sample.common.model.PaginationData; import com.dji.sample.wayline.model.dto.WaylineFileDTO; -import com.dji.sample.wayline.model.param.WaylineQueryParam; +import com.dji.sdk.cloudapi.wayline.GetWaylineListRequest; +import com.dji.sdk.cloudapi.wayline.GetWaylineListResponse; +import com.dji.sdk.common.PaginationData; import org.springframework.web.multipart.MultipartFile; import java.net.URL; @@ -23,7 +24,7 @@ public interface IWaylineFileService { * @param param * @return */ - PaginationData getWaylinesByParam(String workspaceId, WaylineQueryParam param); + PaginationData getWaylinesByParam(String workspaceId, GetWaylineListRequest param); /** * Query the information of this wayline file according to the wayline file id. @@ -31,7 +32,7 @@ public interface IWaylineFileService { * @param waylineId * @return */ - Optional getWaylineByWaylineId(String workspaceId, String waylineId); + Optional getWaylineByWaylineId(String workspaceId, String waylineId); /** * Get the download address of the file object. diff --git a/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java b/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java index 608c93f..1b5c84f 100644 --- a/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java +++ b/src/main/java/com/dji/sample/wayline/service/IWaylineJobService.java @@ -1,16 +1,10 @@ package com.dji.sample.wayline.service; -import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.CommonTopicReceiver; import com.dji.sample.wayline.model.dto.WaylineJobDTO; import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum; import com.dji.sample.wayline.model.param.CreateJobParam; -import com.dji.sample.wayline.model.param.UpdateJobParam; -import org.springframework.messaging.MessageHeaders; +import com.dji.sdk.common.PaginationData; -import java.sql.SQLException; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -41,46 +35,6 @@ public interface IWaylineJobService { */ Optional createWaylineJobByParent(String workspaceId, String parentId); - /** - * Issue wayline mission to the dock. - * @param param - * @param customClaim user info - * @return - */ - ResponseResult publishFlightTask(CreateJobParam param, CustomClaim customClaim) throws SQLException; - - /** - * Issue wayline mission to the dock. - * @param waylineJob - * @return - * @throws SQLException - */ - ResponseResult publishOneFlightTask(WaylineJobDTO waylineJob) throws SQLException; - - /** - * Execute the task immediately. - * @param jobId - * @throws SQLException - * @return - */ - Boolean executeFlightTask(String workspaceId, String jobId); - - /** - * Cancel the task Base on job Ids. - * @param workspaceId - * @param jobIds - * @throws SQLException - */ - void cancelFlightTask(String workspaceId, Collection jobIds); - - /** - * Cancel the dock tasks that have been issued but have not yet been executed. - * @param workspaceId - * @param dockSn - * @param jobIds - */ - void publishCancelTask(String workspaceId, String dockSn, List jobIds); - /** * Query wayline jobs based on conditions. * @param workspaceId @@ -114,28 +68,6 @@ public interface IWaylineJobService { */ PaginationData getJobsByWorkspaceId(String workspaceId, long page, long pageSize); - /** - * Process to get interface data of flight mission resources. - * @param receiver - * @param headers - */ - void flightTaskResourceGet(CommonTopicReceiver receiver, MessageHeaders headers); - - /** - * Set the media files for this job to upload immediately. - * @param workspaceId - * @param jobId - */ - void uploadMediaHighestPriority(String workspaceId, String jobId); - - /** - * Manually control the execution status of wayline job. - * @param workspaceId - * @param jobId - * @param param - */ - void updateJobStatus(String workspaceId, String jobId, UpdateJobParam param); - /** * Query the wayline execution status of the dock. * @param dockSn diff --git a/src/main/java/com/dji/sample/wayline/service/IWaylineRedisService.java b/src/main/java/com/dji/sample/wayline/service/IWaylineRedisService.java index 0f8408c..7230c50 100644 --- a/src/main/java/com/dji/sample/wayline/service/IWaylineRedisService.java +++ b/src/main/java/com/dji/sample/wayline/service/IWaylineRedisService.java @@ -1,9 +1,9 @@ package com.dji.sample.wayline.service; import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.wayline.model.dto.ConditionalWaylineJobKey; import com.dji.sample.wayline.model.dto.WaylineJobDTO; -import com.dji.sample.wayline.model.dto.WaylineJobKey; -import com.dji.sample.wayline.model.dto.WaylineTaskProgressReceiver; +import com.dji.sdk.cloudapi.wayline.FlighttaskProgress; import java.util.Optional; @@ -19,14 +19,14 @@ public interface IWaylineRedisService { * @param dockSn * @param data */ - void setRunningWaylineJob(String dockSn, EventsReceiver data); + void setRunningWaylineJob(String dockSn, EventsReceiver data); /** * Query the status of wayline job performed by the dock in redis. * @param dockSn * @return */ - Optional> getRunningWaylineJob(String dockSn); + Optional> getRunningWaylineJob(String dockSn); /** * Delete the wayline job status of the dock operation in redis. @@ -70,13 +70,6 @@ public interface IWaylineRedisService { */ String getBlockedWaylineJobId(String dockSn); - /** - * Delete the wayline job id blocked by the dock in redis. - * @param dockSn - * @return - */ - Boolean delBlockedWaylineJobId(String dockSn); - /** * Save the conditional wayline job by the dock to redis. * @param waylineJob @@ -97,30 +90,11 @@ public interface IWaylineRedisService { */ Boolean delConditionalWaylineJob(String jobId); - /** - * Add the wayline job that needs to be issued. - * @param waylineJob - * @return - */ - Boolean addPreparedWaylineJob(WaylineJobDTO waylineJob); + Boolean addPrepareConditionalWaylineJob(WaylineJobDTO waylineJob); - /** - * Get the latest wayline job that needs to be issued. - * @return - */ - Optional getNearestPreparedWaylineJob(); + Optional getNearestConditionalWaylineJob(); - /** - * Get the time when the wayline job is issued. - * @param jobKey - * @return - */ - Double getPreparedWaylineJobTime(WaylineJobKey jobKey); + Double getConditionalWaylineJobTime(ConditionalWaylineJobKey jobKey); - /** - * Delete the wayline job that needs to be issued in redis. - * @param jobKey - * @return - */ - Boolean removePreparedWaylineJob(WaylineJobKey jobKey); + Boolean removePrepareConditionalWaylineJob(ConditionalWaylineJobKey jobKey); } diff --git a/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java b/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java index 893b0bc..938cd80 100644 --- a/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java +++ b/src/main/java/com/dji/sample/wayline/service/impl/FlightTaskServiceImpl.java @@ -1,40 +1,54 @@ package com.dji.sample.wayline.service.impl; import com.dji.sample.common.error.CommonErrorEnum; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.IMessageSenderService; +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.component.mqtt.model.EventsReceiver; 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.component.websocket.service.IWebSocketMessageService; import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.service.IDeviceRedisService; import com.dji.sample.media.model.MediaFileCountDTO; +import com.dji.sample.media.service.IMediaRedisService; +import com.dji.sample.wayline.model.dto.ConditionalWaylineJobKey; import com.dji.sample.wayline.model.dto.WaylineJobDTO; -import com.dji.sample.wayline.model.dto.WaylineJobKey; -import com.dji.sample.wayline.model.dto.WaylineTaskProgressReceiver; +import com.dji.sample.wayline.model.dto.WaylineTaskConditionDTO; +import com.dji.sample.wayline.model.enums.WaylineErrorCodeEnum; import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum; -import com.dji.sample.wayline.model.enums.WaylineTaskTypeEnum; +import com.dji.sample.wayline.model.param.CreateJobParam; +import com.dji.sample.wayline.model.param.UpdateJobParam; import com.dji.sample.wayline.service.IFlightTaskService; +import com.dji.sample.wayline.service.IWaylineFileService; import com.dji.sample.wayline.service.IWaylineJobService; import com.dji.sample.wayline.service.IWaylineRedisService; -import com.fasterxml.jackson.core.type.TypeReference; +import com.dji.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum; +import com.dji.sdk.cloudapi.media.UploadFlighttaskMediaPrioritize; +import com.dji.sdk.cloudapi.media.api.AbstractMediaService; +import com.dji.sdk.cloudapi.wayline.*; +import com.dji.sdk.cloudapi.wayline.api.AbstractWaylineService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpStatus; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.messaging.MessageHeaders; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; -import java.time.LocalDateTime; -import java.time.ZoneId; +import java.net.URL; +import java.sql.SQLException; +import java.time.*; import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * @author sean @@ -43,16 +57,13 @@ import java.util.concurrent.TimeUnit; */ @Service @Slf4j -public class FlightTaskServiceImpl implements IFlightTaskService { - - @Autowired - private IMessageSenderService messageSender; +public class FlightTaskServiceImpl extends AbstractWaylineService implements IFlightTaskService { @Autowired private ObjectMapper mapper; @Autowired - private ISendMessageService websocketMessageService; + private IWebSocketMessageService websocketMessageService; @Autowired private IWaylineJobService waylineJobService; @@ -63,205 +74,427 @@ public class FlightTaskServiceImpl implements IFlightTaskService { @Autowired private IWaylineRedisService waylineRedisService; - /** - * Handle the progress messages of the flight tasks reported by the dock. - * @param receiver - * @param headers - */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHT_TASK_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) - public CommonTopicReceiver handleProgress(CommonTopicReceiver receiver, MessageHeaders headers) { - EventsReceiver eventsReceiver = mapper.convertValue(receiver.getData(), - new TypeReference>(){}); - eventsReceiver.setBid(receiver.getBid()); - eventsReceiver.setSn(receiver.getGateway()); + @Autowired + private IMediaRedisService mediaRedisService; - WaylineTaskProgressReceiver output = eventsReceiver.getOutput(); + @Autowired + private IWaylineFileService waylineFileService; - log.info("Task progress: {}", output.getProgress().toString()); + @Autowired + private SDKWaylineService abstractWaylineService; + + @Autowired + @Qualifier("mediaServiceImpl") + private AbstractMediaService abstractMediaService; - if (eventsReceiver.getResult() != ResponseResult.CODE_SUCCESS) { - log.error("Task progress ===> Error code: " + eventsReceiver.getResult()); + @Scheduled(initialDelay = 10, fixedRate = 5, timeUnit = TimeUnit.SECONDS) + public void checkScheduledJob() { + Object jobIdValue = RedisOpsUtils.zGetMin(RedisConst.WAYLINE_JOB_TIMED_EXECUTE); + if (Objects.isNull(jobIdValue)) { + return; + } + log.info("Check the timed tasks of the wayline. {}", jobIdValue); + // format: {workspace_id}:{dock_sn}:{job_id} + String[] jobArr = String.valueOf(jobIdValue).split(RedisConst.DELIMITER); + double time = RedisOpsUtils.zScore(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue); + long now = System.currentTimeMillis(); + int offset = 30_000; + + // Expired tasks are deleted directly. + if (time < now - offset) { + RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue); + waylineJobService.updateJob(WaylineJobDTO.builder() + .jobId(jobArr[2]) + .status(WaylineJobStatusEnum.FAILED.getVal()) + .executeTime(LocalDateTime.now()) + .completedTime(LocalDateTime.now()) + .code(HttpStatus.SC_REQUEST_TIMEOUT).build()); + return; } - EventsResultStatusEnum statusEnum = EventsResultStatusEnum.find(output.getStatus()); - waylineRedisService.setRunningWaylineJob(receiver.getGateway(), eventsReceiver); + if (now <= time && time <= now + offset) { + try { + this.executeFlightTask(jobArr[0], jobArr[2]); + } catch (Exception e) { + log.info("The scheduled task delivery failed."); + waylineJobService.updateJob(WaylineJobDTO.builder() + .jobId(jobArr[2]) + .status(WaylineJobStatusEnum.FAILED.getVal()) + .executeTime(LocalDateTime.now()) + .completedTime(LocalDateTime.now()) + .code(HttpStatus.SC_INTERNAL_SERVER_ERROR).build()); + } finally { + RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue); + } + } + } - Optional deviceOpt = deviceRedisService.getDeviceOnline(receiver.getGateway()); - if (deviceOpt.isEmpty()) { - return null; + @Scheduled(initialDelay = 10, fixedRate = 5, timeUnit = TimeUnit.SECONDS) + public void prepareConditionJob() { + Optional jobKeyOpt = waylineRedisService.getNearestConditionalWaylineJob(); + if (jobKeyOpt.isEmpty()) { + return; } + ConditionalWaylineJobKey jobKey = jobKeyOpt.get(); + log.info("Check the conditional tasks of the wayline. {}", jobKey.toString()); + // format: {workspace_id}:{dock_sn}:{job_id} + double time = waylineRedisService.getConditionalWaylineJobTime(jobKey); + long now = System.currentTimeMillis(); + // prepare the task one day in advance. + int offset = 86_400_000; - if (statusEnum.getEnd()) { - handleEndStatus(receiver, statusEnum, output.getExt().getMediaCount(), eventsReceiver.getResult(), deviceOpt.get()); + if (now + offset < time) { + return; } - websocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), - BizCodeEnum.FLIGHT_TASK_PROGRESS.getCode(), eventsReceiver); + WaylineJobDTO job = WaylineJobDTO.builder() + .jobId(jobKey.getJobId()) + .status(WaylineJobStatusEnum.FAILED.getVal()) + .executeTime(LocalDateTime.now()) + .completedTime(LocalDateTime.now()) + .code(HttpStatus.SC_INTERNAL_SERVER_ERROR).build(); + try { + Optional waylineJobOpt = waylineRedisService.getConditionalWaylineJob(jobKey.getJobId()); + if (waylineJobOpt.isEmpty()) { + job.setCode(CommonErrorEnum.REDIS_DATA_NOT_FOUND.getCode()); + waylineJobService.updateJob(job); + waylineRedisService.removePrepareConditionalWaylineJob(jobKey); + return; + } + WaylineJobDTO waylineJob = waylineJobOpt.get(); - return receiver; - } + HttpResultResponse result = this.publishOneFlightTask(waylineJob); + waylineRedisService.removePrepareConditionalWaylineJob(jobKey); - private void handleEndStatus(CommonTopicReceiver receiver, EventsResultStatusEnum statusEnum, int mediaCount, int code, DeviceDTO dock) { + if (HttpResultResponse.CODE_SUCCESS == result.getCode()) { + return; + } - WaylineJobDTO job = WaylineJobDTO.builder() - .jobId(receiver.getBid()) - .status(WaylineJobStatusEnum.SUCCESS.getVal()) - .completedTime(LocalDateTime.now()) - .mediaCount(mediaCount) - .build(); + // If the end time is exceeded, no more retries will be made. + waylineRedisService.delConditionalWaylineJob(jobKey.getJobId()); + if (waylineJob.getEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - RedisConst.WAYLINE_JOB_BLOCK_TIME * 1000 < now) { + return; + } - // record the update of the media count. - if (Objects.nonNull(job.getMediaCount()) && job.getMediaCount() != 0) { - RedisOpsUtils.hashSet(RedisConst.MEDIA_FILE_PREFIX + receiver.getGateway(), job.getJobId(), - MediaFileCountDTO.builder().jobId(receiver.getBid()).mediaCount(job.getMediaCount()).uploadedCount(0).build()); - } + // Retry if the end time has not been exceeded. + this.retryPrepareJob(jobKey, waylineJob); - if (EventsResultStatusEnum.OK != statusEnum) { - job.setCode(code); - job.setStatus(WaylineJobStatusEnum.FAILED.getVal()); + } catch (Exception e) { + log.info("Failed to prepare the conditional task."); + waylineJobService.updateJob(job); } - waylineRedisService.getConditionalWaylineJob(receiver.getBid()).ifPresent(waylineJob -> - retryPrepareConditionJob(new WaylineJobKey(dock.getWorkspaceId(), dock.getDeviceSn(), receiver.getBid()), waylineJob)); - waylineJobService.updateJob(job); - waylineRedisService.delRunningWaylineJob(receiver.getGateway()); - waylineRedisService.delPausedWaylineJob(receiver.getBid()); - waylineRedisService.delBlockedWaylineJobId(receiver.getGateway()); - } /** - * Notifications will be received through this interface when tasks are ready on the device. - * @param receiver - * @param headers + * For immediate tasks, the server time shall prevail. + * @param param */ - @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHT_TASK_READY, outputChannel = ChannelName.OUTBOUND_EVENTS) - public CommonTopicReceiver handleTaskNotifications(CommonTopicReceiver receiver, MessageHeaders headers) { - String dockSn = receiver.getGateway(); - Set flightIds = mapper.convertValue(receiver.getData(), - new TypeReference>>(){}).get(MapKeyConst.FLIGHT_IDS); - - log.info("ready task list:{}", Arrays.toString(flightIds.toArray())); - // Check conditional task blocking status. - String blockedId = waylineRedisService.getBlockedWaylineJobId(dockSn); - if (StringUtils.hasText(blockedId)) { - log.info("The dock is in a state of wayline congestion, and the task will not be executed."); - return null; + private void fillImmediateTime(CreateJobParam param) { + if (TaskTypeEnum.IMMEDIATE != param.getTaskType()) { + return; } + long now = System.currentTimeMillis() / 1000; + param.setTaskDays(List.of(now)); + param.setTaskPeriods(List.of(List.of(now))); + } - Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); - if (deviceOpt.isEmpty()) { - log.info("The dock is offline."); - return null; + + private void addConditions(WaylineJobDTO waylineJob, CreateJobParam param, Long beginTime, Long endTime) { + if (TaskTypeEnum.CONDITIONAL != param.getTaskType()) { + return; } - DeviceDTO device = deviceOpt.get(); - Optional jobOpt = waylineJobService.getJobsByConditions(device.getWorkspaceId(), flightIds, WaylineJobStatusEnum.PENDING) - .stream().filter(job -> flightIds.contains(job.getJobId())) - .sorted(Comparator.comparingInt(a -> a.getTaskType().getVal())) - .min(Comparator.comparing(WaylineJobDTO::getBeginTime)); - if (jobOpt.isEmpty()) { - return receiver; + + waylineJob.setConditions( + WaylineTaskConditionDTO.builder() + .executableConditions(Objects.nonNull(param.getMinStorageCapacity()) ? + new ExecutableConditions().setStorageCapacity(param.getMinStorageCapacity()) : null) + .readyConditions(new ReadyConditions() + .setBatteryCapacity(param.getMinBatteryCapacity()) + .setBeginTime(beginTime) + .setEndTime(endTime)) + .build()); + + waylineRedisService.setConditionalWaylineJob(waylineJob); + // key: wayline_job_condition, value: {workspace_id}:{dock_sn}:{job_id} + boolean isAdd = waylineRedisService.addPrepareConditionalWaylineJob(waylineJob); + if (!isAdd) { + throw new RuntimeException("Failed to create conditional job."); } - executeReadyTask(jobOpt.get()); + } - return receiver; + @Override + public HttpResultResponse publishFlightTask(CreateJobParam param, CustomClaim customClaim) throws SQLException { + fillImmediateTime(param); + + for (Long taskDay : param.getTaskDays()) { + LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(taskDay), ZoneId.systemDefault()); + for (List taskPeriod : param.getTaskPeriods()) { + long beginTime = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(taskPeriod.get(0)), ZoneId.systemDefault())) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + long endTime = taskPeriod.size() > 1 ? + LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(taskPeriod.get(1)), ZoneId.systemDefault())) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : beginTime; + if (TaskTypeEnum.IMMEDIATE != param.getTaskType() && endTime < System.currentTimeMillis()) { + continue; + } + + Optional waylineJobOpt = waylineJobService.createWaylineJob(param, customClaim.getWorkspaceId(), customClaim.getUsername(), beginTime, endTime); + if (waylineJobOpt.isEmpty()) { + throw new SQLException("Failed to create wayline job."); + } + WaylineJobDTO waylineJob = waylineJobOpt.get(); + // If it is a conditional task type, add conditions to the job parameters. + addConditions(waylineJob, param, beginTime, endTime); + + HttpResultResponse response = this.publishOneFlightTask(waylineJob); + if (HttpResultResponse.CODE_SUCCESS != response.getCode()) { + return response; + } + } + } + return HttpResultResponse.success(); } - private void executeReadyTask(WaylineJobDTO waylineJob) { - try { - boolean isExecute = waylineJobService.executeFlightTask(waylineJob.getWorkspaceId(), waylineJob.getJobId()); - if (isExecute || WaylineTaskTypeEnum.CONDITION != waylineJob.getTaskType()) { - return; + public HttpResultResponse publishOneFlightTask(WaylineJobDTO waylineJob) throws SQLException { + + boolean isOnline = deviceRedisService.checkDeviceOnline(waylineJob.getDockSn()); + if (!isOnline) { + throw new RuntimeException("Dock is offline."); + } + + boolean isSuccess = this.prepareFlightTask(waylineJob); + if (!isSuccess) { + return HttpResultResponse.error("Failed to prepare job."); + } + + // Issue an immediate task execution command. + if (TaskTypeEnum.IMMEDIATE == waylineJob.getTaskType()) { + if (!executeFlightTask(waylineJob.getWorkspaceId(), waylineJob.getJobId())) { + return HttpResultResponse.error("Failed to execute job."); } - Optional waylineJobOpt = waylineRedisService.getConditionalWaylineJob(waylineJob.getJobId()); - if (waylineJobOpt.isEmpty()) { - log.info("The conditional job has expired and will no longer be executed."); - return; + } + + if (TaskTypeEnum.TIMED == waylineJob.getTaskType()) { + // key: wayline_job_timed, value: {workspace_id}:{dock_sn}:{job_id} + boolean isAdd = RedisOpsUtils.zAdd(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, + waylineJob.getWorkspaceId() + RedisConst.DELIMITER + waylineJob.getDockSn() + RedisConst.DELIMITER + waylineJob.getJobId(), + waylineJob.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + if (!isAdd) { + return HttpResultResponse.error("Failed to create scheduled job."); } - waylineJob = waylineJobOpt.get(); - this.retryPrepareConditionJob(new WaylineJobKey(waylineJob.getWorkspaceId(), waylineJob.getDockSn(), waylineJob.getJobId()), waylineJob); - } catch (Exception e) { - log.error("Failed to execute task. ID: {}, Name:{}", waylineJob.getJobId(), waylineJob.getJobName()); - this.retryPrepareConditionJob(new WaylineJobKey(waylineJob.getWorkspaceId(), waylineJob.getDockSn(), waylineJob.getJobId()), waylineJob); - e.printStackTrace(); } + + return HttpResultResponse.success(); } - @Scheduled(initialDelay = 10, fixedRate = 5, timeUnit = TimeUnit.SECONDS) - private void prepareWaylineJob() { - Optional jobKeyOpt = waylineRedisService.getNearestPreparedWaylineJob(); - if (jobKeyOpt.isEmpty()) { - return; + private Boolean prepareFlightTask(WaylineJobDTO waylineJob) throws SQLException { + // get wayline file + Optional waylineFile = waylineFileService.getWaylineByWaylineId(waylineJob.getWorkspaceId(), waylineJob.getFileId()); + if (waylineFile.isEmpty()) { + throw new SQLException("Wayline file doesn't exist."); } - // format: {workspace_id}:{dock_sn}:{job_id} - WaylineJobKey jobKey = jobKeyOpt.get(); - log.info("Check the prepared tasks of the wayline. {}", jobKey.toString()); - WaylineJobDTO job = WaylineJobDTO.builder() - .jobId(jobKey.getJobId()) - .status(WaylineJobStatusEnum.FAILED.getVal()) - .executeTime(LocalDateTime.now()) - .completedTime(LocalDateTime.now()) - .code(HttpStatus.SC_INTERNAL_SERVER_ERROR).build(); - Optional waylineJobOpt = getPreparedJob(jobKey, job); - if (waylineJobOpt.isEmpty()) { - return; + // get file url + URL url = waylineFileService.getObjectUrl(waylineJob.getWorkspaceId(), waylineFile.get().getId()); + + FlighttaskPrepareRequest flightTask = new FlighttaskPrepareRequest() + .setFlightId(waylineJob.getJobId()) + .setExecuteTime(waylineJob.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()) + .setTaskType(waylineJob.getTaskType()) + .setWaylineType(waylineJob.getWaylineType()) + .setRthAltitude(waylineJob.getRthAltitude()) + .setOutOfControlAction(waylineJob.getOutOfControlAction()) + .setExitWaylineWhenRcLost(ExitWaylineWhenRcLostEnum.EXECUTE_RC_LOST_ACTION) + .setFile(new FlighttaskFile() + .setUrl(url.toString()) + .setFingerprint(waylineFile.get().getSign())); + + if (TaskTypeEnum.CONDITIONAL == waylineJob.getTaskType()) { + if (Objects.isNull(waylineJob.getConditions())) { + throw new IllegalArgumentException(); + } + flightTask.setReadyConditions(waylineJob.getConditions().getReadyConditions()); + flightTask.setExecutableConditions(waylineJob.getConditions().getExecutableConditions()); } - WaylineJobDTO waylineJob = waylineJobOpt.get(); - try { - ResponseResult result = waylineJobService.publishOneFlightTask(waylineJob); - if (ResponseResult.CODE_SUCCESS == result.getCode()) { - return; + TopicServicesResponse serviceReply = abstractWaylineService.flighttaskPrepare( + SDKManager.getDeviceSDK(waylineJob.getDockSn()), flightTask); + if (!serviceReply.getData().getResult().isSuccess()) { + log.info("Prepare task ====> Error code: {}", serviceReply.getData().getResult()); + waylineJobService.updateJob(WaylineJobDTO.builder() + .workspaceId(waylineJob.getWorkspaceId()) + .jobId(waylineJob.getJobId()) + .executeTime(LocalDateTime.now()) + .status(WaylineJobStatusEnum.FAILED.getVal()) + .completedTime(LocalDateTime.now()) + .code(serviceReply.getData().getResult().getCode()).build()); + return false; + } + return true; + } + + + @Override + public Boolean executeFlightTask(String workspaceId, String jobId) { + // get job + Optional waylineJob = waylineJobService.getJobByJobId(workspaceId, jobId); + if (waylineJob.isEmpty()) { + throw new IllegalArgumentException("Job doesn't exist."); + } + + boolean isOnline = deviceRedisService.checkDeviceOnline(waylineJob.get().getDockSn()); + if (!isOnline) { + throw new RuntimeException("Dock is offline."); + } + + WaylineJobDTO job = waylineJob.get(); + + TopicServicesResponse serviceReply = abstractWaylineService.flighttaskExecute( + SDKManager.getDeviceSDK(job.getDockSn()), new FlighttaskExecuteRequest().setFlightId(jobId)); + if (!serviceReply.getData().getResult().isSuccess()) { + log.info("Execute job ====> Error: {}", serviceReply.getData().getResult()); + waylineJobService.updateJob(WaylineJobDTO.builder() + .jobId(jobId) + .executeTime(LocalDateTime.now()) + .status(WaylineJobStatusEnum.FAILED.getVal()) + .completedTime(LocalDateTime.now()) + .code(serviceReply.getData().getResult().getCode()).build()); + // The conditional task fails and enters the blocking status. + if (TaskTypeEnum.CONDITIONAL == job.getTaskType() + && WaylineErrorCodeEnum.find(serviceReply.getData().getResult().getCode()).isBlock()) { + waylineRedisService.setBlockedWaylineJob(job.getDockSn(), jobId); } - log.info("Failed to prepare the task. {}", result.getMessage()); - job.setCode(result.getCode()); - waylineJobService.updateJob(job); - // Retry if the end time has not been exceeded. - this.retryPrepareConditionJob(jobKey, waylineJob); - } catch (Exception e) { - log.info("Failed to prepare the task. {}", e.getLocalizedMessage()); - waylineJobService.updateJob(job); - this.retryPrepareConditionJob(jobKey, waylineJob); + return false; } + + waylineJobService.updateJob(WaylineJobDTO.builder() + .jobId(jobId) + .executeTime(LocalDateTime.now()) + .status(WaylineJobStatusEnum.IN_PROGRESS.getVal()) + .build()); + waylineRedisService.setRunningWaylineJob(job.getDockSn(), EventsReceiver.builder().bid(jobId).sn(job.getDockSn()).build()); + return true; } - private boolean checkTime(long time) { - // prepare the task one day in advance. - int offset = 86_400_000; - return System.currentTimeMillis() + offset >= time; + @Override + public void cancelFlightTask(String workspaceId, Collection jobIds) { + List waylineJobs = waylineJobService.getJobsByConditions(workspaceId, jobIds, WaylineJobStatusEnum.PENDING); + + Set waylineJobIds = waylineJobs.stream().map(WaylineJobDTO::getJobId).collect(Collectors.toSet()); + // Check if the task status is correct. + boolean isErr = !jobIds.removeAll(waylineJobIds) || !jobIds.isEmpty() ; + if (isErr) { + throw new IllegalArgumentException("These tasks have an incorrect status and cannot be canceled. " + Arrays.toString(jobIds.toArray())); + } + + // Group job id by dock sn. + Map> dockJobs = waylineJobs.stream() + .collect(Collectors.groupingBy(WaylineJobDTO::getDockSn, + Collectors.mapping(WaylineJobDTO::getJobId, Collectors.toList()))); + dockJobs.forEach((dockSn, idList) -> this.publishCancelTask(workspaceId, dockSn, idList)); + + } + + public void publishCancelTask(String workspaceId, String dockSn, List jobIds) { + boolean isOnline = deviceRedisService.checkDeviceOnline(dockSn); + if (!isOnline) { + throw new RuntimeException("Dock is offline."); + } + + TopicServicesResponse serviceReply = abstractWaylineService.flighttaskUndo(SDKManager.getDeviceSDK(dockSn), + new FlighttaskUndoRequest().setFlightIds(jobIds)); + if (!serviceReply.getData().getResult().isSuccess()) { + log.info("Cancel job ====> Error: {}", serviceReply.getData().getResult()); + throw new RuntimeException("Failed to cancel the wayline job of " + dockSn); + } + + for (String jobId : jobIds) { + waylineJobService.updateJob(WaylineJobDTO.builder() + .workspaceId(workspaceId) + .jobId(jobId) + .status(WaylineJobStatusEnum.CANCEL.getVal()) + .completedTime(LocalDateTime.now()) + .build()); + RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, workspaceId + RedisConst.DELIMITER + dockSn + RedisConst.DELIMITER + jobId); + } + } - private Optional getPreparedJob(WaylineJobKey jobKey, WaylineJobDTO job) { - long time = waylineRedisService.getPreparedWaylineJobTime(jobKey).longValue(); - if (!checkTime(time)) { - return Optional.empty(); + @Override + public void uploadMediaHighestPriority(String workspaceId, String jobId) { + Optional jobOpt = waylineJobService.getJobByJobId(workspaceId, jobId); + if (jobOpt.isEmpty()) { + throw new RuntimeException(CommonErrorEnum.ILLEGAL_ARGUMENT.getMessage()); + } + + String dockSn = jobOpt.get().getDockSn(); + String key = RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + dockSn; + if (RedisOpsUtils.checkExist(key) && jobId.equals(((MediaFileCountDTO) RedisOpsUtils.get(key)).getJobId())) { + return; } - Optional waylineJobOpt = waylineRedisService.getConditionalWaylineJob(jobKey.getJobId()); - // Determine whether the conditional task or the scheduled task has expired. + TopicServicesResponse reply = abstractMediaService.uploadFlighttaskMediaPrioritize( + SDKManager.getDeviceSDK(dockSn), new UploadFlighttaskMediaPrioritize().setFlightId(jobId)); + if (!reply.getData().getResult().isSuccess()) { + throw new RuntimeException("Failed to set media job upload priority. Error: " + reply.getData().getResult()); + } + } + + @Override + public void updateJobStatus(String workspaceId, String jobId, UpdateJobParam param) { + Optional waylineJobOpt = waylineJobService.getJobByJobId(workspaceId, jobId); if (waylineJobOpt.isEmpty()) { - waylineJobOpt = waylineJobService.getJobByJobId(jobKey.getWorkspaceId(), jobKey.getJobId()); - if (waylineJobOpt.isEmpty() || waylineJobOpt.get().getEndTime().isBefore(LocalDateTime.now())) { - job.setCode(CommonErrorEnum.REDIS_DATA_NOT_FOUND.getErrorCode()); - waylineJobService.updateJob(job); - return Optional.empty(); - } + throw new RuntimeException("The job does not exist."); } - waylineRedisService.removePreparedWaylineJob(jobKey); - return waylineJobOpt; + WaylineJobDTO waylineJob = waylineJobOpt.get(); + WaylineJobStatusEnum statusEnum = waylineJobService.getWaylineState(waylineJob.getDockSn()); + if (statusEnum.getEnd() || WaylineJobStatusEnum.PENDING == statusEnum) { + throw new RuntimeException("The wayline job status does not match, and the operation cannot be performed."); + } + + switch (param.getStatus()) { + case PAUSE: + pauseJob(workspaceId, waylineJob.getDockSn(), jobId, statusEnum); + break; + case RESUME: + resumeJob(workspaceId, waylineJob.getDockSn(), jobId, statusEnum); + break; + } + } - private void retryPrepareConditionJob(WaylineJobKey jobKey, WaylineJobDTO waylineJob) { - if (WaylineTaskTypeEnum.CONDITION != waylineJob.getTaskType()) { + private void pauseJob(String workspaceId, String dockSn, String jobId, WaylineJobStatusEnum statusEnum) { + if (WaylineJobStatusEnum.PAUSED == statusEnum && jobId.equals(waylineRedisService.getPausedWaylineJobId(dockSn))) { + waylineRedisService.setPausedWaylineJob(dockSn, jobId); return; } - // If the end time is exceeded, no more retries will be made. - waylineRedisService.delConditionalWaylineJob(jobKey.getJobId()); - if (waylineJob.getEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() < System.currentTimeMillis()) { + + TopicServicesResponse reply = abstractWaylineService.flighttaskPause(SDKManager.getDeviceSDK(dockSn)); + if (!reply.getData().getResult().isSuccess()) { + throw new RuntimeException("Failed to pause wayline job. Error: " + reply.getData().getResult()); + } + waylineRedisService.delRunningWaylineJob(dockSn); + waylineRedisService.setPausedWaylineJob(dockSn, jobId); + } + + private void resumeJob(String workspaceId, String dockSn, String jobId, WaylineJobStatusEnum statusEnum) { + Optional> runningDataOpt = waylineRedisService.getRunningWaylineJob(dockSn); + if (WaylineJobStatusEnum.IN_PROGRESS == statusEnum && jobId.equals(runningDataOpt.map(EventsReceiver::getSn).get())) { + waylineRedisService.setRunningWaylineJob(dockSn, runningDataOpt.get()); return; } + TopicServicesResponse reply = abstractWaylineService.flighttaskRecovery(SDKManager.getDeviceSDK(dockSn)); + if (!reply.getData().getResult().isSuccess()) { + throw new RuntimeException("Failed to resume wayline job. Error: " + reply.getData().getResult()); + } + runningDataOpt.ifPresent(runningData -> waylineRedisService.setRunningWaylineJob(dockSn, runningData)); + waylineRedisService.delPausedWaylineJob(dockSn); + } + + @Override + public void retryPrepareJob(ConditionalWaylineJobKey jobKey, WaylineJobDTO waylineJob) { Optional childJobOpt = waylineJobService.createWaylineJobByParent(jobKey.getWorkspaceId(), jobKey.getJobId()); if (childJobOpt.isEmpty()) { log.error("Failed to create wayline job."); @@ -270,7 +503,7 @@ public class FlightTaskServiceImpl implements IFlightTaskService { WaylineJobDTO newJob = childJobOpt.get(); newJob.setBeginTime(LocalDateTime.now().plusSeconds(RedisConst.WAYLINE_JOB_BLOCK_TIME)); - boolean isAdd = waylineRedisService.addPreparedWaylineJob(newJob); + boolean isAdd = waylineRedisService.addPrepareConditionalWaylineJob(newJob); if (!isAdd) { log.error("Failed to create wayline job. {}", newJob.getJobId()); return; @@ -279,4 +512,45 @@ public class FlightTaskServiceImpl implements IFlightTaskService { waylineJob.setJobId(newJob.getJobId()); waylineRedisService.setConditionalWaylineJob(waylineJob); } + + + @Override + public TopicEventsResponse flighttaskReady(TopicEventsRequest response, MessageHeaders headers) { + List flightIds = response.getData().getFlightIds(); + + log.info("ready task list:{}", Arrays.toString(flightIds.toArray()) ); + // Check conditional task blocking status. + String blockedId = waylineRedisService.getBlockedWaylineJobId(response.getGateway()); + if (!StringUtils.hasText(blockedId)) { + return null; + } + + Optional deviceOpt = deviceRedisService.getDeviceOnline(response.getGateway()); + if (deviceOpt.isEmpty()) { + return null; + } + DeviceDTO device = deviceOpt.get(); + + try { + for (String jobId : flightIds) { + boolean isExecute = this.executeFlightTask(device.getWorkspaceId(), jobId); + if (!isExecute) { + return null; + } + Optional waylineJobOpt = waylineRedisService.getConditionalWaylineJob(jobId); + if (waylineJobOpt.isEmpty()) { + log.info("The conditional job has expired and will no longer be executed."); + return new TopicEventsResponse<>(); + } + WaylineJobDTO waylineJob = waylineJobOpt.get(); + this.retryPrepareJob(new ConditionalWaylineJobKey(device.getWorkspaceId(), response.getGateway(), jobId), waylineJob); + return new TopicEventsResponse<>(); + } + } catch (Exception e) { + log.error("Failed to execute conditional task."); + e.printStackTrace(); + } + return new TopicEventsResponse<>(); + } + } diff --git a/src/main/java/com/dji/sample/wayline/service/impl/SDKWaylineService.java b/src/main/java/com/dji/sample/wayline/service/impl/SDKWaylineService.java new file mode 100644 index 0000000..4b82fc7 --- /dev/null +++ b/src/main/java/com/dji/sample/wayline/service/impl/SDKWaylineService.java @@ -0,0 +1,159 @@ +package com.dji.sample.wayline.service.impl; + +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.media.model.MediaFileCountDTO; +import com.dji.sample.media.service.IMediaRedisService; +import com.dji.sample.wayline.model.dto.WaylineJobDTO; +import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum; +import com.dji.sample.wayline.service.IWaylineFileService; +import com.dji.sample.wayline.service.IWaylineJobService; +import com.dji.sample.wayline.service.IWaylineRedisService; +import com.dji.sdk.cloudapi.wayline.*; +import com.dji.sdk.cloudapi.wayline.api.AbstractWaylineService; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; + +import java.net.URL; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.util.Objects; +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/7 + */ +@Service +@Slf4j +public class SDKWaylineService extends AbstractWaylineService { + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private IWaylineRedisService waylineRedisService; + + @Autowired + private IMediaRedisService mediaRedisService; + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IWaylineJobService waylineJobService; + + @Autowired + private IWaylineFileService waylineFileService; + + @Override + public TopicEventsResponse deviceExitHomingNotify(TopicEventsRequest request, MessageHeaders headers) { + return super.deviceExitHomingNotify(request, headers); + } + + @Override + public TopicEventsResponse flighttaskProgress(TopicEventsRequest> response, MessageHeaders headers) { + EventsReceiver eventsReceiver = new EventsReceiver<>(); + eventsReceiver.setResult(response.getData().getResult()); + eventsReceiver.setOutput(response.getData().getOutput()); + eventsReceiver.setBid(response.getBid()); + eventsReceiver.setSn(response.getGateway()); + + FlighttaskProgress output = eventsReceiver.getOutput(); + log.info("Task progress: {}", output.getProgress().toString()); + if (!eventsReceiver.getResult().isSuccess()) { + log.error("Task progress ===> Error: " + eventsReceiver.getResult()); + } + + Optional deviceOpt = deviceRedisService.getDeviceOnline(response.getGateway()); + if (deviceOpt.isEmpty()) { + return new TopicEventsResponse<>(); + } + + FlighttaskStatusEnum statusEnum = output.getStatus(); + waylineRedisService.setRunningWaylineJob(response.getGateway(), eventsReceiver); + + if (statusEnum.isEnd()) { + WaylineJobDTO job = WaylineJobDTO.builder() + .jobId(response.getBid()) + .status(WaylineJobStatusEnum.SUCCESS.getVal()) + .completedTime(LocalDateTime.now()) + .mediaCount(output.getExt().getMediaCount()) + .build(); + + // record the update of the media count. + if (Objects.nonNull(job.getMediaCount()) && job.getMediaCount() != 0) { + mediaRedisService.setMediaCount(response.getGateway(), job.getJobId(), + MediaFileCountDTO.builder().deviceSn(deviceOpt.get().getChildDeviceSn()) + .jobId(response.getBid()).mediaCount(job.getMediaCount()).uploadedCount(0).build()); + } + + if (FlighttaskStatusEnum.OK != statusEnum) { + job.setCode(eventsReceiver.getResult().getCode()); + job.setStatus(WaylineJobStatusEnum.FAILED.getVal()); + } + waylineJobService.updateJob(job); + waylineRedisService.delRunningWaylineJob(response.getGateway()); + waylineRedisService.delPausedWaylineJob(response.getBid()); + } + + webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.FLIGHT_TASK_PROGRESS.getCode(), eventsReceiver); + + return new TopicEventsResponse<>(); + } + + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Override + public TopicRequestsResponse> flighttaskResourceGet(TopicRequestsRequest response, MessageHeaders headers) { + String jobId = response.getData().getFlightId(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(response.getGateway()); + if (deviceOpt.isEmpty()) { + log.error("The device is offline, please try again later."); + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.DEVICE_OFFLINE)); + } + Optional waylineJobOpt = waylineJobService.getJobByJobId(deviceOpt.get().getWorkspaceId(), jobId); + if (waylineJobOpt.isEmpty()) { + log.error("The wayline job does not exist."); + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); + } + + WaylineJobDTO waylineJob = waylineJobOpt.get(); + + // get wayline file + Optional waylineFile = waylineFileService.getWaylineByWaylineId(waylineJob.getWorkspaceId(), waylineJob.getFileId()); + if (waylineFile.isEmpty()) { + log.error("The wayline file does not exist."); + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); + } + // get file url + try { + URL url = waylineFileService.getObjectUrl(waylineJob.getWorkspaceId(), waylineFile.get().getId()); + return new TopicRequestsResponse>().setData( + MqttReply.success(new FlighttaskResourceGetResponse() + .setFile(new FlighttaskFile() + .setUrl(url.toString()) + .setFingerprint(waylineFile.get().getSign())))); + } catch (SQLException | NullPointerException e) { + e.printStackTrace(); + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.SYSTEM_ERROR)); + } + } +} 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 bcea104..ae79c37 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 @@ -3,18 +3,20 @@ package com.dji.sample.wayline.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.dji.sample.common.model.Pagination; -import com.dji.sample.common.model.PaginationData; import com.dji.sample.component.oss.model.OssConfiguration; import com.dji.sample.component.oss.service.impl.OssServiceContext; -import com.dji.sample.manage.model.enums.DeviceDomainEnum; import com.dji.sample.wayline.dao.IWaylineFileMapper; import com.dji.sample.wayline.model.dto.KmzFileProperties; import com.dji.sample.wayline.model.dto.WaylineFileDTO; import com.dji.sample.wayline.model.entity.WaylineFileEntity; -import com.dji.sample.wayline.model.enums.WaylineTemplateTypeEnum; -import com.dji.sample.wayline.model.param.WaylineQueryParam; 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.wayline.GetWaylineListRequest; +import com.dji.sdk.cloudapi.wayline.GetWaylineListResponse; +import com.dji.sdk.cloudapi.wayline.WaylineTypeEnum; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Node; @@ -55,23 +57,23 @@ public class WaylineFileServiceImpl implements IWaylineFileService { private OssServiceContext ossService; @Override - public PaginationData getWaylinesByParam(String workspaceId, WaylineQueryParam param) { + public PaginationData getWaylinesByParam(String workspaceId, GetWaylineListRequest param) { // Paging Query Page page = mapper.selectPage( new Page(param.getPage(), param.getPageSize()), new LambdaQueryWrapper() .eq(WaylineFileEntity::getWorkspaceId, workspaceId) - .eq(param.isFavorited(), WaylineFileEntity::getFavorited, param.isFavorited()) + .eq(Objects.nonNull(param.getFavorited()), WaylineFileEntity::getFavorited, param.getFavorited()) .and(param.getTemplateType() != null, wrapper -> { - for (Integer type : param.getTemplateType()) { - wrapper.like(WaylineFileEntity::getTemplateTypes, type).or(); + for (WaylineTypeEnum type : param.getTemplateType()) { + wrapper.like(WaylineFileEntity::getTemplateTypes, type.getValue()).or(); } }) // There is a risk of SQL injection .last(StringUtils.hasText(param.getOrderBy()), " order by " + param.getOrderBy())); // Wrap the results of a paging query into a custom paging object. - List records = page.getRecords() + List records = page.getRecords() .stream() .map(this::entityConvertToDTO) .collect(Collectors.toList()); @@ -80,7 +82,7 @@ public class WaylineFileServiceImpl implements IWaylineFileService { } @Override - public Optional getWaylineByWaylineId(String workspaceId, String waylineId) { + public Optional getWaylineByWaylineId(String workspaceId, String waylineId) { return Optional.ofNullable( this.entityConvertToDTO( mapper.selectOne( @@ -91,7 +93,7 @@ public class WaylineFileServiceImpl implements IWaylineFileService { @Override public URL getObjectUrl(String workspaceId, String waylineId) throws SQLException { - Optional waylineOpt = this.getWaylineByWaylineId(workspaceId, waylineId); + Optional waylineOpt = this.getWaylineByWaylineId(workspaceId, waylineId); if (waylineOpt.isEmpty()) { throw new SQLException(waylineId + " does not exist."); } @@ -145,11 +147,11 @@ public class WaylineFileServiceImpl implements IWaylineFileService { @Override public Boolean deleteByWaylineId(String workspaceId, String waylineId) { - Optional waylineOpt = this.getWaylineByWaylineId(workspaceId, waylineId); + Optional waylineOpt = this.getWaylineByWaylineId(workspaceId, waylineId); if (waylineOpt.isEmpty()) { return true; } - WaylineFileDTO wayline = waylineOpt.get(); + GetWaylineListResponse wayline = waylineOpt.get(); boolean isDel = mapper.delete(new LambdaUpdateWrapper() .eq(WaylineFileEntity::getWorkspaceId, workspaceId) .eq(WaylineFileEntity::getWaylineId, waylineId)) @@ -169,7 +171,6 @@ public class WaylineFileServiceImpl implements IWaylineFileService { try { WaylineFileDTO waylineFile = waylineFileOpt.get(); - waylineFile.setWaylineId(workspaceId); waylineFile.setUsername(creator); ossService.putObject(OssConfiguration.bucket, waylineFile.getObjectKey(), file.getInputStream()); @@ -218,12 +219,12 @@ public class WaylineFileServiceImpl implements IWaylineFileService { } return Optional.of(WaylineFileDTO.builder() - .droneModelKey(String.format("%s-%s-%s", DeviceDomainEnum.SUB_DEVICE.getVal(), type, subType)) - .payloadModelKeys(List.of(String.format("%s-%s-%s",DeviceDomainEnum.PAYLOAD.getVal(), payloadType, payloadSubType))) + .droneModelKey(String.format("%s-%s-%s", DeviceDomainEnum.DRONE.getDomain(), type, subType)) + .payloadModelKeys(List.of(String.format("%s-%s-%s",DeviceDomainEnum.PAYLOAD.getDomain(), payloadType, payloadSubType))) .objectKey(OssConfiguration.objectDirPrefix + File.separator + filename) .name(filename.substring(0, filename.lastIndexOf(WAYLINE_FILE_SUFFIX))) .sign(DigestUtils.md5DigestAsHex(file.getInputStream())) - .templateTypes(List.of(WaylineTemplateTypeEnum.find(templateType).map(WaylineTemplateTypeEnum::getVal).orElse(-1))) + .templateTypes(List.of(WaylineTypeEnum.find(templateType).getValue())) .build()); } @@ -237,25 +238,24 @@ public class WaylineFileServiceImpl implements IWaylineFileService { * @param entity * @return */ - private WaylineFileDTO entityConvertToDTO(WaylineFileEntity entity) { + private GetWaylineListResponse entityConvertToDTO(WaylineFileEntity entity) { if (entity == null) { return null; } - return WaylineFileDTO.builder() - .droneModelKey(entity.getDroneModelKey()) - .favorited(entity.getFavorited()) - .name(entity.getName()) - .payloadModelKeys(entity.getPayloadModelKeys() != null ? - Arrays.asList(entity.getPayloadModelKeys().split(",")) : null) - .templateTypes(Arrays.stream(entity.getTemplateTypes().split(",")) - .map(Integer::parseInt) + return new GetWaylineListResponse() + .setDroneModelKey(DeviceEnum.find(entity.getDroneModelKey())) + .setFavorited(entity.getFavorited()) + .setName(entity.getName()) + .setPayloadModelKeys(entity.getPayloadModelKeys() != null ? + Arrays.stream(entity.getPayloadModelKeys().split(",")).map(DeviceEnum::find).collect(Collectors.toList()) : null) + .setTemplateTypes(Arrays.stream(entity.getTemplateTypes().split(",")) + .map(Integer::parseInt).map(WaylineTypeEnum::find) .collect(Collectors.toList())) - .username(entity.getUsername()) - .objectKey(entity.getObjectKey()) - .sign(entity.getSign()) - .updateTime(entity.getUpdateTime()) - .waylineId(entity.getWaylineId()) - .build(); + .setUsername(entity.getUsername()) + .setObjectKey(entity.getObjectKey()) + .setSign(entity.getSign()) + .setUpdateTime(entity.getUpdateTime()) + .setId(entity.getWaylineId()); } diff --git a/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java b/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java index 9d07192..923fd93 100644 --- a/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java +++ b/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java @@ -3,52 +3,40 @@ package com.dji.sample.wayline.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.dji.sample.common.error.CommonErrorEnum; -import com.dji.sample.common.model.CustomClaim; -import com.dji.sample.common.model.Pagination; -import com.dji.sample.common.model.PaginationData; -import com.dji.sample.common.model.ResponseResult; -import com.dji.sample.component.mqtt.model.*; -import com.dji.sample.component.mqtt.service.IMessageSenderService; +import com.dji.sample.component.mqtt.model.EventsReceiver; import com.dji.sample.component.redis.RedisConst; import com.dji.sample.component.redis.RedisOpsUtils; -import com.dji.sample.control.model.param.DrcModeParam; -import com.dji.sample.control.service.IDrcService; import com.dji.sample.manage.model.dto.DeviceDTO; -import com.dji.sample.manage.model.enums.DeviceModeCodeEnum; -import com.dji.sample.manage.model.enums.DockModeCodeEnum; -import com.dji.sample.manage.model.receiver.OsdDockReceiver; -import com.dji.sample.manage.model.receiver.OsdSubDeviceReceiver; import com.dji.sample.manage.service.IDeviceRedisService; import com.dji.sample.manage.service.IDeviceService; import com.dji.sample.media.model.MediaFileCountDTO; -import com.dji.sample.media.model.MediaMethodEnum; import com.dji.sample.media.service.IFileService; import com.dji.sample.wayline.dao.IWaylineJobMapper; -import com.dji.sample.wayline.model.dto.*; +import com.dji.sample.wayline.model.dto.WaylineJobDTO; import com.dji.sample.wayline.model.entity.WaylineJobEntity; -import com.dji.sample.wayline.model.enums.*; +import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum; import com.dji.sample.wayline.model.param.CreateJobParam; -import com.dji.sample.wayline.model.param.UpdateJobParam; import com.dji.sample.wayline.service.IWaylineFileService; import com.dji.sample.wayline.service.IWaylineJobService; import com.dji.sample.wayline.service.IWaylineRedisService; -import com.fasterxml.jackson.core.type.TypeReference; +import com.dji.sdk.cloudapi.device.DockModeCodeEnum; +import com.dji.sdk.cloudapi.device.DroneModeCodeEnum; +import com.dji.sdk.cloudapi.device.OsdDock; +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.wayline.*; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.mqtt.support.MqttHeaders; -import org.springframework.messaging.MessageHeaders; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import java.net.URL; -import java.sql.SQLException; -import java.time.*; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.*; import java.util.stream.Collectors; @@ -71,18 +59,12 @@ public class WaylineJobServiceImpl implements IWaylineJobService { @Autowired private IDeviceService deviceService; - @Autowired - private IMessageSenderService messageSender; - @Autowired private ObjectMapper objectMapper; @Autowired private IFileService fileService; - @Autowired - private IDrcService drcService; - @Autowired private IDeviceRedisService deviceRedisService; @@ -113,9 +95,9 @@ public class WaylineJobServiceImpl implements IWaylineJobService { .beginTime(beginTime) .endTime(endTime) .status(WaylineJobStatusEnum.PENDING.getVal()) - .taskType(param.getTaskType().getVal()) - .waylineType(param.getWaylineType().getVal()) - .outOfControlAction(param.getOutOfControlAction()) + .taskType(param.getTaskType().getType()) + .waylineType(param.getWaylineType().getValue()) + .outOfControlAction(param.getOutOfControlAction().getAction()) .rthAltitude(param.getRthAltitude()) .mediaCount(0) .build(); @@ -140,238 +122,13 @@ public class WaylineJobServiceImpl implements IWaylineJobService { return this.insertWaylineJob(jobEntity); } - /** - * For immediate tasks, the server time shall prevail. - * @param param - */ - private void fillImmediateTime(CreateJobParam param) { - if (WaylineTaskTypeEnum.IMMEDIATE != param.getTaskType()) { - return; - } - long now = System.currentTimeMillis() / 1000; - param.setTaskDays(Collections.singletonList(now)); - param.setTaskPeriods(Collections.singletonList(Collections.singletonList(now))); - } - - @Override - public ResponseResult publishFlightTask(CreateJobParam param, CustomClaim customClaim) throws SQLException { - fillImmediateTime(param); - - param.getTaskDays().sort((a, b) -> (int) (a - b)); - param.getTaskPeriods().sort((a, b) -> (int) (a.get(0) - b.get(0))); - for (Long taskDay : param.getTaskDays()) { - LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(taskDay), ZoneId.systemDefault()); - for (List taskPeriod : param.getTaskPeriods()) { - long beginTime = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(taskPeriod.get(0)), ZoneId.systemDefault())) - .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); - long endTime = taskPeriod.size() > 1 && Objects.nonNull(taskPeriod.get(1)) ? - LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(taskPeriod.get(1)), ZoneId.systemDefault())) - .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : beginTime; - if (WaylineTaskTypeEnum.IMMEDIATE != param.getTaskType() && endTime < System.currentTimeMillis()) { - return ResponseResult.error("The task has expired."); - } - Optional waylineJobOpt = this.createWaylineJob(param, customClaim.getWorkspaceId(), customClaim.getUsername(), beginTime, endTime); - if (waylineJobOpt.isEmpty()) { - return ResponseResult.error("Failed to create wayline job."); - } - - WaylineJobDTO waylineJob = waylineJobOpt.get(); - if (WaylineTaskTypeEnum.IMMEDIATE == param.getTaskType()) { - return this.publishOneFlightTask(waylineJob); - } - - // If it is a conditional task type, add conditions to the job parameters. - addPreparedJob(waylineJob, param, beginTime, endTime); - } - } - return ResponseResult.success(); - } - - private void addPreparedJob(WaylineJobDTO waylineJob, CreateJobParam param, Long beginTime, Long endTime) { - if (WaylineTaskTypeEnum.CONDITION == param.getTaskType()) { - waylineJob.setConditions( - WaylineTaskConditionDTO.builder() - .executableConditions(Objects.nonNull(param.getMinStorageCapacity()) ? - WaylineTaskExecutableConditionDTO.builder().storageCapacity(param.getMinStorageCapacity()).build() : null) - .readyConditions(WaylineTaskReadyConditionDTO.builder() - .batteryCapacity(param.getMinBatteryCapacity()) - .beginTime(beginTime) - .endTime(endTime) - .build()) - .build()); - - waylineRedisService.setConditionalWaylineJob(waylineJob); - } - // value: {workspace_id}:{dock_sn}:{job_id} - boolean isAdd = waylineRedisService.addPreparedWaylineJob(waylineJob); - if (!isAdd) { - throw new RuntimeException("Failed to create prepare job."); - } - } - - public ResponseResult publishOneFlightTask(WaylineJobDTO waylineJob) throws SQLException { - - boolean isSuccess = this.prepareFlightTask(waylineJob); - if (!isSuccess) { - return ResponseResult.error("Failed to prepare job."); - } - - // Issue an immediate task execution command. - if (WaylineTaskTypeEnum.IMMEDIATE == waylineJob.getTaskType()) { - boolean isExecuted = executeFlightTask(waylineJob.getWorkspaceId(), waylineJob.getJobId()); - if (!isExecuted) { - return ResponseResult.error("Failed to execute job."); - } - } - - return ResponseResult.success(); - } - - private Boolean prepareFlightTask(WaylineJobDTO waylineJob) throws SQLException { - - boolean isOnline = deviceRedisService.checkDeviceOnline(waylineJob.getDockSn()); - if (!isOnline) { - throw new RuntimeException("Dock is offline."); - } - - // get wayline file - Optional waylineFile = waylineFileService.getWaylineByWaylineId(waylineJob.getWorkspaceId(), waylineJob.getFileId()); - if (waylineFile.isEmpty()) { - throw new SQLException("Wayline file doesn't exist."); - } - - // get file url - URL url = waylineFileService.getObjectUrl(waylineJob.getWorkspaceId(), waylineFile.get().getWaylineId()); - - WaylineTaskCreateDTO flightTask = WaylineTaskCreateDTO.builder() - .flightId(waylineJob.getJobId()) - .executeTime(waylineJob.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()) - .taskType(waylineJob.getTaskType()) - .waylineType(waylineJob.getWaylineType()) - .rthAltitude(waylineJob.getRthAltitude()) - .outOfControlAction(waylineJob.getOutOfControlAction()) - .file(WaylineTaskFileDTO.builder() - .url(url.toString()) - .fingerprint(waylineFile.get().getSign()) - .build()) - .build(); - - if (WaylineTaskTypeEnum.CONDITION == waylineJob.getTaskType()) { - if (Objects.isNull(waylineJob.getConditions())) { - throw new IllegalArgumentException(); - } - flightTask.setReadyConditions(waylineJob.getConditions().getReadyConditions()); - flightTask.setExecutableConditions(waylineJob.getConditions().getExecutableConditions()); - } - - ServiceReply serviceReply = messageSender.publishServicesTopic( - waylineJob.getDockSn(), WaylineMethodEnum.FLIGHT_TASK_PREPARE.getMethod(), flightTask, waylineJob.getJobId()); - if (ResponseResult.CODE_SUCCESS != serviceReply.getResult()) { - log.info("Prepare task ====> Error code: {}", serviceReply.getResult()); - this.updateJob(WaylineJobDTO.builder() - .workspaceId(waylineJob.getWorkspaceId()) - .jobId(waylineJob.getJobId()) - .executeTime(LocalDateTime.now()) - .status(WaylineJobStatusEnum.FAILED.getVal()) - .completedTime(LocalDateTime.now()) - .code(serviceReply.getResult()).build()); - return false; - } - return true; - } - - @Override - public Boolean executeFlightTask(String workspaceId, String jobId) { - // get job - Optional waylineJob = this.getJobByJobId(workspaceId, jobId); - if (waylineJob.isEmpty()) { - throw new IllegalArgumentException("Job doesn't exist."); - } - - boolean isOnline = deviceRedisService.checkDeviceOnline(waylineJob.get().getDockSn()); - if (!isOnline) { - throw new RuntimeException("Dock is offline."); - } - - WaylineJobDTO job = waylineJob.get(); - WaylineTaskCreateDTO flightTask = WaylineTaskCreateDTO.builder().flightId(jobId).build(); - - ServiceReply serviceReply = messageSender.publishServicesTopic( - job.getDockSn(), WaylineMethodEnum.FLIGHT_TASK_EXECUTE.getMethod(), flightTask, jobId); - if (ResponseResult.CODE_SUCCESS != serviceReply.getResult()) { - log.info("Execute job ====> Error code: {}", serviceReply.getResult()); - this.updateJob(WaylineJobDTO.builder() - .jobId(jobId) - .executeTime(LocalDateTime.now()) - .status(WaylineJobStatusEnum.FAILED.getVal()) - .completedTime(LocalDateTime.now()) - .code(serviceReply.getResult()).build()); - // The conditional task fails and enters the blocking status. - if (WaylineTaskTypeEnum.CONDITION == job.getTaskType() - && WaylineErrorCodeEnum.find(serviceReply.getResult()).isBlock()) { - waylineRedisService.setBlockedWaylineJob(job.getDockSn(), jobId); - } - return false; - } - - this.updateJob(WaylineJobDTO.builder() - .jobId(jobId) - .executeTime(LocalDateTime.now()) - .status(WaylineJobStatusEnum.IN_PROGRESS.getVal()) - .build()); - waylineRedisService.setRunningWaylineJob(job.getDockSn(), EventsReceiver.builder().bid(jobId).sn(job.getDockSn()).build()); - return true; - } - - @Override - public void cancelFlightTask(String workspaceId, Collection jobIds) { - List waylineJobs = getJobsByConditions(workspaceId, jobIds, WaylineJobStatusEnum.PENDING); - - Set waylineJobIds = waylineJobs.stream().map(WaylineJobDTO::getJobId).collect(Collectors.toSet()); - // Check if the task status is correct. - boolean isErr = !jobIds.removeAll(waylineJobIds) || !jobIds.isEmpty() ; - if (isErr) { - throw new IllegalArgumentException("These tasks have an incorrect status and cannot be canceled. " + Arrays.toString(jobIds.toArray())); - } - - // Group job id by dock sn. - Map> dockJobs = waylineJobs.stream() - .collect(Collectors.groupingBy(WaylineJobDTO::getDockSn, - Collectors.mapping(WaylineJobDTO::getJobId, Collectors.toList()))); - dockJobs.forEach((dockSn, idList) -> this.publishCancelTask(workspaceId, dockSn, idList)); - - } - - public void publishCancelTask(String workspaceId, String dockSn, List jobIds) { - boolean isOnline = deviceRedisService.checkDeviceOnline(dockSn); - if (!isOnline) { - throw new RuntimeException("Dock is offline."); - } - - ServiceReply serviceReply = messageSender.publishServicesTopic( - dockSn, WaylineMethodEnum.FLIGHT_TASK_CANCEL.getMethod(), Map.of(MapKeyConst.FLIGHT_IDS, jobIds)); - if (ResponseResult.CODE_SUCCESS != serviceReply.getResult()) { - log.info("Cancel job ====> Error code: {}", serviceReply.getResult()); - throw new RuntimeException("Failed to cancel the wayline job of " + dockSn); - } - - for (String jobId : jobIds) { - this.updateJob(WaylineJobDTO.builder() - .workspaceId(workspaceId) - .jobId(jobId) - .status(WaylineJobStatusEnum.CANCEL.getVal()) - .completedTime(LocalDateTime.now()) - .build()); - } - - } - public List getJobsByConditions(String workspaceId, Collection jobIds, WaylineJobStatusEnum status) { return mapper.selectList( new LambdaQueryWrapper() .eq(WaylineJobEntity::getWorkspaceId, workspaceId) .eq(Objects.nonNull(status), WaylineJobEntity::getStatus, status.getVal()) - .in(!CollectionUtils.isEmpty(jobIds), WaylineJobEntity::getJobId, jobIds)) + .and(!CollectionUtils.isEmpty(jobIds), + wrapper -> jobIds.forEach(id -> wrapper.eq(WaylineJobEntity::getJobId, id).or()))) .stream() .map(this::entity2Dto) .collect(Collectors.toList()); @@ -408,85 +165,6 @@ public class WaylineJobServiceImpl implements IWaylineJobService { return new PaginationData(records, new Pagination(pageData)); } - - @Override - @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_FLIGHT_TASK_RESOURCE_GET, outputChannel = ChannelName.OUTBOUND) - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void flightTaskResourceGet(CommonTopicReceiver receiver, MessageHeaders headers) { - Map jobIdMap = objectMapper.convertValue(receiver.getData(), new TypeReference>() {}); - String jobId = jobIdMap.get(MapKeyConst.FLIGHT_ID); - - CommonTopicResponse.CommonTopicResponseBuilder builder = CommonTopicResponse.builder() - .tid(receiver.getTid()) - .bid(receiver.getBid()) - .method(RequestsMethodEnum.FLIGHT_TASK_RESOURCE_GET.getMethod()) - .timestamp(System.currentTimeMillis()); - - String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString() + TopicConst._REPLY_SUF; - - Optional deviceOpt = deviceRedisService.getDeviceOnline(receiver.getGateway()); - if (deviceOpt.isEmpty()) { - return; - } - Optional waylineJobOpt = this.getJobByJobId(deviceOpt.get().getWorkspaceId(), jobId); - if (waylineJobOpt.isEmpty()) { - builder.data(RequestsReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); - messageSender.publish(topic, builder.build()); - return; - } - - WaylineJobDTO waylineJob = waylineJobOpt.get(); - - // get wayline file - Optional waylineFile = waylineFileService.getWaylineByWaylineId(waylineJob.getWorkspaceId(), waylineJob.getFileId()); - if (waylineFile.isEmpty()) { - builder.data(RequestsReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); - messageSender.publish(topic, builder.build()); - return; - } - - // get file url - URL url = null; - try { - url = waylineFileService.getObjectUrl(waylineJob.getWorkspaceId(), waylineFile.get().getWaylineId()); - builder.data(RequestsReply.success(WaylineTaskCreateDTO.builder() - .file(WaylineTaskFileDTO.builder() - .url(url.toString()) - .fingerprint(waylineFile.get().getSign()) - .build()) - .build())); - - } catch (SQLException | NullPointerException e) { - e.printStackTrace(); - builder.data(RequestsReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); - messageSender.publish(topic, builder.build()); - return; - } - - messageSender.publish(topic, builder.build()); - - } - - @Override - public void uploadMediaHighestPriority(String workspaceId, String jobId) { - Optional jobOpt = getJobByJobId(workspaceId, jobId); - if (jobOpt.isEmpty()) { - throw new RuntimeException(CommonErrorEnum.ILLEGAL_ARGUMENT.getErrorMsg()); - } - - String dockSn = jobOpt.get().getDockSn(); - String key = RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + dockSn; - if (RedisOpsUtils.checkExist(key) && jobId.equals(((MediaFileCountDTO) RedisOpsUtils.get(key)).getJobId())) { - return; - } - - ServiceReply reply = messageSender.publishServicesTopic( - dockSn, MediaMethodEnum.UPLOAD_FLIGHT_TASK_MEDIA_PRIORITIZE.getMethod(), Map.of(MapKeyConst.FLIGHT_ID, jobId)); - if (ResponseResult.CODE_SUCCESS != reply.getResult()) { - throw new RuntimeException("Failed to set media job upload priority. Error Code: " + reply.getResult()); - } - } - private WaylineJobEntity dto2Entity(WaylineJobDTO dto) { WaylineJobEntity.WaylineJobEntityBuilder builder = WaylineJobEntity.builder(); if (dto == null) { @@ -512,53 +190,31 @@ public class WaylineJobServiceImpl implements IWaylineJobService { .fileId(dto.getFileId()) .dockSn(dto.getDockSn()) .workspaceId(dto.getWorkspaceId()) - .taskType(Optional.ofNullable(dto.getTaskType()).map(WaylineTaskTypeEnum::getVal).orElse(null)) - .waylineType(Optional.ofNullable(dto.getWaylineType()).map(WaylineTemplateTypeEnum::getVal).orElse(null)) + .taskType(Optional.ofNullable(dto.getTaskType()).map(TaskTypeEnum::getType).orElse(null)) + .waylineType(Optional.ofNullable(dto.getWaylineType()).map(WaylineTypeEnum::getValue).orElse(null)) .username(dto.getUsername()) .rthAltitude(dto.getRthAltitude()) - .outOfControlAction(dto.getOutOfControlAction()) + .outOfControlAction(Optional.ofNullable(dto.getOutOfControlAction()) + .map(OutOfControlActionEnum::getAction).orElse(null)) .parentId(dto.getParentId()) .build(); } - @Override - public void updateJobStatus(String workspaceId, String jobId, UpdateJobParam param) { - Optional waylineJobOpt = this.getJobByJobId(workspaceId, jobId); - if (waylineJobOpt.isEmpty()) { - throw new RuntimeException("The job does not exist."); - } - WaylineJobDTO waylineJob = waylineJobOpt.get(); - WaylineJobStatusEnum statusEnum = this.getWaylineState(waylineJob.getDockSn()); - if (statusEnum.getEnd() || WaylineJobStatusEnum.PENDING == statusEnum) { - throw new RuntimeException("The wayline job status does not match, and the operation cannot be performed."); - } - - switch (param.getStatus()) { - case PAUSE: - pauseJob(workspaceId, waylineJob.getDockSn(), jobId, statusEnum); - break; - case RESUME: - resumeJob(workspaceId, waylineJob.getDockSn(), jobId, statusEnum); - break; - } - - } - public WaylineJobStatusEnum getWaylineState(String dockSn) { Optional dockOpt = deviceRedisService.getDeviceOnline(dockSn); if (dockOpt.isEmpty() || !StringUtils.hasText(dockOpt.get().getChildDeviceSn())) { return WaylineJobStatusEnum.UNKNOWN; } - Optional dockOsdOpt = deviceRedisService.getDeviceOsd(dockSn, OsdDockReceiver.class); - Optional deviceOsdOpt = deviceRedisService.getDeviceOsd(dockOpt.get().getChildDeviceSn(), OsdSubDeviceReceiver.class); + Optional dockOsdOpt = deviceRedisService.getDeviceOsd(dockSn, OsdDock.class); + Optional deviceOsdOpt = deviceRedisService.getDeviceOsd(dockOpt.get().getChildDeviceSn(), OsdDockDrone.class); if (dockOsdOpt.isEmpty() || deviceOsdOpt.isEmpty() || DockModeCodeEnum.WORKING != dockOsdOpt.get().getModeCode()) { return WaylineJobStatusEnum.UNKNOWN; } - OsdSubDeviceReceiver osdDevice = deviceOsdOpt.get(); - if (DeviceModeCodeEnum.WAYLINE == osdDevice.getModeCode() - || DeviceModeCodeEnum.MANUAL == osdDevice.getModeCode() - || DeviceModeCodeEnum.TAKEOFF_AUTO == osdDevice.getModeCode()) { + OsdDockDrone osdDevice = deviceOsdOpt.get(); + if (DroneModeCodeEnum.WAYLINE == osdDevice.getModeCode() + || DroneModeCodeEnum.MANUAL == osdDevice.getModeCode() + || DroneModeCodeEnum.TAKEOFF_AUTO == osdDevice.getModeCode()) { if (StringUtils.hasText(waylineRedisService.getPausedWaylineJobId(dockSn))) { return WaylineJobStatusEnum.PAUSED; } @@ -569,43 +225,6 @@ public class WaylineJobServiceImpl implements IWaylineJobService { return WaylineJobStatusEnum.UNKNOWN; } - private void pauseJob(String workspaceId, String dockSn, String jobId, WaylineJobStatusEnum statusEnum) { - if (WaylineJobStatusEnum.PAUSED == statusEnum && jobId.equals(waylineRedisService.getPausedWaylineJobId(dockSn))) { - waylineRedisService.setPausedWaylineJob(dockSn, jobId); - return; - } - - ServiceReply reply = messageSender.publishServicesTopic( - dockSn, WaylineMethodEnum.FLIGHT_TASK_PAUSE.getMethod(), "", jobId); - if (ResponseResult.CODE_SUCCESS != reply.getResult()) { - throw new RuntimeException("Failed to pause wayline job. Error Code: " + reply.getResult()); - } - waylineRedisService.delRunningWaylineJob(dockSn); - waylineRedisService.setPausedWaylineJob(dockSn, jobId); - } - - private void resumeJob(String workspaceId, String dockSn, String jobId, WaylineJobStatusEnum statusEnum) { - Optional> runningDataOpt = waylineRedisService.getRunningWaylineJob(dockSn); - if (WaylineJobStatusEnum.IN_PROGRESS == statusEnum && jobId.equals(runningDataOpt.map(EventsReceiver::getSn).get())) { - waylineRedisService.setRunningWaylineJob(dockSn, runningDataOpt.get()); - return; - } - ServiceReply reply = messageSender.publishServicesTopic( - dockSn, WaylineMethodEnum.FLIGHT_TASK_RESUME.getMethod(), "", jobId); - if (ResponseResult.CODE_SUCCESS != reply.getResult()) { - throw new RuntimeException("Failed to resume wayline job. Error Code: " + reply.getResult()); - } - - runningDataOpt.ifPresent(runningData -> waylineRedisService.setRunningWaylineJob(dockSn, runningData)); - waylineRedisService.delPausedWaylineJob(dockSn); - - if (deviceService.checkDockDrcMode(dockSn)) { - drcService.deviceDrcExit(workspaceId, DrcModeParam.builder().dockSn(dockSn) - .clientId(drcService.getDrcModeInRedis(dockSn)).build()); - } - - } - private WaylineJobDTO entity2Dto(WaylineJobEntity entity) { if (entity == null) { return null; @@ -616,7 +235,7 @@ public class WaylineJobServiceImpl implements IWaylineJobService { .jobName(entity.getName()) .fileId(entity.getFileId()) .fileName(waylineFileService.getWaylineByWaylineId(entity.getWorkspaceId(), entity.getFileId()) - .orElse(WaylineFileDTO.builder().build()).getName()) + .orElse(new GetWaylineListResponse()).getName()) .dockSn(entity.getDockSn()) .dockName(deviceService.getDeviceBySn(entity.getDockSn()) .orElse(DeviceDTO.builder().build()).getNickname()) @@ -633,10 +252,10 @@ public class WaylineJobServiceImpl implements IWaylineJobService { LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getExecuteTime()), ZoneId.systemDefault()) : null) .completedTime(WaylineJobStatusEnum.find(entity.getStatus()).getEnd() ? LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getUpdateTime()), ZoneId.systemDefault()) : null) - .taskType(WaylineTaskTypeEnum.find(entity.getTaskType())) - .waylineType(WaylineTemplateTypeEnum.find(entity.getWaylineType())) + .taskType(TaskTypeEnum.find(entity.getTaskType())) + .waylineType(WaylineTypeEnum.find(entity.getWaylineType())) .rthAltitude(entity.getRthAltitude()) - .outOfControlAction(entity.getOutOfControlAction()) + .outOfControlAction(OutOfControlActionEnum.find(entity.getOutOfControlAction())) .mediaCount(entity.getMediaCount()); if (Objects.nonNull(entity.getEndTime())) { @@ -645,8 +264,8 @@ public class WaylineJobServiceImpl implements IWaylineJobService { if (WaylineJobStatusEnum.IN_PROGRESS.getVal() == entity.getStatus()) { builder.progress(waylineRedisService.getRunningWaylineJob(entity.getDockSn()) .map(EventsReceiver::getOutput) - .map(WaylineTaskProgressReceiver::getProgress) - .map(WaylineTaskProgress::getPercent) + .map(FlighttaskProgress::getProgress) + .map(FlighttaskProgressData::getPercent) .orElse(null)); } diff --git a/src/main/java/com/dji/sample/wayline/service/impl/WaylineRedisServiceImpl.java b/src/main/java/com/dji/sample/wayline/service/impl/WaylineRedisServiceImpl.java index 3307533..72aadd6 100644 --- a/src/main/java/com/dji/sample/wayline/service/impl/WaylineRedisServiceImpl.java +++ b/src/main/java/com/dji/sample/wayline/service/impl/WaylineRedisServiceImpl.java @@ -3,10 +3,10 @@ package com.dji.sample.wayline.service.impl; import com.dji.sample.component.mqtt.model.EventsReceiver; import com.dji.sample.component.redis.RedisConst; import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.wayline.model.dto.ConditionalWaylineJobKey; import com.dji.sample.wayline.model.dto.WaylineJobDTO; -import com.dji.sample.wayline.model.dto.WaylineJobKey; -import com.dji.sample.wayline.model.dto.WaylineTaskProgressReceiver; import com.dji.sample.wayline.service.IWaylineRedisService; +import com.dji.sdk.cloudapi.wayline.FlighttaskProgress; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @@ -25,13 +25,13 @@ import java.util.Optional; public class WaylineRedisServiceImpl implements IWaylineRedisService { @Override - public void setRunningWaylineJob(String dockSn, EventsReceiver data) { + public void setRunningWaylineJob(String dockSn, EventsReceiver data) { RedisOpsUtils.setWithExpire(RedisConst.WAYLINE_JOB_RUNNING_PREFIX + dockSn, data, RedisConst.DRC_MODE_ALIVE_SECOND); } @Override - public Optional> getRunningWaylineJob(String dockSn) { - return Optional.ofNullable((EventsReceiver) RedisOpsUtils.get(RedisConst.WAYLINE_JOB_RUNNING_PREFIX + dockSn)); + public Optional> getRunningWaylineJob(String dockSn) { + return Optional.ofNullable((EventsReceiver) RedisOpsUtils.get(RedisConst.WAYLINE_JOB_RUNNING_PREFIX + dockSn)); } @Override @@ -64,18 +64,13 @@ public class WaylineRedisServiceImpl implements IWaylineRedisService { return (String) RedisOpsUtils.get(RedisConst.WAYLINE_JOB_BLOCK_PREFIX + dockSn); } - @Override - public Boolean delBlockedWaylineJobId(String dockSn) { - return RedisOpsUtils.del(RedisConst.WAYLINE_JOB_BLOCK_PREFIX + dockSn); - } - @Override public void setConditionalWaylineJob(WaylineJobDTO waylineJob) { if (!StringUtils.hasText(waylineJob.getJobId())) { throw new RuntimeException("Job id can't be null."); } RedisOpsUtils.setWithExpire(RedisConst.WAYLINE_JOB_CONDITION_PREFIX + waylineJob.getJobId(), waylineJob, - Math.abs(Duration.between(waylineJob.getEndTime(), LocalDateTime.now()).getSeconds())); + (Duration.between(waylineJob.getEndTime(), LocalDateTime.now()).getSeconds())); } @Override @@ -89,29 +84,29 @@ public class WaylineRedisServiceImpl implements IWaylineRedisService { } @Override - public Boolean addPreparedWaylineJob(WaylineJobDTO waylineJob) { + public Boolean addPrepareConditionalWaylineJob(WaylineJobDTO waylineJob) { if (Objects.isNull(waylineJob.getBeginTime())) { return false; } // value: {workspace_id}:{dock_sn}:{job_id} - return RedisOpsUtils.zAdd(RedisConst.WAYLINE_JOB_PREPARED, + return RedisOpsUtils.zAdd(RedisConst.WAYLINE_JOB_CONDITION_PREPARE, waylineJob.getWorkspaceId() + RedisConst.DELIMITER + waylineJob.getDockSn() + RedisConst.DELIMITER + waylineJob.getJobId(), waylineJob.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); } @Override - public Optional getNearestPreparedWaylineJob() { - return Optional.ofNullable(RedisOpsUtils.zGetMin(RedisConst.WAYLINE_JOB_PREPARED)) - .map(Object::toString).map(WaylineJobKey::new); + public Optional getNearestConditionalWaylineJob() { + return Optional.ofNullable(RedisOpsUtils.zGetMin(RedisConst.WAYLINE_JOB_CONDITION_PREPARE)) + .map(Object::toString).map(ConditionalWaylineJobKey::new); } @Override - public Double getPreparedWaylineJobTime(WaylineJobKey jobKey) { - return RedisOpsUtils.zScore(RedisConst.WAYLINE_JOB_PREPARED, jobKey.getKey()); + public Double getConditionalWaylineJobTime(ConditionalWaylineJobKey jobKey) { + return RedisOpsUtils.zScore(RedisConst.WAYLINE_JOB_CONDITION_PREPARE, jobKey.getKey()); } @Override - public Boolean removePreparedWaylineJob(WaylineJobKey jobKey) { - return RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_PREPARED, jobKey.getKey()); + public Boolean removePrepareConditionalWaylineJob(ConditionalWaylineJobKey jobKey) { + return RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_CONDITION_PREPARE, jobKey.getKey()); } } diff --git a/src/main/java/com/dji/sdk/README.md b/src/main/java/com/dji/sdk/README.md new file mode 100644 index 0000000..f3f5ff5 --- /dev/null +++ b/src/main/java/com/dji/sdk/README.md @@ -0,0 +1,48 @@ +# 如何接入CloudSDK +### 1. 在组件扫描中增加包名:com.dji.sdk +### [2. 连接MQTT](#如何连接MQTT) +### [3. 实现SDK 的方法](#如何实现SDK的方法) +### [4. 调用SDK 的方法](#如何调用SDK的方法) + + +## 如何连接MQTT +- 在spring容器中注入MqttConnectOptions和MqttPahoClientFactory; + ![1](../../../../resources/image/6.png) + +- 在application.yml中配置cloud-sdk.mqtt.inbound-topic,未配置则不进行初始化订阅。 + + +## 如何实现SDK的方法 + - 定义一个类,继承com.dji.sdk.cloudapi.*.api包中的抽象类; + - 重写具体的方法以实现功能; + - 将定义的类放入spring容器中,由spring管理bean的生命周期。 +### 【设备上线】示例: + - 定义一个类:SDKDeviceService 继承AbstractDeviceService; +![1](../../../../resources/image/1.png) + - 重写方法updateTopoOnline,实现设备上线功能。 +![1](../../../../resources/image/2.png) + +## 如何调用SDK的方法 + - 定义一个类,继承com.dji.sdk.cloudapi.*.api包中的抽象类; + - 在需要调用的类中注入该类; + - 调用具体的方法。 +### 【航线预下发命令】示例: + - 定义一个类:SDKWaylineService 继承 AbstractWaylineService; +![1](../../../../resources/image/3.png) + - 在WaylineJobServiceImpl中注入该类; +![1](../../../../resources/image/4.png) + - 调用下发命令的方法: +![1](../../../../resources/image/5.png) + +## 如何实现CloudAPI 定义的http 接口 + - 定义一个类,实现com.dji.sdk.cloudapi.*.api包中的http接口类; + - 重写具体的方法以实现接口,无需定义请求地址和方法等数据。 + ![1](../../../../resources/image/7.png) + +## 如何查看CloudAPI 定义的所有http 接口 + - 启动程序 + - 浏览器打开:http://localhost:6789/swagger-ui/index.html + +## 如何接入WebSocket + - CloudSDK 已经定义了WebSocket服务,但是没有实现WebSocket管理。默认地址为:http://localhost:6789/api/v1/ws + - 自定义接入参考:com.dji.sample.component.websocket.config \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/annotations/CloudSDKVersion.java b/src/main/java/com/dji/sdk/annotations/CloudSDKVersion.java new file mode 100644 index 0000000..e7476d1 --- /dev/null +++ b/src/main/java/com/dji/sdk/annotations/CloudSDKVersion.java @@ -0,0 +1,26 @@ +package com.dji.sdk.annotations; + +import com.dji.sdk.common.CloudSDKVersionEnum; +import com.dji.sdk.common.GatewayTypeEnum; + +import java.lang.annotation.*; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/22 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.METHOD}) +public @interface CloudSDKVersion { + + CloudSDKVersionEnum since() default CloudSDKVersionEnum.V0_0_1; + + CloudSDKVersionEnum deprecated() default CloudSDKVersionEnum.V99; + + GatewayTypeEnum[] include() default {}; + + GatewayTypeEnum[] exclude() default {}; + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/config/ConfigScopeEnum.java b/src/main/java/com/dji/sdk/cloudapi/config/ConfigScopeEnum.java new file mode 100644 index 0000000..bc7004f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/config/ConfigScopeEnum.java @@ -0,0 +1,34 @@ +package com.dji.sdk.cloudapi.config; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +public enum ConfigScopeEnum { + + PRODUCT("product"); + + private final String scope; + + ConfigScopeEnum(String scope) { + this.scope = scope; + } + + @JsonValue + public String getScope() { + return scope; + } + + @JsonCreator + public static ConfigScopeEnum find(String scope) { + return Arrays.stream(values()).filter(scopeEnum -> scopeEnum.scope.equals(scope)).findAny() + .orElseThrow(() -> new CloudSDKException(ConfigScopeEnum.class, scope)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/config/ConfigTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/config/ConfigTypeEnum.java new file mode 100644 index 0000000..f8bf6d0 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/config/ConfigTypeEnum.java @@ -0,0 +1,34 @@ +package com.dji.sdk.cloudapi.config; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +public enum ConfigTypeEnum { + + JSON("json"); + + private final String type; + + ConfigTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static ConfigTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(ConfigTypeEnum.class, type)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/config/ProductConfigResponse.java b/src/main/java/com/dji/sdk/cloudapi/config/ProductConfigResponse.java new file mode 100644 index 0000000..f3a9bd2 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/config/ProductConfigResponse.java @@ -0,0 +1,73 @@ +package com.dji.sdk.cloudapi.config; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +public class ProductConfigResponse extends BaseModel { + + private String ntpServerHost; + + @NotNull + private String appId; + + @NotNull + private String appKey; + + @NotNull + private String appLicense; + + public ProductConfigResponse() { + } + + @Override + public String toString() { + return "ProductConfigResponse{" + + "ntpServerHost='" + ntpServerHost + '\'' + + ", appId='" + appId + '\'' + + ", appKey='" + appKey + '\'' + + ", appLicense='" + appLicense + '\'' + + '}'; + } + + public String getNtpServerHost() { + return ntpServerHost; + } + + public ProductConfigResponse setNtpServerHost(String ntpServerHost) { + this.ntpServerHost = ntpServerHost; + return this; + } + + public String getAppId() { + return appId; + } + + public ProductConfigResponse setAppId(String appId) { + this.appId = appId; + return this; + } + + public String getAppKey() { + return appKey; + } + + public ProductConfigResponse setAppKey(String appKey) { + this.appKey = appKey; + return this; + } + + public String getAppLicense() { + return appLicense; + } + + public ProductConfigResponse setAppLicense(String appLicense) { + this.appLicense = appLicense; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/config/RequestsConfigRequest.java b/src/main/java/com/dji/sdk/cloudapi/config/RequestsConfigRequest.java new file mode 100644 index 0000000..c25d861 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/config/RequestsConfigRequest.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.config; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +public class RequestsConfigRequest { + + private ConfigTypeEnum configType; + + private ConfigScopeEnum configScope; + + public RequestsConfigRequest() { + } + + @Override + public String toString() { + return "RequestsConfigRequest{" + + "configType=" + configType + + ", configScope=" + configScope + + '}'; + } + + public ConfigTypeEnum getConfigType() { + return configType; + } + + public RequestsConfigRequest setConfigType(ConfigTypeEnum configType) { + this.configType = configType; + return this; + } + + public ConfigScopeEnum getConfigScope() { + return configScope; + } + + public RequestsConfigRequest setConfigScope(ConfigScopeEnum configScope) { + this.configScope = configScope; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/config/api/AbstractConfigService.java b/src/main/java/com/dji/sdk/cloudapi/config/api/AbstractConfigService.java new file mode 100644 index 0000000..36b866f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/config/api/AbstractConfigService.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.config.api; + +import com.dji.sdk.cloudapi.config.ProductConfigResponse; +import com.dji.sdk.cloudapi.config.RequestsConfigRequest; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public abstract class AbstractConfigService { + + /** + * Inform of file uploading progress + * @param request data + * @param headers The headers for a {@link Message}. + * @return requests_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_CONFIG, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse requestsConfig(TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("requestsConfig not implemented"); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/CameraAimRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/CameraAimRequest.java new file mode 100644 index 0000000..ab9ea9d --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/CameraAimRequest.java @@ -0,0 +1,99 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraAimRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private CameraTypeEnum cameraType; + + /** + * true: Lock the gimbal, the gimbal and the drone rotate together. + * false: Only the gimbal rotates, but the drone does not. + */ + @NotNull + private Boolean locked; + + /** + * upper left corner as center point + */ + @Min(0) + @Max(1) + private Float x; + + @Min(0) + @Max(1) + private Float y; + + public CameraAimRequest() { + } + + @Override + public String toString() { + return "CameraAimRequest{" + + "payloadIndex=" + payloadIndex + + ", cameraType=" + cameraType + + ", locked=" + locked + + ", x=" + x + + ", y=" + y + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraAimRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public CameraTypeEnum getCameraType() { + return cameraType; + } + + public CameraAimRequest setCameraType(CameraTypeEnum cameraType) { + this.cameraType = cameraType; + return this; + } + + public Boolean getLocked() { + return locked; + } + + public CameraAimRequest setLocked(Boolean locked) { + this.locked = locked; + return this; + } + + public Float getX() { + return x; + } + + public CameraAimRequest setX(Float x) { + this.x = x; + return this; + } + + public Float getY() { + return y; + } + + public CameraAimRequest setY(Float y) { + this.y = y; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/CameraFocalLengthSetRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/CameraFocalLengthSetRequest.java new file mode 100644 index 0000000..73de6a0 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/CameraFocalLengthSetRequest.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraFocalLengthSetRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private ZoomCameraTypeEnum cameraType; + + @Min(2) + @Max(200) + @NotNull + private Float zoomFactor; + + public CameraFocalLengthSetRequest() { + } + + @Override + public String toString() { + return "CameraFocalLengthSetRequest{" + + "payloadIndex=" + payloadIndex + + ", cameraType=" + cameraType + + ", zoomFactor=" + zoomFactor + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraFocalLengthSetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ZoomCameraTypeEnum getCameraType() { + return cameraType; + } + + public CameraFocalLengthSetRequest setCameraType(ZoomCameraTypeEnum cameraType) { + this.cameraType = cameraType; + return this; + } + + public Float getZoomFactor() { + return zoomFactor; + } + + public CameraFocalLengthSetRequest setZoomFactor(Float zoomFactor) { + this.zoomFactor = zoomFactor; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/CameraModeSwitchRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/CameraModeSwitchRequest.java new file mode 100644 index 0000000..37d00c8 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/CameraModeSwitchRequest.java @@ -0,0 +1,50 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.device.CameraModeEnum; +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraModeSwitchRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private CameraModeEnum cameraMode; + + public CameraModeSwitchRequest() { + } + + @Override + public String toString() { + return "CameraModeSwitchRequest{" + + "payloadIndex=" + payloadIndex + + ", cameraMode=" + cameraMode + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraModeSwitchRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public CameraModeEnum getCameraMode() { + return cameraMode; + } + + public CameraModeSwitchRequest setCameraMode(CameraModeEnum cameraMode) { + this.cameraMode = cameraMode; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/CameraPhotoTakeRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/CameraPhotoTakeRequest.java new file mode 100644 index 0000000..a2fef96 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/CameraPhotoTakeRequest.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraPhotoTakeRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + public CameraPhotoTakeRequest() { + } + + @Override + public String toString() { + return "CameraPhotoTakeRequest{" + + "payloadIndex=" + payloadIndex + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraPhotoTakeRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/CameraRecordingStartRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/CameraRecordingStartRequest.java new file mode 100644 index 0000000..f695c7d --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/CameraRecordingStartRequest.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraRecordingStartRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + public CameraRecordingStartRequest() { + } + + @Override + public String toString() { + return "CameraRecordingStartRequest{" + + "payloadIndex=" + payloadIndex + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraRecordingStartRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/CameraRecordingStopRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/CameraRecordingStopRequest.java new file mode 100644 index 0000000..f98e268 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/CameraRecordingStopRequest.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraRecordingStopRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + public CameraRecordingStopRequest() { + } + + @Override + public String toString() { + return "CameraRecordingStopRequest{" + + "payloadIndex=" + payloadIndex + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraRecordingStopRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } +} diff --git a/src/main/java/com/dji/sample/control/model/enums/CameraTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/CameraTypeEnum.java similarity index 55% rename from src/main/java/com/dji/sample/control/model/enums/CameraTypeEnum.java rename to src/main/java/com/dji/sdk/cloudapi/control/CameraTypeEnum.java index cda43e1..03dd866 100644 --- a/src/main/java/com/dji/sample/control/model/enums/CameraTypeEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/control/CameraTypeEnum.java @@ -1,8 +1,8 @@ -package com.dji.sample.control.model.enums; +package com.dji.sdk.cloudapi.control; +import com.dji.sdk.exception.CloudSDKException; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import lombok.Getter; import java.util.Arrays; @@ -11,7 +11,6 @@ import java.util.Arrays; * @version 1.4 * @date 2023/3/3 */ -@Getter public enum CameraTypeEnum { ZOOM("zoom"), @@ -20,7 +19,7 @@ public enum CameraTypeEnum { IR("ir"); - String type; + private final String type; CameraTypeEnum(String type) { this.type = type; @@ -32,7 +31,8 @@ public enum CameraTypeEnum { } @JsonCreator - public static CameraTypeEnum find(String cameraType) { - return Arrays.stream(CameraTypeEnum.values()).filter(typeEnum -> typeEnum.type.equals(cameraType)).findAny().get(); + public static CameraTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(CameraTypeEnum.class, type)); } } diff --git a/src/main/java/com/dji/sdk/cloudapi/control/CommanderFlightModeEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/CommanderFlightModeEnum.java new file mode 100644 index 0000000..9e2ea90 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/CommanderFlightModeEnum.java @@ -0,0 +1,37 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/8/7 + */ +public enum CommanderFlightModeEnum { + + SMART_HEIGHT(0), + + SETTING_HEIGHT(1); + + private final int mode; + + CommanderFlightModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static CommanderFlightModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(CommanderFlightModeEnum.class, mode)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/CommanderModeLostActionEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/CommanderModeLostActionEnum.java new file mode 100755 index 0000000..f3f630e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/CommanderModeLostActionEnum.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum CommanderModeLostActionEnum { + + CONTINUE(0), + + EXECUTE_RC_LOST_ACTION(1); + + private final int action; + + CommanderModeLostActionEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static CommanderModeLostActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(CommanderModeLostActionEnum.class, action)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/ControlErrorCodeEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/ControlErrorCodeEnum.java new file mode 100644 index 0000000..90c782c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/ControlErrorCodeEnum.java @@ -0,0 +1,91 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.common.IErrorInfo; +import com.dji.sdk.mqtt.events.IEventsErrorCode; +import com.dji.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum ControlErrorCodeEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + SETTING_RTH_FAILED(327000, "Height of return to home setting failed."), + + SETTING_LOST_ACTION_FAILED(327001, "Signal lost action setting failed."), + + OBTAIN_CONTROL_FAILED(327002, "Failed to obtain control."), + + DEVICE_OFFLINE(327003, "Failed to obtain control. Device offline."), + + DRAG_LIVESTREAM_VIEW_FAILED(327004, "Failed to drag livestream view."), + + AIM_FAILED(327005, "Failed to double tab to be AIM."), + + TAKE_PHOTO_FAILED(327006, "Failed to take photo."), + + START_RECORDING_FAILED(327007, "Failed to start recording."), + + STOP_RECORDING_FAILED(327008, "Failed to stop recording."), + + SWITCH_CAMERA_MODE_FAILED(327009, "Failed to switch camera modes."), + + ZOOM_CAMERA_ZOOM_FAILED(327010, "Failed to zoom in/out with zoom camera."), + + IR_CAMERA_ZOOM_FAILED(327011, "Failed to zoom in/out with IR camera."), + + DEVICE_LOCK(327012, "Failed to obtain control. Device is locked."), + + SETTING_WAYLINE_LOST_ACTION_FAILED(327013, "Wayline signal lost action setting failed."), + + GIMBAL_REACH_LIMIT(327014, "Gimbal reached movement limit."), + + WRONG_LENS_TYPE(327015, "Invalid camera lens type."), + + + DRC_ABNORMAL(514300, "DRC abnormal."), + + DRC_HEARTBEAT_TIMED_OUT(514301, "DRC heartbeat timed out."), + + DRC_CERTIFICATE_ABNORMAL(514302, "DRC certificate is abnormal."), + + DRC_LINK_LOST(514303, "DRC link is lost."), + + DRC_LINK_REFUSED(514304, "DRC link is refused."), + + UNKNOWN(-1, "UNKNOWN"), + + ; + + + private final String msg; + + private final int code; + + ControlErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + /** + * @param code error code + * @return enumeration object + */ + public static ControlErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/ControlMethodEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/ControlMethodEnum.java new file mode 100644 index 0000000..4aab79d --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/ControlMethodEnum.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.control; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/2 + */ +public enum ControlMethodEnum { + + FLIGHT_AUTHORITY_GRAB("flight_authority_grab"), + + PAYLOAD_AUTHORITY_GRAB("payload_authority_grab"), + + DRC_MODE_ENTER("drc_mode_enter"), + + DRC_MODE_EXIT("drc_mode_exit"), + + FLY_TO_POINT("fly_to_point"), + + FLY_TO_POINT_STOP("fly_to_point_stop"), + + TAKEOFF_TO_POINT("takeoff_to_point"), + + CAMERA_MODE_SWITCH("camera_mode_switch"), + + CAMERA_PHOTO_TAKE("camera_photo_take"), + + CAMERA_RECORDING_START("camera_recording_start"), + + CAMERA_RECORDING_STOP("camera_recording_stop"), + + CAMERA_AIM("camera_aim"), + + CAMERA_FOCAL_LENGTH_SET("camera_focal_length_set"), + + GIMBAL_RESET("gimbal_reset"), + + DRONE_CONTROL("drone_control"), + + DRONE_EMERGENCY_STOP("drone_emergency_stop"), + + HEART_BEAT("heart_beat"); + + private final String method; + + ControlMethodEnum(String method) { + this.method = method; + } + + public String getMethod() { + return method; + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/DelayInfoPush.java b/src/main/java/com/dji/sdk/cloudapi/control/DelayInfoPush.java new file mode 100644 index 0000000..d7a8caa --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/DelayInfoPush.java @@ -0,0 +1,44 @@ +package com.dji.sdk.cloudapi.control; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class DelayInfoPush { + + private Integer sdrCmdDelay; + + private List liveviewDelayList; + + public DelayInfoPush() { + } + + @Override + public String toString() { + return "DelayInfoPush{" + + "sdrCmdDelay=" + sdrCmdDelay + + ", liveviewDelayList=" + liveviewDelayList + + '}'; + } + + public Integer getSdrCmdDelay() { + return sdrCmdDelay; + } + + public DelayInfoPush setSdrCmdDelay(Integer sdrCmdDelay) { + this.sdrCmdDelay = sdrCmdDelay; + return this; + } + + public List getLiveviewDelayList() { + return liveviewDelayList; + } + + public DelayInfoPush setLiveviewDelayList(List liveviewDelayList) { + this.liveviewDelayList = liveviewDelayList; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/DrcModeEnterRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/DrcModeEnterRequest.java new file mode 100644 index 0000000..7c5bcf2 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/DrcModeEnterRequest.java @@ -0,0 +1,75 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/12 + */ +public class DrcModeEnterRequest extends BaseModel { + + @NotNull + @Valid + private DrcModeMqttBroker mqttBroker; + + /** + * range: 1 - 30 + */ + @Min(1) + @Max(30) + @NotNull + private Integer osdFrequency; + + /** + * range: 1 - 30 + */ + @Min(1) + @Max(30) + @NotNull + private Integer hsiFrequency; + + public DrcModeEnterRequest() { + } + + @Override + public String toString() { + return "DrcModeEnterRequest{" + + "mqttBroker=" + mqttBroker + + ", osdFrequency=" + osdFrequency + + ", hsiFrequency=" + hsiFrequency + + '}'; + } + + public DrcModeMqttBroker getMqttBroker() { + return mqttBroker; + } + + public DrcModeEnterRequest setMqttBroker(DrcModeMqttBroker mqttBroker) { + this.mqttBroker = mqttBroker; + return this; + } + + public Integer getOsdFrequency() { + return osdFrequency; + } + + public DrcModeEnterRequest setOsdFrequency(Integer osdFrequency) { + this.osdFrequency = osdFrequency; + return this; + } + + public Integer getHsiFrequency() { + return hsiFrequency; + } + + public DrcModeEnterRequest setHsiFrequency(Integer hsiFrequency) { + this.hsiFrequency = hsiFrequency; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/DrcModeMqttBroker.java b/src/main/java/com/dji/sdk/cloudapi/control/DrcModeMqttBroker.java new file mode 100644 index 0000000..7b16c71 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/DrcModeMqttBroker.java @@ -0,0 +1,102 @@ +package com.dji.sdk.cloudapi.control; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/11 + */ +public class DrcModeMqttBroker { + + @NotNull + private String address; + + @NotNull + private String username; + + @NotNull + private String password; + + @NotNull + private String clientId; + + @NotNull + @Min(1234567890) + @Max(9999999999L) + private Long expireTime; + + @NotNull + private Boolean enableTls; + + public DrcModeMqttBroker() { + } + + @Override + public String toString() { + return "DrcModeMqttBroker{" + + "address='" + address + '\'' + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", clientId='" + clientId + '\'' + + ", expireTime=" + expireTime + + ", enableTls=" + enableTls + + '}'; + } + + public String getAddress() { + return address; + } + + public DrcModeMqttBroker setAddress(String address) { + this.address = address; + return this; + } + + public String getUsername() { + return username; + } + + public DrcModeMqttBroker setUsername(String username) { + this.username = username; + return this; + } + + public String getPassword() { + return password; + } + + public DrcModeMqttBroker setPassword(String password) { + this.password = password; + return this; + } + + public String getClientId() { + return clientId; + } + + public DrcModeMqttBroker setClientId(String clientId) { + this.clientId = clientId; + return this; + } + + public Long getExpireTime() { + return expireTime; + } + + public DrcModeMqttBroker setExpireTime(Long expireTime) { + this.expireTime = expireTime; + return this; + } + + public Boolean getEnableTls() { + return enableTls; + } + + public DrcModeMqttBroker setEnableTls(Boolean enableTls) { + this.enableTls = enableTls; + return this; + } +} diff --git a/src/main/java/com/dji/sample/control/model/enums/DrcStatusErrorEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/DrcStatusErrorEnum.java similarity index 72% rename from src/main/java/com/dji/sample/control/model/enums/DrcStatusErrorEnum.java rename to src/main/java/com/dji/sdk/cloudapi/control/DrcStatusErrorEnum.java index 1cee634..34dc7b4 100644 --- a/src/main/java/com/dji/sample/control/model/enums/DrcStatusErrorEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/control/DrcStatusErrorEnum.java @@ -1,6 +1,7 @@ -package com.dji.sample.control.model.enums; +package com.dji.sdk.cloudapi.control; -import com.dji.sample.common.error.IErrorInfo; +import com.dji.sdk.common.IErrorInfo; +import com.dji.sdk.exception.CloudSDKException; import com.fasterxml.jackson.annotation.JsonCreator; import java.util.Arrays; @@ -22,13 +23,11 @@ public enum DrcStatusErrorEnum implements IErrorInfo { MQTT_LOST(514303, "The dock network is abnormal and the mqtt connection is lost."), - MQTT_REFUSE(514304, "The dock connection to mqtt server was refused."), + MQTT_REFUSE(514304, "The dock connection to mqtt server was refused."); - UNKNOWN(-1, "Unknown"); + private final String msg; - String msg; - - int code; + private final int code; DrcStatusErrorEnum(int code, String msg) { this.code = code; @@ -36,17 +35,18 @@ public enum DrcStatusErrorEnum implements IErrorInfo { } @Override - public String getErrorMsg() { + public String getMessage() { return msg; } @Override - public Integer getErrorCode() { + public Integer getCode() { return code; } @JsonCreator(mode = JsonCreator.Mode.DELEGATING) public static DrcStatusErrorEnum find(int code) { - return Arrays.stream(values()).filter(error -> error.code == code).findAny().orElse(UNKNOWN); + return Arrays.stream(values()).filter(error -> error.code == code).findAny() + .orElseThrow(() -> new CloudSDKException(DrcStatusErrorEnum.class, code)); } } diff --git a/src/main/java/com/dji/sdk/cloudapi/control/DrcStatusNotify.java b/src/main/java/com/dji/sdk/cloudapi/control/DrcStatusNotify.java new file mode 100644 index 0000000..4b04670 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/DrcStatusNotify.java @@ -0,0 +1,44 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.device.DrcStateEnum; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/17 + */ +public class DrcStatusNotify { + + private DrcStatusErrorEnum result; + + private DrcStateEnum drcState; + + public DrcStatusNotify() { + } + + @Override + public String toString() { + return "DrcStatusNotify{" + + "result=" + result + + ", drcState=" + drcState + + '}'; + } + + public DrcStatusErrorEnum getResult() { + return result; + } + + public DrcStatusNotify setResult(DrcStatusErrorEnum result) { + this.result = result; + return this; + } + + public DrcStateEnum getDrcState() { + return drcState; + } + + public DrcStatusNotify setDrcState(DrcStateEnum drcState) { + this.drcState = drcState; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/DroneControlRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/DroneControlRequest.java new file mode 100644 index 0000000..e6ba180 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/DroneControlRequest.java @@ -0,0 +1,121 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class DroneControlRequest extends BaseModel { + + @NotNull + private Long seq; + + @Min(-17) + @Max(17) + private Float x; + + @Min(-17) + @Max(17) + private Float y; + + @Min(-4) + @Max(5) + private Float h; + + @Min(-90) + @Max(90) + private Float w; + + @Min(2) + @Max(10) + private Integer freq; + + @Min(100) + @Max(1000) + private Integer delayTime; + + public DroneControlRequest() { + } + + @Override + public String toString() { + return "DroneControlRequest{" + + "seq=" + seq + + ", x=" + x + + ", y=" + y + + ", h=" + h + + ", w=" + w + + ", freq=" + freq + + ", delayTime=" + delayTime + + '}'; + } + + public Long getSeq() { + return seq; + } + + public DroneControlRequest setSeq(Long seq) { + this.seq = seq; + return this; + } + + public Float getX() { + return x; + } + + public DroneControlRequest setX(Float x) { + this.x = x; + return this; + } + + public Float getY() { + return y; + } + + public DroneControlRequest setY(Float y) { + this.y = y; + return this; + } + + public Float getH() { + return h; + } + + public DroneControlRequest setH(Float h) { + this.h = h; + return this; + } + + public Float getW() { + return w; + } + + public DroneControlRequest setW(Float w) { + this.w = w; + return this; + } + + public Integer getFreq() { + return freq; + } + + public DroneControlRequest setFreq(Integer freq) { + this.freq = freq; + return this; + } + + public Integer getDelayTime() { + return delayTime; + } + + public DroneControlRequest setDelayTime(Integer delayTime) { + this.delayTime = delayTime; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/DroneControlResponse.java b/src/main/java/com/dji/sdk/cloudapi/control/DroneControlResponse.java new file mode 100644 index 0000000..d47b61b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/DroneControlResponse.java @@ -0,0 +1,31 @@ +package com.dji.sdk.cloudapi.control; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class DroneControlResponse { + + private Long seq; + + public DroneControlResponse() { + } + + @Override + public String toString() { + return "DroneControlResponse{" + + "seq=" + seq + + '}'; + } + + public Long getSeq() { + return seq; + } + + public DroneControlResponse setSeq(Long seq) { + this.seq = seq; + return this; + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/FlyToPointProgress.java b/src/main/java/com/dji/sdk/cloudapi/control/FlyToPointProgress.java new file mode 100644 index 0000000..ffdc8bc --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/FlyToPointProgress.java @@ -0,0 +1,68 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.wayline.WaylineErrorCodeEnum; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/14 + */ +public class FlyToPointProgress { + + private WaylineErrorCodeEnum result; + + private FlyToStatusEnum status; + + private String flyToId; + + private Integer wayPointIndex; + + public FlyToPointProgress() { + } + + @Override + public String toString() { + return "FlyToPointProgress{" + + "result=" + result + + ", status=" + status + + ", flyToId='" + flyToId + '\'' + + ", wayPointIndex=" + wayPointIndex + + '}'; + } + + public WaylineErrorCodeEnum getResult() { + return result; + } + + public FlyToPointProgress setResult(WaylineErrorCodeEnum result) { + this.result = result; + return this; + } + + public FlyToStatusEnum getStatus() { + return status; + } + + public FlyToPointProgress setStatus(FlyToStatusEnum status) { + this.status = status; + return this; + } + + public String getFlyToId() { + return flyToId; + } + + public FlyToPointProgress setFlyToId(String flyToId) { + this.flyToId = flyToId; + return this; + } + + public Integer getWayPointIndex() { + return wayPointIndex; + } + + public FlyToPointProgress setWayPointIndex(Integer wayPointIndex) { + this.wayPointIndex = wayPointIndex; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/FlyToPointRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/FlyToPointRequest.java new file mode 100644 index 0000000..8af4ca9 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/FlyToPointRequest.java @@ -0,0 +1,71 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.*; +import java.util.List; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/14 + */ +public class FlyToPointRequest extends BaseModel { + + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @NotNull + private String flyToId; + + @Min(1) + @Max(15) + @NotNull + private Integer maxSpeed; + + /** + * The M30 series only support one point. + */ + @Size(min = 1) + @Valid + @NotNull + private List points; + + public FlyToPointRequest() { + } + + @Override + public String toString() { + return "FlyToPointRequest{" + + "flyToId='" + flyToId + '\'' + + ", maxSpeed=" + maxSpeed + + ", points=" + points + + '}'; + } + + public String getFlyToId() { + return flyToId; + } + + public FlyToPointRequest setFlyToId(String flyToId) { + this.flyToId = flyToId; + return this; + } + + public Integer getMaxSpeed() { + return maxSpeed; + } + + public FlyToPointRequest setMaxSpeed(Integer maxSpeed) { + this.maxSpeed = maxSpeed; + return this; + } + + public List getPoints() { + return points; + } + + public FlyToPointRequest setPoints(List points) { + this.points = points; + return this; + } +} diff --git a/src/main/java/com/dji/sample/control/model/enums/FlyToStatusEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/FlyToStatusEnum.java similarity index 60% rename from src/main/java/com/dji/sample/control/model/enums/FlyToStatusEnum.java rename to src/main/java/com/dji/sdk/cloudapi/control/FlyToStatusEnum.java index 4291769..f1d32a2 100644 --- a/src/main/java/com/dji/sample/control/model/enums/FlyToStatusEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/control/FlyToStatusEnum.java @@ -1,6 +1,8 @@ -package com.dji.sample.control.model.enums; +package com.dji.sdk.cloudapi.control; +import com.dji.sdk.exception.CloudSDKException; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; import java.util.Arrays; @@ -13,15 +15,15 @@ public enum FlyToStatusEnum { WAYLINE_PROGRESS("wayline_progress", "The FlyTo job is in progress."), - WAYLINE_FAILED("wayline_failed", "The Fly To task execution failed."), + WAYLINE_FAILED("wayline_failed", "The FlyTo job execution failed."), WAYLINE_OK("wayline_ok", "The FlyTo job executed successfully."), WAYLINE_CANCEL("wayline_cancel", "The FlyTo job is closed."); - String status; + private final String status; - String message; + private final String message; FlyToStatusEnum(String status, String message) { this.status = status; @@ -32,8 +34,14 @@ public enum FlyToStatusEnum { return message; } + @JsonValue + public String getStatus() { + return status; + } + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) public static FlyToStatusEnum find(String status) { - return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny().get(); + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(FlyToStatusEnum.class, status)); } } diff --git a/src/main/java/com/dji/sdk/cloudapi/control/GimbalResetModeEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/GimbalResetModeEnum.java new file mode 100644 index 0000000..8c14b6b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/GimbalResetModeEnum.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/13 + */ +public enum GimbalResetModeEnum { + + RECENTER(0), + + DOWN(1), + + RECENTER_PAN(2), + + PITCH_DOWN(3); + + private final int mode; + + GimbalResetModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static GimbalResetModeEnum find(int mode) { + return Arrays.stream(values()).filter(resetModeEnum -> resetModeEnum.ordinal() == mode).findAny() + .orElseThrow(() -> new CloudSDKException(GimbalResetModeEnum.class, mode)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/GimbalResetRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/GimbalResetRequest.java new file mode 100644 index 0000000..8030180 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/GimbalResetRequest.java @@ -0,0 +1,49 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class GimbalResetRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private GimbalResetModeEnum resetMode; + + public GimbalResetRequest() { + } + + @Override + public String toString() { + return "GimbalResetRequest{" + + "payloadIndex=" + payloadIndex + + ", resetMode=" + resetMode + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public GimbalResetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public GimbalResetModeEnum getResetMode() { + return resetMode; + } + + public GimbalResetRequest setResetMode(GimbalResetModeEnum resetMode) { + this.resetMode = resetMode; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/HeartBeatRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/HeartBeatRequest.java new file mode 100644 index 0000000..8ae23af --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/HeartBeatRequest.java @@ -0,0 +1,50 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class HeartBeatRequest extends BaseModel { + + @NotNull + private Long seq; + + @NotNull + @Min(123456789012L) + private Long timestamp; + + public HeartBeatRequest() { + } + + @Override + public String toString() { + return "HeartBeatRequest{" + + "seq=" + seq + + ", timestamp=" + timestamp + + '}'; + } + + public Long getSeq() { + return seq; + } + + public HeartBeatRequest setSeq(Long seq) { + this.seq = seq; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public HeartBeatRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/HsiInfoPush.java b/src/main/java/com/dji/sdk/cloudapi/control/HsiInfoPush.java new file mode 100644 index 0000000..c9c5712 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/HsiInfoPush.java @@ -0,0 +1,248 @@ +package com.dji.sdk.cloudapi.control; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class HsiInfoPush { + + private Integer upDistance; + + private Integer downDistance; + + private List aroundDistance; + + private Boolean upEnable; + + private Boolean upWork; + + private Boolean downEnable; + + private Boolean downWork; + + private Boolean leftEnable; + + private Boolean leftWork; + + private Boolean rightEnable; + + private Boolean rightWork; + + private Boolean frontEnable; + + private Boolean frontWork; + + private Boolean backEnable; + + private Boolean backWork; + + private Boolean verticalEnable; + + private Boolean verticalWork; + + private Boolean horizontalEnable; + + private Boolean horizontalWork; + + public HsiInfoPush() { + } + + @Override + public String toString() { + return "HsiInfoPush{" + + "upDistance=" + upDistance + + ", downDistance=" + downDistance + + ", aroundDistance=" + aroundDistance + + ", upEnable=" + upEnable + + ", upWork=" + upWork + + ", downEnable=" + downEnable + + ", downWork=" + downWork + + ", leftEnable=" + leftEnable + + ", leftWork=" + leftWork + + ", rightEnable=" + rightEnable + + ", rightWork=" + rightWork + + ", frontEnable=" + frontEnable + + ", frontWork=" + frontWork + + ", backEnable=" + backEnable + + ", backWork=" + backWork + + ", verticalEnable=" + verticalEnable + + ", verticalWork=" + verticalWork + + ", horizontalEnable=" + horizontalEnable + + ", horizontalWork=" + horizontalWork + + '}'; + } + + public Integer getUpDistance() { + return upDistance; + } + + public HsiInfoPush setUpDistance(Integer upDistance) { + this.upDistance = upDistance; + return this; + } + + public Integer getDownDistance() { + return downDistance; + } + + public HsiInfoPush setDownDistance(Integer downDistance) { + this.downDistance = downDistance; + return this; + } + + public List getAroundDistance() { + return aroundDistance; + } + + public HsiInfoPush setAroundDistance(List aroundDistance) { + this.aroundDistance = aroundDistance; + return this; + } + + public Boolean getUpEnable() { + return upEnable; + } + + public HsiInfoPush setUpEnable(Boolean upEnable) { + this.upEnable = upEnable; + return this; + } + + public Boolean getUpWork() { + return upWork; + } + + public HsiInfoPush setUpWork(Boolean upWork) { + this.upWork = upWork; + return this; + } + + public Boolean getDownEnable() { + return downEnable; + } + + public HsiInfoPush setDownEnable(Boolean downEnable) { + this.downEnable = downEnable; + return this; + } + + public Boolean getDownWork() { + return downWork; + } + + public HsiInfoPush setDownWork(Boolean downWork) { + this.downWork = downWork; + return this; + } + + public Boolean getLeftEnable() { + return leftEnable; + } + + public HsiInfoPush setLeftEnable(Boolean leftEnable) { + this.leftEnable = leftEnable; + return this; + } + + public Boolean getLeftWork() { + return leftWork; + } + + public HsiInfoPush setLeftWork(Boolean leftWork) { + this.leftWork = leftWork; + return this; + } + + public Boolean getRightEnable() { + return rightEnable; + } + + public HsiInfoPush setRightEnable(Boolean rightEnable) { + this.rightEnable = rightEnable; + return this; + } + + public Boolean getRightWork() { + return rightWork; + } + + public HsiInfoPush setRightWork(Boolean rightWork) { + this.rightWork = rightWork; + return this; + } + + public Boolean getFrontEnable() { + return frontEnable; + } + + public HsiInfoPush setFrontEnable(Boolean frontEnable) { + this.frontEnable = frontEnable; + return this; + } + + public Boolean getFrontWork() { + return frontWork; + } + + public HsiInfoPush setFrontWork(Boolean frontWork) { + this.frontWork = frontWork; + return this; + } + + public Boolean getBackEnable() { + return backEnable; + } + + public HsiInfoPush setBackEnable(Boolean backEnable) { + this.backEnable = backEnable; + return this; + } + + public Boolean getBackWork() { + return backWork; + } + + public HsiInfoPush setBackWork(Boolean backWork) { + this.backWork = backWork; + return this; + } + + public Boolean getVerticalEnable() { + return verticalEnable; + } + + public HsiInfoPush setVerticalEnable(Boolean verticalEnable) { + this.verticalEnable = verticalEnable; + return this; + } + + public Boolean getVerticalWork() { + return verticalWork; + } + + public HsiInfoPush setVerticalWork(Boolean verticalWork) { + this.verticalWork = verticalWork; + return this; + } + + public Boolean getHorizontalEnable() { + return horizontalEnable; + } + + public HsiInfoPush setHorizontalEnable(Boolean horizontalEnable) { + this.horizontalEnable = horizontalEnable; + return this; + } + + public Boolean getHorizontalWork() { + return horizontalWork; + } + + public HsiInfoPush setHorizontalWork(Boolean horizontalWork) { + this.horizontalWork = horizontalWork; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/JoystickInvalidNotify.java b/src/main/java/com/dji/sdk/cloudapi/control/JoystickInvalidNotify.java new file mode 100644 index 0000000..29e2f79 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/JoystickInvalidNotify.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.control; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/14 + */ +public class JoystickInvalidNotify { + + private JoystickInvalidReasonEnum reason; + + public JoystickInvalidNotify() { + } + + @Override + public String toString() { + return "JoystickInvalidNotify{" + + "reason=" + reason + + '}'; + } + + public JoystickInvalidReasonEnum getReason() { + return reason; + } + + public JoystickInvalidNotify setReason(JoystickInvalidReasonEnum reason) { + this.reason = reason; + return this; + } +} diff --git a/src/main/java/com/dji/sample/control/model/enums/DrcModeReasonEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/JoystickInvalidReasonEnum.java similarity index 57% rename from src/main/java/com/dji/sample/control/model/enums/DrcModeReasonEnum.java rename to src/main/java/com/dji/sdk/cloudapi/control/JoystickInvalidReasonEnum.java index ceb20ac..190783e 100644 --- a/src/main/java/com/dji/sample/control/model/enums/DrcModeReasonEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/control/JoystickInvalidReasonEnum.java @@ -1,6 +1,8 @@ -package com.dji.sample.control.model.enums; +package com.dji.sdk.cloudapi.control; +import com.dji.sdk.exception.CloudSDKException; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; import java.util.Arrays; @@ -9,9 +11,7 @@ import java.util.Arrays; * @version 1.4 * @date 2023/3/14 */ -public enum DrcModeReasonEnum { - - UNKNOWN(-1, "unknown"), +public enum JoystickInvalidReasonEnum { RC_LOST(0, "The remote controller is lost."), @@ -23,17 +23,18 @@ public enum DrcModeReasonEnum { RC_AUTHORITY(4, "The remote controller grabs control authority."); - int val; + private final int reason; - String message; + private final String message; - DrcModeReasonEnum(int val, String message) { - this.val = val; + JoystickInvalidReasonEnum(int reason, String message) { + this.reason = reason; this.message = message; } + @JsonValue public int getVal() { - return val; + return reason; } public String getMessage() { @@ -41,7 +42,8 @@ public enum DrcModeReasonEnum { } @JsonCreator(mode = JsonCreator.Mode.DELEGATING) - public static DrcModeReasonEnum find(int val) { - return Arrays.stream(values()).filter(reasonEnum -> reasonEnum.val == val).findAny().orElse(UNKNOWN); + public static JoystickInvalidReasonEnum find(int reason) { + return Arrays.stream(values()).filter(reasonEnum -> reasonEnum.reason == reason).findAny() + .orElseThrow(() -> new CloudSDKException(JoystickInvalidReasonEnum.class, reason)); } } diff --git a/src/main/java/com/dji/sdk/cloudapi/control/LiveviewDelay.java b/src/main/java/com/dji/sdk/cloudapi/control/LiveviewDelay.java new file mode 100644 index 0000000..7e7fb1e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/LiveviewDelay.java @@ -0,0 +1,35 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.device.VideoId; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class LiveviewDelay { + + private Integer liveviewDelayTime; + + private VideoId videoId; + + public LiveviewDelay() { + } + + @Override + public String toString() { + return "LiveviewDelay{" + + "liveviewDelayTime=" + liveviewDelayTime + + ", videoId=" + videoId + + '}'; + } + + public Integer getLiveviewDelayTime() { + return liveviewDelayTime; + } + + public LiveviewDelay setLiveviewDelayTime(Integer liveviewDelayTime) { + this.liveviewDelayTime = liveviewDelayTime; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/OsdInfoPush.java b/src/main/java/com/dji/sdk/cloudapi/control/OsdInfoPush.java new file mode 100644 index 0000000..5e80741 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/OsdInfoPush.java @@ -0,0 +1,138 @@ +package com.dji.sdk.cloudapi.control; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class OsdInfoPush { + + private Float attitudeHead; + + private Float latitude; + + private Float longitude; + + private Float height; + + private Float speedX; + + private Float speedY; + + private Float speedZ; + + private Float gimbalPitch; + + private Float gimbalRoll; + + private Float gimbalYaw; + + public OsdInfoPush() { + } + + @Override + public String toString() { + return "OsdInfoPush{" + + "attitudeHead=" + attitudeHead + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + ", speedX=" + speedX + + ", speedY=" + speedY + + ", speedZ=" + speedZ + + ", gimbalPitch=" + gimbalPitch + + ", gimbalRoll=" + gimbalRoll + + ", gimbalYaw=" + gimbalYaw + + '}'; + } + + public Float getAttitudeHead() { + return attitudeHead; + } + + public OsdInfoPush setAttitudeHead(Float attitudeHead) { + this.attitudeHead = attitudeHead; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public OsdInfoPush setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public OsdInfoPush setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public OsdInfoPush setHeight(Float height) { + this.height = height; + return this; + } + + public Float getSpeedX() { + return speedX; + } + + public OsdInfoPush setSpeedX(Float speedX) { + this.speedX = speedX; + return this; + } + + public Float getSpeedY() { + return speedY; + } + + public OsdInfoPush setSpeedY(Float speedY) { + this.speedY = speedY; + return this; + } + + public Float getSpeedZ() { + return speedZ; + } + + public OsdInfoPush setSpeedZ(Float speedZ) { + this.speedZ = speedZ; + return this; + } + + public Float getGimbalPitch() { + return gimbalPitch; + } + + public OsdInfoPush setGimbalPitch(Float gimbalPitch) { + this.gimbalPitch = gimbalPitch; + return this; + } + + public Float getGimbalRoll() { + return gimbalRoll; + } + + public OsdInfoPush setGimbalRoll(Float gimbalRoll) { + this.gimbalRoll = gimbalRoll; + return this; + } + + public Float getGimbalYaw() { + return gimbalYaw; + } + + public OsdInfoPush setGimbalYaw(Float gimbalYaw) { + this.gimbalYaw = gimbalYaw; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/PayloadAuthorityGrabRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/PayloadAuthorityGrabRequest.java new file mode 100644 index 0000000..4b99053 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/PayloadAuthorityGrabRequest.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class PayloadAuthorityGrabRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + public PayloadAuthorityGrabRequest() { + } + + @Override + public String toString() { + return "PayloadAuthorityGrabRequest{" + + "payloadIndex=" + payloadIndex + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public PayloadAuthorityGrabRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/PayloadControlMethodEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/PayloadControlMethodEnum.java new file mode 100644 index 0000000..d9a14aa --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/PayloadControlMethodEnum.java @@ -0,0 +1,51 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.common.BaseModel; +import com.dji.sdk.exception.CloudSDKException; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/2 + */ +public enum PayloadControlMethodEnum { + + CAMERA_MODE_SWITCH(ControlMethodEnum.CAMERA_MODE_SWITCH, CameraModeSwitchRequest.class), + + CAMERA_PHOTO_TAKE(ControlMethodEnum.CAMERA_PHOTO_TAKE, CameraPhotoTakeRequest.class), + + CAMERA_RECORDING_START(ControlMethodEnum.CAMERA_RECORDING_START, CameraRecordingStartRequest.class), + + CAMERA_RECORDING_STOP(ControlMethodEnum.CAMERA_RECORDING_STOP, CameraRecordingStopRequest.class), + + CAMERA_AIM(ControlMethodEnum.CAMERA_AIM, CameraAimRequest.class), + + CAMERA_FOCAL_LENGTH_SET(ControlMethodEnum.CAMERA_FOCAL_LENGTH_SET, CameraFocalLengthSetRequest.class), + + GIMBAL_RESET(ControlMethodEnum.GIMBAL_RESET, GimbalResetRequest.class), + ; + + private final ControlMethodEnum payloadMethod; + + private final Class clazz; + + PayloadControlMethodEnum(ControlMethodEnum payloadMethod, Class clazz) { + this.payloadMethod = payloadMethod; + this.clazz = clazz; + } + + public ControlMethodEnum getPayloadMethod() { + return payloadMethod; + } + + public Class getClazz() { + return clazz; + } + + public static PayloadControlMethodEnum find(String method) { + return Arrays.stream(values()).filter(methodEnum -> methodEnum.payloadMethod.getMethod().equals(method)).findAny() + .orElseThrow(() -> new CloudSDKException(PayloadControlMethodEnum.class, method)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/Point.java b/src/main/java/com/dji/sdk/cloudapi/control/Point.java new file mode 100644 index 0000000..f44e76c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/Point.java @@ -0,0 +1,71 @@ +package com.dji.sdk.cloudapi.control; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/14 + */ +public class Point { + + @Min(-90) + @Max(90) + @NotNull + private Float latitude; + + @NotNull + @Min(-180) + @Max(180) + private Float longitude; + + /** + * WGS84 + * The M30 series are ellipsoidal heights. + */ + @NotNull + @Min(2) + @Max(10000) + private Float height; + + public Point() { + } + + @Override + public String toString() { + return "Point{" + + "latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + '}'; + } + + public Float getLatitude() { + return latitude; + } + + public Point setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public Point setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public Point setHeight(Float height) { + this.height = height; + return this; + } +} diff --git a/src/main/java/com/dji/sample/control/model/enums/TakeoffStatusEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/TakeoffStatusEnum.java similarity index 74% rename from src/main/java/com/dji/sample/control/model/enums/TakeoffStatusEnum.java rename to src/main/java/com/dji/sdk/cloudapi/control/TakeoffStatusEnum.java index 94ae3de..968255b 100644 --- a/src/main/java/com/dji/sample/control/model/enums/TakeoffStatusEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/control/TakeoffStatusEnum.java @@ -1,6 +1,8 @@ -package com.dji.sample.control.model.enums; +package com.dji.sdk.cloudapi.control; +import com.dji.sdk.exception.CloudSDKException; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; import java.util.Arrays; @@ -23,15 +25,16 @@ public enum TakeoffStatusEnum { TASK_FINISH("task_finish", "The drone takeoff job is completed."); - String status; + private final String status; - String message; + private final String message; TakeoffStatusEnum(String status, String message) { this.status = status; this.message = message; } + @JsonValue public String getStatus() { return status; } @@ -42,6 +45,7 @@ public enum TakeoffStatusEnum { @JsonCreator(mode = JsonCreator.Mode.DELEGATING) public static TakeoffStatusEnum find(String status) { - return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny().get(); + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(TakeoffStatusEnum.class, status)); } } diff --git a/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointProgress.java b/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointProgress.java new file mode 100644 index 0000000..008e238 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointProgress.java @@ -0,0 +1,80 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.cloudapi.wayline.WaylineErrorCodeEnum; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/14 + */ +public class TakeoffToPointProgress { + + private WaylineErrorCodeEnum result; + + private TakeoffStatusEnum status; + + private String flightId; + + private String trackId; + + private Integer wayPointIndex; + + public TakeoffToPointProgress() { + } + + @Override + public String toString() { + return "TakeoffToPointProgress{" + + "result=" + result + + ", status=" + status + + ", flightId='" + flightId + '\'' + + ", trackId='" + trackId + '\'' + + ", wayPointIndex=" + wayPointIndex + + '}'; + } + + public WaylineErrorCodeEnum getResult() { + return result; + } + + public TakeoffToPointProgress setResult(WaylineErrorCodeEnum result) { + this.result = result; + return this; + } + + public TakeoffStatusEnum getStatus() { + return status; + } + + public TakeoffToPointProgress setStatus(TakeoffStatusEnum status) { + this.status = status; + return this; + } + + public String getFlightId() { + return flightId; + } + + public TakeoffToPointProgress setFlightId(String flightId) { + this.flightId = flightId; + return this; + } + + public String getTrackId() { + return trackId; + } + + public TakeoffToPointProgress setTrackId(String trackId) { + this.trackId = trackId; + return this; + } + + public Integer getWayPointIndex() { + return wayPointIndex; + } + + public TakeoffToPointProgress setWayPointIndex(Integer wayPointIndex) { + this.wayPointIndex = wayPointIndex; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java b/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java new file mode 100644 index 0000000..2c5424e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/TakeoffToPointRequest.java @@ -0,0 +1,218 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.annotations.CloudSDKVersion; +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 javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class TakeoffToPointRequest extends BaseModel { + + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @NotNull + private String flightId; + + @Min(-180) + @Max(180) + @NotNull + private Float targetLongitude; + + @Min(-90) + @Max(90) + @NotNull + private Float targetLatitude; + + @Min(2) + @Max(10000) + @NotNull + private Float targetHeight; + + @Min(2) + @Max(1500) + @NotNull + private Float securityTakeoffHeight; + + @Min(2) + @Max(1500) + @NotNull + private Float rthAltitude; + + @NotNull + private RcLostActionEnum rcLostAction; + + @NotNull + private ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost; + + @Min(1) + @Max(15) + @NotNull + private Integer maxSpeed; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @NotNull + private RthModeEnum rthMode; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @NotNull + private CommanderModeLostActionEnum commanderModeLostAction; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @NotNull + private CommanderFlightModeEnum commanderFlightMode; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @NotNull + @Min(2) + @Max(3000) + private Float commanderFlightHeight; + + public TakeoffToPointRequest() { + } + + @Override + public String toString() { + return "TakeoffToPointRequest{" + + "flightId='" + flightId + '\'' + + ", targetLongitude=" + targetLongitude + + ", targetLatitude=" + targetLatitude + + ", targetHeight=" + targetHeight + + ", securityTakeoffHeight=" + securityTakeoffHeight + + ", rthAltitude=" + rthAltitude + + ", rcLostAction=" + rcLostAction + + ", exitWaylineWhenRcLost=" + exitWaylineWhenRcLost + + ", maxSpeed=" + maxSpeed + + ", rthMode=" + rthMode + + ", commanderModeLostAction=" + commanderModeLostAction + + ", commanderFlightMode=" + commanderFlightMode + + ", commanderFlightHeight=" + commanderFlightHeight + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public TakeoffToPointRequest setFlightId(String flightId) { + this.flightId = flightId; + return this; + } + + public Float getTargetLongitude() { + return targetLongitude; + } + + public TakeoffToPointRequest setTargetLongitude(Float targetLongitude) { + this.targetLongitude = targetLongitude; + return this; + } + + public Float getTargetLatitude() { + return targetLatitude; + } + + public TakeoffToPointRequest setTargetLatitude(Float targetLatitude) { + this.targetLatitude = targetLatitude; + return this; + } + + public Float getTargetHeight() { + return targetHeight; + } + + public TakeoffToPointRequest setTargetHeight(Float targetHeight) { + this.targetHeight = targetHeight; + return this; + } + + public Float getSecurityTakeoffHeight() { + return securityTakeoffHeight; + } + + public TakeoffToPointRequest setSecurityTakeoffHeight(Float securityTakeoffHeight) { + this.securityTakeoffHeight = securityTakeoffHeight; + return this; + } + + public Float getRthAltitude() { + return rthAltitude; + } + + public TakeoffToPointRequest setRthAltitude(Float rthAltitude) { + this.rthAltitude = rthAltitude; + return this; + } + + public RcLostActionEnum getRcLostAction() { + return rcLostAction; + } + + public TakeoffToPointRequest setRcLostAction(RcLostActionEnum rcLostAction) { + this.rcLostAction = rcLostAction; + return this; + } + + public ExitWaylineWhenRcLostEnum getExitWaylineWhenRcLost() { + return exitWaylineWhenRcLost; + } + + public TakeoffToPointRequest setExitWaylineWhenRcLost(ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost) { + this.exitWaylineWhenRcLost = exitWaylineWhenRcLost; + return this; + } + + public Integer getMaxSpeed() { + return maxSpeed; + } + + public RthModeEnum getRthMode() { + return rthMode; + } + + public TakeoffToPointRequest setRthMode(RthModeEnum rthMode) { + this.rthMode = rthMode; + return this; + } + + public CommanderModeLostActionEnum getCommanderModeLostAction() { + return commanderModeLostAction; + } + + public TakeoffToPointRequest setCommanderModeLostAction(CommanderModeLostActionEnum commanderModeLostAction) { + this.commanderModeLostAction = commanderModeLostAction; + return this; + } + + public CommanderFlightModeEnum getCommanderFlightMode() { + return commanderFlightMode; + } + + public TakeoffToPointRequest setCommanderFlightMode(CommanderFlightModeEnum commanderFlightMode) { + this.commanderFlightMode = commanderFlightMode; + return this; + } + + public Float getCommanderFlightHeight() { + return commanderFlightHeight; + } + + public TakeoffToPointRequest setCommanderFlightHeight(Float commanderFlightHeight) { + this.commanderFlightHeight = commanderFlightHeight; + return this; + } + + public TakeoffToPointRequest setMaxSpeed(Integer maxSpeed) { + this.maxSpeed = maxSpeed; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/control/ZoomCameraTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/control/ZoomCameraTypeEnum.java new file mode 100644 index 0000000..fef98dd --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/ZoomCameraTypeEnum.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.control; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public enum ZoomCameraTypeEnum { + + ZOOM("zoom"), + + IR("ir"); + + private final String type; + + ZoomCameraTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static ZoomCameraTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(ZoomCameraTypeEnum.class, type)); + } +} 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 new file mode 100644 index 0000000..8ea9e77 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/control/api/AbstractControlService.java @@ -0,0 +1,399 @@ +package com.dji.sdk.cloudapi.control.api; + +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.exception.CloudSDKException; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.drc.DrcDownPublish; +import com.dji.sdk.mqtt.drc.DrcUpData; +import com.dji.sdk.mqtt.drc.TopicDrcRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.services.ServicesPublish; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import javax.annotation.Resource; +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public abstract class AbstractControlService { + + @Resource + private ServicesPublish servicesPublish; + + @Resource + private DrcDownPublish drcDownPublish; + + /** + * Event notification of flyto result + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLY_TO_POINT_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse flyToPointProgress(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("flyToPointProgress not implemented"); + } + + /** + * Event notification of one-key taking off result + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_TAKEOFF_TO_POINT_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse takeoffToPointProgress(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("takeoffToPointProgress not implemented"); + } + + /** + * Notification of DRC link state + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_DRC_STATUS_NOTIFY, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse drcStatusNotify(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("drcStatusNotify not implemented"); + } + + /** + * Reason notification of invalid Joystick control + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_JOYSTICK_INVALID_NOTIFY, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse joystickInvalidNotify(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("joystickInvalidNotify not implemented"); + } + + /** + * Flight control authority grabbing + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flightAuthorityGrab(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.FLIGHT_AUTHORITY_GRAB.getMethod()); + } + + /** + * Payload control authority grabbing + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse payloadAuthorityGrab(GatewayManager gateway, PayloadAuthorityGrabRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.PAYLOAD_AUTHORITY_GRAB.getMethod(), + request); + } + + /** + * Enter the live flight controls mode + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse drcModeEnter(GatewayManager gateway, DrcModeEnterRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.DRC_MODE_ENTER.getMethod(), + request); + } + + /** + * Exit the live flight controls mode + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse drcModeExit(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.DRC_MODE_EXIT.getMethod()); + } + + /** + * One-key taking off + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse takeoffToPoint(GatewayManager gateway, TakeoffToPointRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.TAKEOFF_TO_POINT.getMethod(), + request); + } + + /** + * flyto target point + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flyToPoint(GatewayManager gateway, FlyToPointRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.FLY_TO_POINT.getMethod(), + request); + } + + /** + * End the task of flying to target point + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flyToPointStop(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.FLY_TO_POINT_STOP.getMethod()); + } + + /** + * Payload control - switch the camera mode + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraModeSwitch(GatewayManager gateway, CameraModeSwitchRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_MODE_SWITCH.getMethod(), + request); + } + + /** + * Payload control - take single photo + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraPhotoTake(GatewayManager gateway, CameraPhotoTakeRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_PHOTO_TAKE.getMethod(), + request); + } + + /** + * Payload control - start recording + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraRecordingStart(GatewayManager gateway, CameraRecordingStartRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_RECORDING_START.getMethod(), + request); + } + + /** + * Payload control - stop recording + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraRecordingStop(GatewayManager gateway, CameraRecordingStopRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_RECORDING_STOP.getMethod(), + request); + } + + /** + * Payload control - double tab to become AIM + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraAim(GatewayManager gateway, CameraAimRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_AIM.getMethod(), + request); + } + + /** + * Payload control - zoom + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraFocalLengthSet(GatewayManager gateway, CameraFocalLengthSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_FOCAL_LENGTH_SET.getMethod(), + request); + } + + /** + * Payload control - reset the gimbal + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse gimbalReset(GatewayManager gateway, GimbalResetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.GIMBAL_RESET.getMethod(), + request); + } + + /** + * Payload control + * @param gateway + * @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); + } + Common.validateModel(request); + return servicesPublish.publish( + gateway.getGatewaySn(), + methodEnum.getPayloadMethod().getMethod(), + request); + } + + + /** + * DRC-flight control + * @param gateway + * @param request data + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + protected void droneControlDown(GatewayManager gateway, DroneControlRequest request) { + drcDownPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.DRONE_CONTROL.getMethod(), + request); + } + + /** + * Drc up notification of drone control result + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_DRONE_CONTROL) + public void droneControlUp(TopicDrcRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("droneControlUp not implemented"); + } + + /** + * DRC-drone emergency stop + * @param gateway + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public void droneEmergencyStopDown(GatewayManager gateway) { + drcDownPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.DRONE_EMERGENCY_STOP.getMethod()); + } + + /** + * Drc up notification of drone emergency stop result + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_DRONE_EMERGENCY_STOP) + public void droneEmergencyStopUp(TopicDrcRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("droneEmergencyStopUp not implemented"); + } + + + /** + * DRC-heart beat + * @param gateway + * @param request data + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public void heartBeatDown(GatewayManager gateway, HeartBeatRequest request) { + drcDownPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.HEART_BEAT.getMethod(), + request); + } + + /** + * Drc up notification of heart beat result + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_HEART_BEAT) + public void heartBeatUp(TopicDrcRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("heartBeatUp not implemented"); + } + + /** + * DRC-obstacle avoidance information pushing + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_HSI_INFO_PUSH) + public void hsiInfoPush(TopicDrcRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("hsiInfoPush not implemented"); + } + + /** + * DRC-delay information pushing of image transmission link + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_DELAY_INFO_PUSH) + public void delayInfoPush(TopicDrcRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("delayInfoPush not implemented"); + } + + /** + * DRC-high frequency osd information pushing + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_OSD_INFO_PUSH) + public void osdInfoPush(TopicDrcRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("osdInfoPush not implemented"); + } + + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/AirConditionerModeSwitchActionEnum.java b/src/main/java/com/dji/sdk/cloudapi/debug/AirConditionerModeSwitchActionEnum.java new file mode 100644 index 0000000..f35ce91 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/AirConditionerModeSwitchActionEnum.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.debug; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/28 + */ +public enum AirConditionerModeSwitchActionEnum { + + IDLE_MODE(0), + + COOLING_MODE(1), + + heating_mode(2), + + DEHUMIDIFICATION_MODE(3); + + private final int action; + + AirConditionerModeSwitchActionEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static AirConditionerModeSwitchActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(AirConditionerModeSwitchActionEnum.class, action)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/AirConditionerModeSwitchRequest.java b/src/main/java/com/dji/sdk/cloudapi/debug/AirConditionerModeSwitchRequest.java new file mode 100644 index 0000000..78698bc --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/AirConditionerModeSwitchRequest.java @@ -0,0 +1,35 @@ +package com.dji.sdk.cloudapi.debug; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class AirConditionerModeSwitchRequest extends BaseModel { + + @NotNull + private AirConditionerModeSwitchActionEnum action; + + public AirConditionerModeSwitchRequest() { + } + + @Override + public String toString() { + return "AirConditionerModeSwitchRequest{" + + "action=" + action + + '}'; + } + + public AirConditionerModeSwitchActionEnum getAction() { + return action; + } + + public AirConditionerModeSwitchRequest setAction(AirConditionerModeSwitchActionEnum action) { + this.action = action; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/AlarmStateSwitchRequest.java b/src/main/java/com/dji/sdk/cloudapi/debug/AlarmStateSwitchRequest.java new file mode 100644 index 0000000..0f7c584 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/AlarmStateSwitchRequest.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.debug; + +import com.dji.sdk.cloudapi.device.SwitchActionEnum; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class AlarmStateSwitchRequest extends BaseModel { + + @NotNull + private SwitchActionEnum action; + + public AlarmStateSwitchRequest() { + } + + @Override + public String toString() { + return "AlarmStateSwitchRequest{" + + "action=" + action + + '}'; + } + + public SwitchActionEnum getAction() { + return action; + } + + public AlarmStateSwitchRequest setAction(SwitchActionEnum action) { + this.action = action; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/BatteryMaintenanceSwitchRequest.java b/src/main/java/com/dji/sdk/cloudapi/debug/BatteryMaintenanceSwitchRequest.java new file mode 100644 index 0000000..c25f1ca --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/BatteryMaintenanceSwitchRequest.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.debug; + +import com.dji.sdk.cloudapi.device.SwitchActionEnum; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class BatteryMaintenanceSwitchRequest extends BaseModel { + + @NotNull + private SwitchActionEnum action; + + public BatteryMaintenanceSwitchRequest() { + } + + @Override + public String toString() { + return "BatteryMaintenanceSwitchRequest{" + + "action=" + action + + '}'; + } + + public SwitchActionEnum getAction() { + return action; + } + + public BatteryMaintenanceSwitchRequest setAction(SwitchActionEnum action) { + this.action = action; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/BatteryStoreModeSwitchRequest.java b/src/main/java/com/dji/sdk/cloudapi/debug/BatteryStoreModeSwitchRequest.java new file mode 100644 index 0000000..974bbcc --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/BatteryStoreModeSwitchRequest.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.debug; + +import com.dji.sdk.cloudapi.device.BatteryStoreModeEnum; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class BatteryStoreModeSwitchRequest extends BaseModel { + + @NotNull + private BatteryStoreModeEnum action; + + public BatteryStoreModeSwitchRequest() { + } + + @Override + public String toString() { + return "BatteryStoreModeSwitchRequest{" + + "action=" + action + + '}'; + } + + public BatteryStoreModeEnum getAction() { + return action; + } + + public BatteryStoreModeSwitchRequest setAction(BatteryStoreModeEnum action) { + this.action = action; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/DebugErrorCodeEnum.java b/src/main/java/com/dji/sdk/cloudapi/debug/DebugErrorCodeEnum.java new file mode 100644 index 0000000..982de18 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/DebugErrorCodeEnum.java @@ -0,0 +1,168 @@ +package com.dji.sdk.cloudapi.debug; + +import com.dji.sdk.common.IErrorInfo; +import com.dji.sdk.mqtt.events.IEventsErrorCode; +import com.dji.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum DebugErrorCodeEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + AIRCRAFT_NO_DONGLE(326002, "The DJI Cellular module is not installed on the aircraft."), + + AIRCRAFT_DONGLE_NO_SIM(326003, "There is no SIM card installed in the DJI Cellular module of the aircraft."), + + AIRCRAFT_DONGLE_NEED_UPGRADE(326004, "The DJI Cellular module of the aircraft needs to be upgraded, otherwise it cannot be used."), + + ESTABLISH_CONNECTION_FAILED(326005, "The 4G transmission of the aircraft fails to be enabled, and the 4G transmission cannot establish a connection. Please check the 4G signal strength, or consult the operator to check the package traffic and APN settings."), + + SDR_SWITCH_FAILED(326006, "The 4G transmission switch failed, please try again later."), + + WRONG_COMMAND_FORMAT(326007, "The command format is wrong."), + + DOCK_NO_DONGLE(326008, "The DJI Cellular module is not installed on the dock."), + + DOCK_DONGLE_NO_SIM(326009, "There is no SIM card installed in the DJI Cellular module of the dock."), + + DOCK_DONGLE_NEED_UPGRADE(326010, "The DJI Cellular module of the dock needs to be upgraded, otherwise it cannot be used."), + + COMMAND_NOT_SUPPORTED(514100, "Dock error. Restart dock and try again."), + + PUSH_DRIVING_RODS_FAILED(514101, "Failed to push driving rods into place."), + + PULL_DRIVING_RODS_FAILED(514102, "Failed to pull driving rods back."), + + LOW_POWER_1(514103, "Aircraft battery level low. Unable to perform task. Wait until aircraft is charged up to 50% and try again."), + + CHARGE_FAILED(514104, "Failed to charge battery."), + + STOP_CHARGING_FAILED(514105, "Failed to stop charging battery."), + + REBOOT_DRONE_FAILED(514106, "Failed to reboot drone."), + + OPEN_DOCK_COVER_FAILED(514107, "Failed to open dock cover."), + + CLOSE_DOCK_COVER_FAILED(514108, "Failed to close dock cover."), + + POWER_ON_AIRCRAFT_FAILED(514109, "Failed to power on aircraft."), + + POWER_OFF_AIRCRAFT_FAILED(514110, "Failed to power off aircraft."), + + OPEN_SLOW_MOTION_FAILED(514111, "Propeller error in opening slow motion mode"), + + CLOSE_SLOW_MOTION_FAILED(514112, "Propeller error in closing slow motion mode"), + + AIRCRAFT_NOT_FOUND_1(514113, "Connection error between driving rod and aircraft. Check if aircraft is inside dock, driving rods are stuck, or charging connector is stained or damaged."), + + OBTAIN_BATTERY_FAILED(514114, "Failed to obtain aircraft battery status. Restart dock and try again."), + + DOCK_BUSY(514116, "Unable to perform operation. Dock is executing other command. Try again later."), + + OBTAIN_DOCK_COVER_FAILED(514117, "Dock cover is open or not fully closed. Restart dock and try again"), + + OBTAIN_DRIVING_RODS_FAILED(514118, "Driving rods pulled back or not pushed into place. Restart dock and try again."), + + TRANSMISSION_ERROR(514120, "Dock and aircraft disconnected. Restart dock and try again or relink dock and aircraft."), + + EMERGENCY_BUTTON_PRESSED_DOWN(514121, "Emergency stop button pressed down. Release button."), + + OBTAIN_CHARGING_STATUS_FAILED(514122, "Failed to obtain aircraft charging status. Restart dock and try again."), + + LOW_POWER_2(514123, "Aircraft battery level too low. Unable to power on aircraft."), + + OBTAIN_BATTERY_STATUS_FAILED(514124, "Failed to obtain aircraft battery information."), + + BATTERY_FULL(514125, "Aircraft battery level almost full. Unable to start charging. Charge battery when battery level is lower than 95%."), + + HEAVY_RAINFALL(514134, "Heavy rainfall. Unable to perform task. Try again later."), + + HIGH_WIND(514135, "Wind speed too high (≥12 m/s). Unable to perform task. Try again later."), + + POWER_SUPPLY_ERROR(514136, "Dock power supply error. Unable to perform task. Resume power supply and try again."), + + LOW_ENVIRONMENT_TEMPERATURE(514137, "Environment temperature too low (lower than -20° C). Unable to perform task. Try again later."), + + BATTERY_MAINTAINING(514138, "Maintaining aircraft battery. Unable to perform task. Wait until maintenance is complete."), + + MAINTAIN_BATTERY_FAILED(514139, "Failed to maintain aircraft battery. No maintenance required."), + + SETTING_BATTERY_STORAGE_FAILED(514140, "Failed to set battery storage mode."), + + DOCK_SYSTEM_ERROR(514141, "Dock system error. Restart dock and try again."), + + AIRCRAFT_NOT_FOUND_2(514142, "Connection error between driving rod and aircraft before takeoff. Check if aircraft is inside dock, driving rods are stuck, or charging connector is stained or damaged."), + + DRIVING_RODS_ERROR(514143, "Driving rods pulled back or not pushed into place. Try again later or restart dock and try again."), + + DOCK_COVER_ERROR(514144, "Dock cover is open or not fully closed."), + + ONSITE_DEBUGGING_MODE(514145, "Dock in onsite debugging mode. Unable to perform current operation or task."), + + REMOTE_DEBUGGING_MODE(514146, "Dock in remote debugging mode. Unable to perform task."), + + FIRMWARE_UPDATING(514147, "Updating device firmware. Unable to perform task."), + + WORKING(514148, "Task in progress. Dock unable to enter remote debugging mode or perform task again. "), + + WRONG_STATUS(514149, "The airport is not in operation mode, but an operation mode-related command has been issued."), + + RESTARTING(514150, "Restarting device."), + + UPDATING(514151, "Updating device firmware."), + + NOT_REMOTE_DEBUGGING_MODE(514153, "Dock exited remote debugging mode. Unable to perform current operation."), + + INITIALIZING(514170, "Initializing dock. Unable to perform operation. Wait until initialization completes."), + + WRONG_PARAMETER(514171, "Cloud command parameter error. Dock unable to execute command."), + + DISABLE_AC_FAILED(514180, "Failed to disable AC cooling or heating."), + + ENABLE_AC_COOLING_FAILED(514181, "Failed to enable AC cooling."), + + ENABLE_AC_HEATING_FAILED(514182, "Failed to enable AC heating."), + + ENABLE_AC_DEHUMIDIFYING_FAILED(514183, "Failed to enable AC dehumidifying."), + + LOW_TEMPERATURE(514184, "Ambient temperature below 0° C. Unable to enable AC cooling."), + + HIGH_TEMPERATURE(514185, "Ambient temperature above 45° C. Unable to enable AC heating"), + + UNKNOWN(-1, "UNKNOWN"), + + ; + + + private final String msg; + + private final int code; + + DebugErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + /** + * @param code error code + * @return enumeration object + */ + public static DebugErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/DebugMethodEnum.java b/src/main/java/com/dji/sdk/cloudapi/debug/DebugMethodEnum.java new file mode 100644 index 0000000..ec69c0f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/DebugMethodEnum.java @@ -0,0 +1,76 @@ +package com.dji.sdk.cloudapi.debug; + +import com.dji.sdk.common.BaseModel; +import com.dji.sdk.exception.CloudSDKException; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum DebugMethodEnum { + + DEBUG_MODE_OPEN("debug_mode_open", null), + + DEBUG_MODE_CLOSE("debug_mode_close", null), + + SUPPLEMENT_LIGHT_OPEN("supplement_light_open", null), + + SUPPLEMENT_LIGHT_CLOSE("supplement_light_close", null), + + DEVICE_REBOOT("device_reboot", null), + + DRONE_OPEN("drone_open", null), + + DRONE_CLOSE("drone_close", null), + + DRONE_FORMAT("drone_format", null), + + DEVICE_FORMAT("device_format", null), + + COVER_OPEN("cover_open", null), + + COVER_CLOSE("cover_close", null), + + PUTTER_OPEN("putter_open", null), + + PUTTER_CLOSE("putter_close", null), + + CHARGE_OPEN("charge_open", null), + + CHARGE_CLOSE("charge_close", null), + + BATTERY_MAINTENANCE_SWITCH("battery_maintenance_switch", BatteryMaintenanceSwitchRequest.class), + + ALARM_STATE_SWITCH("alarm_state_switch", AlarmStateSwitchRequest.class), + + BATTERY_STORE_MODE_SWITCH("battery_store_mode_switch", BatteryStoreModeSwitchRequest.class), + + SDR_WORKMODE_SWITCH("sdr_workmode_switch", SdrWorkmodeSwitchRequest.class), + + AIR_CONDITIONER_MODE_SWITCH("air_conditioner_mode_switch", AirConditionerModeSwitchRequest.class); + + private final String method; + + private final Class clazz; + + DebugMethodEnum(String method, Class clazz) { + this.method = method; + this.clazz = clazz; + } + + public String getMethod() { + return method; + } + + public Class getClazz() { + return clazz; + } + + public static DebugMethodEnum find(String method) { + return Arrays.stream(values()).filter(methodEnum -> methodEnum.method.equals(method)).findAny() + .orElseThrow(() -> new CloudSDKException(DebugMethodEnum.class, method)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugProgress.java b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugProgress.java new file mode 100644 index 0000000..f5a1b75 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugProgress.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.debug; + +/** + * @author sean + * @version 1.2 + * @date 2022/7/29 + */ +public class RemoteDebugProgress { + + private RemoteDebugStatusEnum status; + + private RemoteDebugProgressData progress; + + public RemoteDebugProgress() { + } + + @Override + public String toString() { + return "RemoteDebugProgress{" + + "status=" + status + + ", progress=" + progress + + '}'; + } + + public RemoteDebugStatusEnum getStatus() { + return status; + } + + public RemoteDebugProgress setStatus(RemoteDebugStatusEnum status) { + this.status = status; + return this; + } + + public RemoteDebugProgressData getProgress() { + return progress; + } + + public RemoteDebugProgress setProgress(RemoteDebugProgressData progress) { + this.progress = progress; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugProgressData.java b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugProgressData.java new file mode 100644 index 0000000..c512c8f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugProgressData.java @@ -0,0 +1,78 @@ +package com.dji.sdk.cloudapi.debug; + +/** + * @author sean + * @version 1.2 + * @date 2022/7/29 + */ +public class RemoteDebugProgressData { + + private Integer percent; + + private Integer currentStep; + + private Integer totalSteps; + + private RemoteDebugStepKeyEnum stepKey; + + private Integer stepResult; + + public RemoteDebugProgressData() { + } + + @Override + public String toString() { + return "RemoteDebugProgressData{" + + "percent=" + percent + + ", currentStep=" + currentStep + + ", totalSteps=" + totalSteps + + ", stepKey='" + stepKey + '\'' + + ", stepResult=" + stepResult + + '}'; + } + + public Integer getPercent() { + return percent; + } + + public RemoteDebugProgressData setPercent(Integer percent) { + this.percent = percent; + return this; + } + + public Integer getCurrentStep() { + return currentStep; + } + + public RemoteDebugProgressData setCurrentStep(Integer currentStep) { + this.currentStep = currentStep; + return this; + } + + public Integer getTotalSteps() { + return totalSteps; + } + + public RemoteDebugProgressData setTotalSteps(Integer totalSteps) { + this.totalSteps = totalSteps; + return this; + } + + public RemoteDebugStepKeyEnum getStepKey() { + return stepKey; + } + + public RemoteDebugProgressData setStepKey(RemoteDebugStepKeyEnum stepKey) { + this.stepKey = stepKey; + return this; + } + + public Integer getStepResult() { + return stepResult; + } + + public RemoteDebugProgressData setStepResult(Integer stepResult) { + this.stepResult = stepResult; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugResponse.java b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugResponse.java new file mode 100644 index 0000000..5e2f371 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugResponse.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.debug; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class RemoteDebugResponse { + + private RemoteDebugStatusEnum status; + + public RemoteDebugResponse() { + } + + @Override + public String toString() { + return "RemoteDebugResponse{" + + "status=" + status + + '}'; + } + + public RemoteDebugStatusEnum getStatus() { + return status; + } + + public RemoteDebugResponse setStatus(RemoteDebugStatusEnum status) { + this.status = status; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugStatusEnum.java b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugStatusEnum.java new file mode 100644 index 0000000..164d6af --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugStatusEnum.java @@ -0,0 +1,57 @@ +package com.dji.sdk.cloudapi.debug; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/17 + */ +public enum RemoteDebugStatusEnum { + + SENT("sent", false), + + IN_PROGRESS("in_progress", false), + + OK("ok", true), + + PAUSED("paused", false), + + REJECTED("rejected", true), + + FAILED("failed", true), + + CANCELED("canceled", true), + + TIMEOUT("timeout", true); + + private final String status; + + private final boolean end; + + RemoteDebugStatusEnum(String status, boolean end) { + this.status = status; + this.end = end; + } + + @JsonValue + public String getStatus() { + return status; + } + + public boolean isEnd() { + return end; + } + + @JsonCreator + public static RemoteDebugStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(RemoteDebugStatusEnum.class, status)); + } +} + + diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugStepKeyEnum.java b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugStepKeyEnum.java new file mode 100644 index 0000000..ddeca50 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/RemoteDebugStepKeyEnum.java @@ -0,0 +1,88 @@ +package com.dji.sdk.cloudapi.debug; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public enum RemoteDebugStepKeyEnum { + + GET_BID("get_bid", "Get bid"), + + UPGRADING_PREVENT_REBOOT("upgrading_prevent_reboot", "Check if the device is being updated"), + + CHECK_WORK_MODE("check_work_mode", "Check whether to enter remote debugging mode"), + + CHECK_TASK_STATE("check_task_state", "Check if the DJI Dock is free"), + + LAND_MCU_REBOOT("land_mcu_reboot", "Land MCU reboot"), + + RAIN_MCU_REBOOT("rain_mcu_reboot", "Weather station MCU reboot"), + + CORE_MCU_REBOOT("core_mcu_reboot", "Central control MCU reboot"), + + SDR_REBOOT("sdr_reboot", "SDR reboot"), + + WRITE_REBOOT_PARAM_FILE("write_reboot_param_file", "Write reboot flag"), + + GET_DRONE_POWER_STATE("get_drone_power_state", "Get battery charge state"), + + CLOSE_PUTTER("close_putter", "Close the putter"), + + CHECK_WIRED_CONNECT_STATE("check_wired_connect_state", "Get aircraft state"), + + OPEN_DRONE("open_drone", "Open the plane"), + + OPEN_ALARM("open_alarm", "Open sound and light alarm"), + + CHECK_SCRAM_STATE("check_scram_state", "Check if the emergency stop switch is pressed"), + + OPEN_COVER("open_cover", "Open the hatch"), + + CHECK_DRONE_SDR_CONNECT_STATE("check_drone_sdr_connect_state", "Establish SDR wireless connection"), + + TURN_ON_DRONE("turn_on_drone", "Turn the plane on"), + + DRONE_PADDLE_FORWARD("drone_paddle_forward", "Turn on forward paddle"), + + CLOSE_COVER("close_cover", "Close the hatch"), + + DRONE_PADDLE_REVERSE("drone_paddle_reverse", "Turn on reverse paddle"), + + DRONE_PADDLE_STOP("drone_paddle_stop", "Stop Paddle Rotation"), + + FREE_PUTTER("free_putter", "Free Putter"), + + STOP_CHARGE("stop_charge", "Stop charging"); + + private final String stepKey; + + private final String message; + + RemoteDebugStepKeyEnum(String stepKey, String message) { + this.stepKey = stepKey; + this.message = message; + } + + @JsonValue + public String getStepKey() { + return stepKey; + } + + public String getMessage() { + return message; + } + + @JsonCreator + public static RemoteDebugStepKeyEnum find(String stepKey) { + return Arrays.stream(values()).filter(stepKeyEnum -> stepKeyEnum.stepKey.equals(stepKey)).findAny() + .orElseThrow(() -> new CloudSDKException(RemoteDebugStepKeyEnum.class,stepKey)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/debug/SdrWorkmodeSwitchRequest.java b/src/main/java/com/dji/sdk/cloudapi/debug/SdrWorkmodeSwitchRequest.java new file mode 100644 index 0000000..2298a28 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/SdrWorkmodeSwitchRequest.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.debug; + +import com.dji.sdk.cloudapi.device.LinkWorkModeEnum; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class SdrWorkmodeSwitchRequest extends BaseModel { + + @NotNull + private LinkWorkModeEnum linkWorkmode; + + public SdrWorkmodeSwitchRequest() { + } + + @Override + public String toString() { + return "SdrWorkmodeSwitchRequest{" + + "linkWorkmode=" + linkWorkmode + + '}'; + } + + public LinkWorkModeEnum getLinkWorkmode() { + return linkWorkmode; + } + + public SdrWorkmodeSwitchRequest setLinkWorkmode(LinkWorkModeEnum linkWorkmode) { + this.linkWorkmode = linkWorkmode; + return this; + } +} 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 new file mode 100644 index 0000000..1d3e6a1 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/debug/api/AbstractDebugService.java @@ -0,0 +1,340 @@ +package com.dji.sdk.cloudapi.debug.api; + +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.exception.CloudSDKException; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.services.ServicesPublish; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import com.fasterxml.jackson.core.type.TypeReference; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import javax.annotation.Resource; +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public abstract class AbstractDebugService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Open the debug mode + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> debugModeOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DEBUG_MODE_OPEN.getMethod()); + } + + /** + * Close the debug mode + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> debugModeClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DEBUG_MODE_CLOSE.getMethod()); + } + + /** + * Open the supplement light + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> supplementLightOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.SUPPLEMENT_LIGHT_OPEN.getMethod()); + } + + /** + * Close the supplement light + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> supplementLightClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.SUPPLEMENT_LIGHT_CLOSE.getMethod()); + } + + /** + * Maintenance state switch of battery + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> batteryMaintenanceSwitch(GatewayManager gateway, BatteryMaintenanceSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.BATTERY_MAINTENANCE_SWITCH.getMethod(), + request); + } + + /** + * Air conditioner working mode switch of dock + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> airConditionerModeSwitch(GatewayManager gateway, AirConditionerModeSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.AIR_CONDITIONER_MODE_SWITCH.getMethod(), + request); + } + + /** + * Sound and light alarm switch of dock + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> alarmStateSwitch(GatewayManager gateway, AlarmStateSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.AIR_CONDITIONER_MODE_SWITCH.getMethod(), + request); + } + + /** + * Battery storage mode switch of dock + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> batteryStoreModeSwitch(GatewayManager gateway, BatteryStoreModeSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.BATTERY_STORE_MODE_SWITCH.getMethod(), + request); + } + + /** + * Reboot the dock + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> deviceReboot(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DEVICE_REBOOT.getMethod()); + } + + /** + * Power on the aircraft + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> droneOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DRONE_OPEN.getMethod()); + } + + /** + * Power off the aircraft + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> droneClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DRONE_CLOSE.getMethod()); + } + + /** + * Format the dock data + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> deviceFormat(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DEVICE_FORMAT.getMethod()); + } + + /** + * Format the aircraft data + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> droneFormat(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DRONE_FORMAT.getMethod()); + } + + /** + * Open the dock cover + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> coverOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.COVER_OPEN.getMethod()); + } + + /** + * Close the dock cover + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> coverClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.COVER_CLOSE.getMethod()); + } + + /** + * Open the putter + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> putterOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.PUTTER_OPEN.getMethod()); + } + + /** + * Close the putter + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> putterClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.PUTTER_CLOSE.getMethod()); + } + + /** + * Turn on charging + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> chargeOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.CHARGE_OPEN.getMethod()); + } + + /** + * Turn off charging + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> chargeClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.CHARGE_CLOSE.getMethod()); + } + + /** + * Switch of 4G enhancement mode + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> sdrWorkmodeSwitch(GatewayManager gateway, SdrWorkmodeSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.SDR_WORKMODE_SWITCH.getMethod(), + request); + } + + /** + * Common interface for remote debugging + * @param gateway + * @param methodEnum + * @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); + } + Common.validateModel(request); + } + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + methodEnum.getMethod(), + request); + } + + /** + * Inform of remote debug progress + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse remoteDebugProgress(TopicEventsRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("remoteDebugProgress not implemented"); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/AirConditioner.java b/src/main/java/com/dji/sdk/cloudapi/device/AirConditioner.java new file mode 100644 index 0000000..7be54b4 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/AirConditioner.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AirConditioner { + + private AirConditionerStateEnum airConditionerState; + + private Integer switchTime; + + public AirConditioner() { + } + + @Override + public String toString() { + return "AirConditioner{" + + "airConditionerState=" + airConditionerState + + ", switchTime=" + switchTime + + '}'; + } + + public AirConditionerStateEnum getAirConditionerState() { + return airConditionerState; + } + + public AirConditioner setAirConditionerState(AirConditionerStateEnum airConditionerState) { + this.airConditionerState = airConditionerState; + return this; + } + + public Integer getSwitchTime() { + return switchTime; + } + + public AirConditioner setSwitchTime(Integer switchTime) { + this.switchTime = switchTime; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/AirConditionerStateEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/AirConditionerStateEnum.java new file mode 100644 index 0000000..f58728f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/AirConditionerStateEnum.java @@ -0,0 +1,56 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum AirConditionerStateEnum { + + IDLE(0), + + COOL(1), + + HEAT(2), + + DEHUMIDIFICATION(3), + + COOLING_EXIT(4), + + HEATING_EXIT(5), + + DEHUMIDIFICATION_EXIT(6), + + COOLING_PREPARATION(7), + + HEATING_PREPARATION(8), + + DEHUMIDIFICATION_PREPARATION(9), + + DISCONNECTED(32767), + ; + + private final int state; + + AirConditionerStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static AirConditionerStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(AirConditionerStateEnum.class, state)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/AlternateLandPoint.java b/src/main/java/com/dji/sdk/cloudapi/device/AlternateLandPoint.java new file mode 100644 index 0000000..8b1e144 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/AlternateLandPoint.java @@ -0,0 +1,69 @@ +package com.dji.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/11 + */ +public class AlternateLandPoint { + + private Float latitude; + + private Float longitude; + + private Float safeLandHeight; + + @JsonProperty("is_configured") + private Boolean configured; + + public AlternateLandPoint() { + } + + @Override + public String toString() { + return "AlternateLandPoint{" + + "latitude=" + latitude + + ", longitude=" + longitude + + ", safeLandHeight=" + safeLandHeight + + ", configured=" + configured + + '}'; + } + + public Float getLatitude() { + return latitude; + } + + public AlternateLandPoint setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public AlternateLandPoint setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getSafeLandHeight() { + return safeLandHeight; + } + + public AlternateLandPoint setSafeLandHeight(Float safeLandHeight) { + this.safeLandHeight = safeLandHeight; + return this; + } + + public Boolean getConfigured() { + return configured; + } + + public AlternateLandPoint setConfigured(Boolean configured) { + this.configured = configured; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/BackupBattery.java b/src/main/java/com/dji/sdk/cloudapi/device/BackupBattery.java new file mode 100644 index 0000000..0b3e753 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/BackupBattery.java @@ -0,0 +1,57 @@ +package com.dji.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/3 + */ +public class BackupBattery { + + private Integer voltage; + + private Float temperature; + + @JsonProperty("switch") + private Boolean batterySwitch; + + public BackupBattery() { + } + + @Override + public String toString() { + return "BackupBattery{" + + "voltage=" + voltage + + ", temperature=" + temperature + + ", batterySwitch=" + batterySwitch + + '}'; + } + + public Integer getVoltage() { + return voltage; + } + + public BackupBattery setVoltage(Integer voltage) { + this.voltage = voltage; + return this; + } + + public Float getTemperature() { + return temperature; + } + + public BackupBattery setTemperature(Float temperature) { + this.temperature = temperature; + return this; + } + + public Boolean getBatterySwitch() { + return batterySwitch; + } + + public BackupBattery setBatterySwitch(Boolean batterySwitch) { + this.batterySwitch = batterySwitch; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/Battery.java b/src/main/java/com/dji/sdk/cloudapi/device/Battery.java new file mode 100644 index 0000000..15e51bd --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/Battery.java @@ -0,0 +1,138 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/24 + */ +public class Battery { + + private String firmwareVersion; + + private BatteryIndexEnum index; + + private Integer loopTimes; + + private Integer capacityPercent; + + private String sn; + + private Integer subType; + + private Float temperature; + + private Integer type; + + private Integer voltage; + + private Integer highVoltageStorageDays; + + public Battery() { + } + + @Override + public String toString() { + return "Battery{" + + "firmwareVersion='" + firmwareVersion + '\'' + + ", index=" + index + + ", loopTimes=" + loopTimes + + ", capacityPercent=" + capacityPercent + + ", sn='" + sn + '\'' + + ", subType=" + subType + + ", temperature=" + temperature + + ", type=" + type + + ", voltage=" + voltage + + ", highVoltageStorageDays=" + highVoltageStorageDays + + '}'; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public Battery setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } + + public BatteryIndexEnum getIndex() { + return index; + } + + public Battery setIndex(BatteryIndexEnum index) { + this.index = index; + return this; + } + + public Integer getLoopTimes() { + return loopTimes; + } + + public Battery setLoopTimes(Integer loopTimes) { + this.loopTimes = loopTimes; + return this; + } + + public Integer getCapacityPercent() { + return capacityPercent; + } + + public Battery setCapacityPercent(Integer capacityPercent) { + this.capacityPercent = capacityPercent; + return this; + } + + public String getSn() { + return sn; + } + + public Battery setSn(String sn) { + this.sn = sn; + return this; + } + + public Integer getSubType() { + return subType; + } + + public Battery setSubType(Integer subType) { + this.subType = subType; + return this; + } + + public Float getTemperature() { + return temperature; + } + + public Battery setTemperature(Float temperature) { + this.temperature = temperature; + return this; + } + + public Integer getType() { + return type; + } + + public Battery setType(Integer type) { + this.type = type; + return this; + } + + public Integer getVoltage() { + return voltage; + } + + public Battery setVoltage(Integer voltage) { + this.voltage = voltage; + return this; + } + + public Integer getHighVoltageStorageDays() { + return highVoltageStorageDays; + } + + public Battery setHighVoltageStorageDays(Integer highVoltageStorageDays) { + this.highVoltageStorageDays = highVoltageStorageDays; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/BatteryIndexEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/BatteryIndexEnum.java new file mode 100644 index 0000000..073c20f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/BatteryIndexEnum.java @@ -0,0 +1,37 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum BatteryIndexEnum { + + LEFT(0), + + RIGHT(1); + + private final int index; + + BatteryIndexEnum(int index) { + this.index = index; + } + + @JsonValue + public int getIndex() { + return index; + } + + @JsonCreator + public static BatteryIndexEnum find(int index) { + return Arrays.stream(values()).filter(indexEnum -> indexEnum.index == index).findAny() + .orElseThrow(() -> new CloudSDKException(BatteryIndexEnum.class, index)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/BatteryStoreModeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/BatteryStoreModeEnum.java new file mode 100644 index 0000000..f60590b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/BatteryStoreModeEnum.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum BatteryStoreModeEnum { + + PLAN(1), + + EMERGENCY(2); + + private final int mode; + + BatteryStoreModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static BatteryStoreModeEnum find(int mode) { + return Arrays.stream(BatteryStoreModeEnum.values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(BatteryStoreModeEnum.class, mode)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/CameraModeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/CameraModeEnum.java new file mode 100644 index 0000000..3f82d43 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/CameraModeEnum.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public enum CameraModeEnum { + + PHOTO(0), + + VIDEO(1); + + private final int mode; + + CameraModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static CameraModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(CameraModeEnum.class, mode)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/CameraStateEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/CameraStateEnum.java new file mode 100644 index 0000000..b0adf26 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/CameraStateEnum.java @@ -0,0 +1,37 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/23 + */ +public enum CameraStateEnum { + + IDLE(0), + + WORKING(1), + ; + + private final int state; + + CameraStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static CameraStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(CameraStateEnum.class, state)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/ControlSourceEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/ControlSourceEnum.java new file mode 100644 index 0000000..d2d7793 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/ControlSourceEnum.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/16 + */ +public enum ControlSourceEnum { + + A("A"), + + B("B"), + + UNKNOWN(""); + + private final String controlSource; + + ControlSourceEnum(String controlSource) { + this.controlSource = controlSource; + } + + @JsonValue + public String getControlSource() { + return controlSource; + } + + @JsonCreator + public static ControlSourceEnum find(String controlSource) { + return Arrays.stream(values()).filter(controlSourceEnum -> controlSourceEnum.controlSource.equals(controlSource)).findAny() + .orElseThrow(() -> new CloudSDKException(ControlSourceEnum.class, controlSource)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/CoverStateEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/CoverStateEnum.java new file mode 100644 index 0000000..a7cc62f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/CoverStateEnum.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum CoverStateEnum { + + CLOSED(0), + + OPENED(1), + + HALF_OPEN(2), + + ABNORMAL(3), + ; + + private final int state; + + CoverStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static CoverStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(CoverStateEnum.class, state)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DeviceDomainEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/DeviceDomainEnum.java new file mode 100644 index 0000000..ff94533 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DeviceDomainEnum.java @@ -0,0 +1,43 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +@Schema(description = "device domain", enumAsRef = true) +public enum DeviceDomainEnum { + + DRONE(0), + + PAYLOAD(1), + + REMOTER_CONTROL(2), + + DOCK (3); + + private final int domain; + + DeviceDomainEnum(int domain) { + this.domain = domain; + } + + @JsonCreator + public static DeviceDomainEnum find(int domain) { + return Arrays.stream(values()).filter(domainEnum -> domainEnum.domain == domain).findAny() + .orElseThrow(() -> new CloudSDKException(DeviceDomainEnum.class, domain)); + } + + @JsonValue + public int getDomain() { + return domain; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DeviceEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/DeviceEnum.java new file mode 100644 index 0000000..0009374 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DeviceEnum.java @@ -0,0 +1,121 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +@Schema(description = "device model key.", format = "domain-type-subType", enumAsRef = true, example = "0-89-0") +public enum DeviceEnum { + + M350(DeviceDomainEnum.DRONE, DeviceTypeEnum.M350, DeviceSubTypeEnum.ZERO), + + M300(DeviceDomainEnum.DRONE, DeviceTypeEnum.M300, DeviceSubTypeEnum.ZERO), + + M30(DeviceDomainEnum.DRONE, DeviceTypeEnum.M30, DeviceSubTypeEnum.ZERO), + + M30T(DeviceDomainEnum.DRONE, DeviceTypeEnum.M30, DeviceSubTypeEnum.ONE), + + M3E(DeviceDomainEnum.DRONE, DeviceTypeEnum.M3E, DeviceSubTypeEnum.ZERO), + + M3T(DeviceDomainEnum.DRONE, DeviceTypeEnum.M3E, DeviceSubTypeEnum.ONE), + + M3M(DeviceDomainEnum.DRONE, DeviceTypeEnum.M3E, DeviceSubTypeEnum.TWO), + + Z30(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.Z30, DeviceSubTypeEnum.ZERO), + + XT2(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.XT2, DeviceSubTypeEnum.ZERO), + + FPV(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.FPV, DeviceSubTypeEnum.ZERO), + + XTS(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.XTS, DeviceSubTypeEnum.ZERO), + + H20(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.H20, DeviceSubTypeEnum.ZERO), + + H20T(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.H20T, DeviceSubTypeEnum.ZERO), + + P1(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.P1, DeviceSubTypeEnum._65535), + + M30_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M30_CAMERA, DeviceSubTypeEnum.ZERO), + + M30T_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M30T_CAMERA, DeviceSubTypeEnum.ZERO), + + H20N(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.H20N, DeviceSubTypeEnum.ZERO), + + DOCK_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.DOCK_CAMERA, DeviceSubTypeEnum.ZERO), + + L1(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.L1, DeviceSubTypeEnum.ZERO), + + M3E_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M3E_CAMERA, DeviceSubTypeEnum.ZERO), + + M3T_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M3T_CAMERA, DeviceSubTypeEnum.ZERO), + + M3M_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M3M_CAMERA, DeviceSubTypeEnum.ZERO), + + RC(DeviceDomainEnum.REMOTER_CONTROL, DeviceTypeEnum.RC, DeviceSubTypeEnum.ZERO), + + RC_PLUS(DeviceDomainEnum.REMOTER_CONTROL, DeviceTypeEnum.RC_PLUS, DeviceSubTypeEnum.ZERO), + + RC_PRO(DeviceDomainEnum.REMOTER_CONTROL, DeviceTypeEnum.RC_PRO, DeviceSubTypeEnum.ZERO), + + DOCK(DeviceDomainEnum.DOCK, DeviceTypeEnum.DOCK, DeviceSubTypeEnum.ZERO), + ; + + @Schema(enumAsRef = true) + private final DeviceDomainEnum domain; + + @Schema(enumAsRef = true) + private final DeviceTypeEnum type; + + @Schema(enumAsRef = true) + private final DeviceSubTypeEnum subType; + + DeviceEnum(DeviceDomainEnum domain, DeviceTypeEnum type, DeviceSubTypeEnum subType) { + this.domain = domain; + this.type = type; + this.subType = subType; + } + + public DeviceDomainEnum getDomain() { + return domain; + } + + public DeviceTypeEnum getType() { + return type; + } + + public DeviceSubTypeEnum getSubType() { + return subType; + } + + @JsonValue + public String getDevice() { + return String.format("%s-%s-%s", domain.getDomain(), type.getType(), subType.getSubType()); + } + + public static DeviceEnum find(DeviceDomainEnum domain, DeviceTypeEnum type, DeviceSubTypeEnum subType) { + return Arrays.stream(values()).filter(device -> device.domain == domain && device.type == type && device.subType == subType) + .findAny().orElseThrow(() -> new CloudSDKException(DeviceEnum.class, + String.format("%s-%s-%s", domain.getDomain(), type.getType(), subType.getSubType()))); + } + + public static DeviceEnum find(int domain, int type, int subType) { + return Arrays.stream(values()).filter(device -> device.domain.getDomain() == domain && + device.type.getType() == type && device.subType.getSubType() == subType) + .findAny().orElseThrow(() -> new CloudSDKException(DeviceEnum.class, + String.format("%s-%s-%s", domain, type, subType))); + } + + @JsonCreator + public static DeviceEnum find(String key) { + return Arrays.stream(values()).filter(device -> device.getDevice().equals(key)) + .findAny().orElseThrow(() -> new CloudSDKException(DeviceEnum.class, key)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DeviceModelEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/DeviceModelEnum.java new file mode 100644 index 0000000..2049b88 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DeviceModelEnum.java @@ -0,0 +1,11 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/29 + */ +public enum DeviceModelEnum { + + RC, DOCK, DRONE; +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DeviceOsdHost.java b/src/main/java/com/dji/sdk/cloudapi/device/DeviceOsdHost.java new file mode 100644 index 0000000..f540f48 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DeviceOsdHost.java @@ -0,0 +1,124 @@ +package com.dji.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +public class DeviceOsdHost { + + @Schema(description = "device latitude") + @NotNull + private Float latitude; + + @Schema(description = "device longitude") + @NotNull + private Float longitude; + + @Schema(description = "device ellipsoid height") + @NotNull + private Float height; + + @Schema(description = "device head facing angle") + @NotNull + @JsonProperty("attitude_head") + private Float attitudeHead; + + @Schema(description = "height relative to the takeoff point") + @NotNull + private Float elevation; + + @Schema(description = "horizontal speed") + @NotNull + @JsonProperty("horizontal_speed") + private Float horizontalSpeed; + + @Schema(description = "vertical speed") + @NotNull + @JsonProperty("vertical_speed") + private Float verticalSpeed; + + public DeviceOsdHost() { + } + + @Override + public String toString() { + return "DeviceOsdHost{" + + "latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + ", attitudeHead=" + attitudeHead + + ", elevation=" + elevation + + ", horizontalSpeed=" + horizontalSpeed + + ", verticalSpeed=" + verticalSpeed + + '}'; + } + + public Float getLatitude() { + return latitude; + } + + public DeviceOsdHost setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public DeviceOsdHost setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public DeviceOsdHost setHeight(Float height) { + this.height = height; + return this; + } + + public Float getAttitudeHead() { + return attitudeHead; + } + + public DeviceOsdHost setAttitudeHead(Float attitudeHead) { + this.attitudeHead = attitudeHead; + return this; + } + + public Float getElevation() { + return elevation; + } + + public DeviceOsdHost setElevation(Float elevation) { + this.elevation = elevation; + return this; + } + + public Float getHorizontalSpeed() { + return horizontalSpeed; + } + + public DeviceOsdHost setHorizontalSpeed(Float horizontalSpeed) { + this.horizontalSpeed = horizontalSpeed; + return this; + } + + public Float getVerticalSpeed() { + return verticalSpeed; + } + + public DeviceOsdHost setVerticalSpeed(Float verticalSpeed) { + this.verticalSpeed = verticalSpeed; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DeviceOsdWsResponse.java b/src/main/java/com/dji/sdk/cloudapi/device/DeviceOsdWsResponse.java new file mode 100644 index 0000000..57e17f5 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DeviceOsdWsResponse.java @@ -0,0 +1,53 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.common.BaseModel; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Schema(name = "DeviceOsdWsResponse", description = "BizCode: device_osd.

Websocket response data when device topology changes.

") +public class DeviceOsdWsResponse extends BaseModel { + + @NotNull + @Schema(description = "drone sn", example = "1AD3CA2VL3LAD6") + private String sn; + + @NotNull + @Valid + private DeviceOsdHost host; + + public DeviceOsdWsResponse() { + } + + @Override + public String toString() { + return "DeviceOsdWsResponse{" + + "sn='" + sn + '\'' + + ", host=" + host + + '}'; + } + + public String getSn() { + return sn; + } + + public DeviceOsdWsResponse setSn(String sn) { + this.sn = sn; + return this; + } + + public DeviceOsdHost getHost() { + return host; + } + + public DeviceOsdWsResponse setHost(DeviceOsdHost host) { + this.host = host; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DeviceSubTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/DeviceSubTypeEnum.java new file mode 100644 index 0000000..04d7cfe --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DeviceSubTypeEnum.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/26 + */ +@Schema(description = "device subType", enumAsRef = true) +public enum DeviceSubTypeEnum { + + ZERO(0), + + ONE(1), + + TWO(2), + + _65535(65535); + + private final int subType; + + DeviceSubTypeEnum(int subType) { + this.subType = subType; + } + + @JsonValue + public int getSubType() { + return subType; + } + + @JsonCreator + public static DeviceSubTypeEnum find(int subType) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.subType == subType).findAny() + .orElseThrow(() -> new CloudSDKException(DeviceSubTypeEnum.class, subType)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DeviceTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/DeviceTypeEnum.java new file mode 100644 index 0000000..a4b5520 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DeviceTypeEnum.java @@ -0,0 +1,81 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/26 + */ +@Schema(description = "device type", enumAsRef = true) +public enum DeviceTypeEnum { + + M350(89), + + M300(60), + + M30(67), + + M3E(77), + + Z30(20), + + XT2(26), + + FPV(39), + + XTS(41), + + H20(42), + + H20T(43), + + P1(50), + + M30_CAMERA(52), + + M30T_CAMERA(53), + + H20N(61), + + DOCK_CAMERA(165), + + L1(90742), + + M3E_CAMERA(66), + + M3T_CAMERA(67), + + M3M_CAMERA(68), + + RC(56), + + RC_PLUS(119), + + RC_PRO(144), + + DOCK(1) + ; + + private final int type; + + DeviceTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static DeviceTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(DeviceTypeEnum.class, type)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockDistanceLimitStatus.java b/src/main/java/com/dji/sdk/cloudapi/device/DockDistanceLimitStatus.java new file mode 100644 index 0000000..e53ee8e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockDistanceLimitStatus.java @@ -0,0 +1,58 @@ +package com.dji.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * The state of the drone's limited distance + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class DockDistanceLimitStatus { + + private SwitchActionEnum state; + + private Integer distanceLimit; + + @JsonProperty("is_near_distance_limit") + private Boolean nearDistanceLimit; + + public DockDistanceLimitStatus() { + } + + @Override + public String toString() { + return "DockDistanceLimitStatusSet{" + + "state=" + state + + ", distanceLimit=" + distanceLimit + + ", nearDistanceLimit=" + nearDistanceLimit + + '}'; + } + + public SwitchActionEnum getState() { + return state; + } + + public DockDistanceLimitStatus setState(SwitchActionEnum state) { + this.state = state; + return this; + } + + public Integer getDistanceLimit() { + return distanceLimit; + } + + public DockDistanceLimitStatus setDistanceLimit(Integer distanceLimit) { + this.distanceLimit = distanceLimit; + return this; + } + + public Boolean getNearDistanceLimit() { + return nearDistanceLimit; + } + + public DockDistanceLimitStatus setNearDistanceLimit(Boolean nearDistanceLimit) { + this.nearDistanceLimit = nearDistanceLimit; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockDroneControlSource.java b/src/main/java/com/dji/sdk/cloudapi/device/DockDroneControlSource.java new file mode 100644 index 0000000..1b12a6c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockDroneControlSource.java @@ -0,0 +1,116 @@ +package com.dji.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class DockDroneControlSource { + + private ControlSourceEnum controlSource; + + private Float homeLatitude; + + private Float homeLongitude; + + private Integer lowBatteryWarningThreshold; + + private Integer seriousLowBatteryWarningThreshold; + + private List payloads; + + private Boolean locked; + + private ModeCodeReasonEnum modeCodeReason; + + public DockDroneControlSource() { + } + + @Override + public String toString() { + return "DockDroneControlSource{" + + "controlSource=" + controlSource + + ", homeLatitude=" + homeLatitude + + ", homeLongitude=" + homeLongitude + + ", lowBatteryWarningThreshold=" + lowBatteryWarningThreshold + + ", seriousLowBatteryWarningThreshold=" + seriousLowBatteryWarningThreshold + + ", payloads=" + payloads + + ", locked=" + locked + + ", modeCodeReason=" + modeCodeReason + + '}'; + } + + public ControlSourceEnum getControlSource() { + return controlSource; + } + + public DockDroneControlSource setControlSource(ControlSourceEnum controlSource) { + this.controlSource = controlSource; + return this; + } + + public Float getHomeLatitude() { + return homeLatitude; + } + + public DockDroneControlSource setHomeLatitude(Float homeLatitude) { + this.homeLatitude = homeLatitude; + return this; + } + + public Float getHomeLongitude() { + return homeLongitude; + } + + public DockDroneControlSource setHomeLongitude(Float homeLongitude) { + this.homeLongitude = homeLongitude; + return this; + } + + public Integer getLowBatteryWarningThreshold() { + return lowBatteryWarningThreshold; + } + + public DockDroneControlSource setLowBatteryWarningThreshold(Integer lowBatteryWarningThreshold) { + this.lowBatteryWarningThreshold = lowBatteryWarningThreshold; + return this; + } + + public Integer getSeriousLowBatteryWarningThreshold() { + return seriousLowBatteryWarningThreshold; + } + + public DockDroneControlSource setSeriousLowBatteryWarningThreshold(Integer seriousLowBatteryWarningThreshold) { + this.seriousLowBatteryWarningThreshold = seriousLowBatteryWarningThreshold; + return this; + } + + public List getPayloads() { + return payloads; + } + + public DockDroneControlSource setPayloads(List payloads) { + this.payloads = payloads; + return this; + } + + public Boolean getLocked() { + return locked; + } + + public DockDroneControlSource setLocked(Boolean locked) { + this.locked = locked; + return this; + } + + public ModeCodeReasonEnum getModeCodeReason() { + return modeCodeReason; + } + + public DockDroneControlSource setModeCodeReason(ModeCodeReasonEnum modeCodeReason) { + this.modeCodeReason = modeCodeReason; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockDronePayload.java b/src/main/java/com/dji/sdk/cloudapi/device/DockDronePayload.java new file mode 100644 index 0000000..8351aa1 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockDronePayload.java @@ -0,0 +1,236 @@ +package com.dji.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/6 + */ +public class DockDronePayload { + + private PayloadIndex payloadIndex; + + private Float gimbalPitch; + + private Float gimbalRoll; + + private Float gimbalYaw; + + private Float measureTargetAltitude; + + private Float measureTargetDistance; + + private Float measureTargetLatitude; + + private Float measureTargetLongitude; + + private MeasureTargetStateEnum measureTargetErrorState; + + private Integer version; + + private ThermalPaletteStyleEnum thermalCurrentPaletteStyle; + + private ThermalGainModeEnum thermalGainMode; + + private Float thermalGlobalTemperatureMax; + + private Float thermalGlobalTemperatureMin; + + private Integer thermalIsothermLowerLimit; + + private SwitchActionEnum thermalIsothermState; + + private Integer thermalIsothermUpperLimit; + + private List smartTrackPoint; + + public DockDronePayload() { + } + + @Override + public String toString() { + return "DockDronePayload{" + + "payloadIndex=" + payloadIndex + + ", gimbalPitch=" + gimbalPitch + + ", gimbalRoll=" + gimbalRoll + + ", gimbalYaw=" + gimbalYaw + + ", measureTargetAltitude=" + measureTargetAltitude + + ", measureTargetDistance=" + measureTargetDistance + + ", measureTargetLatitude=" + measureTargetLatitude + + ", measureTargetLongitude=" + measureTargetLongitude + + ", measureTargetErrorState=" + measureTargetErrorState + + ", version=" + version + + ", thermalCurrentPaletteStyle=" + thermalCurrentPaletteStyle + + ", thermalGainMode=" + thermalGainMode + + ", thermalGlobalTemperatureMax=" + thermalGlobalTemperatureMax + + ", thermalGlobalTemperatureMin=" + thermalGlobalTemperatureMin + + ", thermalIsothermLowerLimit=" + thermalIsothermLowerLimit + + ", thermalIsothermState=" + thermalIsothermState + + ", thermalIsothermUpperLimit=" + thermalIsothermUpperLimit + + ", smartTrackPoint=" + smartTrackPoint + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public DockDronePayload setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public Float getGimbalPitch() { + return gimbalPitch; + } + + public DockDronePayload setGimbalPitch(Float gimbalPitch) { + this.gimbalPitch = gimbalPitch; + return this; + } + + public Float getGimbalRoll() { + return gimbalRoll; + } + + public DockDronePayload setGimbalRoll(Float gimbalRoll) { + this.gimbalRoll = gimbalRoll; + return this; + } + + public Float getGimbalYaw() { + return gimbalYaw; + } + + public DockDronePayload setGimbalYaw(Float gimbalYaw) { + this.gimbalYaw = gimbalYaw; + return this; + } + + public Float getMeasureTargetAltitude() { + return measureTargetAltitude; + } + + public DockDronePayload setMeasureTargetAltitude(Float measureTargetAltitude) { + this.measureTargetAltitude = measureTargetAltitude; + return this; + } + + public Float getMeasureTargetDistance() { + return measureTargetDistance; + } + + public DockDronePayload setMeasureTargetDistance(Float measureTargetDistance) { + this.measureTargetDistance = measureTargetDistance; + return this; + } + + public Float getMeasureTargetLatitude() { + return measureTargetLatitude; + } + + public DockDronePayload setMeasureTargetLatitude(Float measureTargetLatitude) { + this.measureTargetLatitude = measureTargetLatitude; + return this; + } + + public Float getMeasureTargetLongitude() { + return measureTargetLongitude; + } + + public DockDronePayload setMeasureTargetLongitude(Float measureTargetLongitude) { + this.measureTargetLongitude = measureTargetLongitude; + return this; + } + + public MeasureTargetStateEnum getMeasureTargetErrorState() { + return measureTargetErrorState; + } + + public DockDronePayload setMeasureTargetErrorState(MeasureTargetStateEnum measureTargetErrorState) { + this.measureTargetErrorState = measureTargetErrorState; + return this; + } + + public Integer getVersion() { + return version; + } + + public DockDronePayload setVersion(Integer version) { + this.version = version; + return this; + } + + public ThermalPaletteStyleEnum getThermalCurrentPaletteStyle() { + return thermalCurrentPaletteStyle; + } + + public DockDronePayload setThermalCurrentPaletteStyle(ThermalPaletteStyleEnum thermalCurrentPaletteStyle) { + this.thermalCurrentPaletteStyle = thermalCurrentPaletteStyle; + return this; + } + + public ThermalGainModeEnum getThermalGainMode() { + return thermalGainMode; + } + + public DockDronePayload setThermalGainMode(ThermalGainModeEnum thermalGainMode) { + this.thermalGainMode = thermalGainMode; + return this; + } + + public Float getThermalGlobalTemperatureMax() { + return thermalGlobalTemperatureMax; + } + + public DockDronePayload setThermalGlobalTemperatureMax(Float thermalGlobalTemperatureMax) { + this.thermalGlobalTemperatureMax = thermalGlobalTemperatureMax; + return this; + } + + public Float getThermalGlobalTemperatureMin() { + return thermalGlobalTemperatureMin; + } + + public DockDronePayload setThermalGlobalTemperatureMin(Float thermalGlobalTemperatureMin) { + this.thermalGlobalTemperatureMin = thermalGlobalTemperatureMin; + return this; + } + + public Integer getThermalIsothermLowerLimit() { + return thermalIsothermLowerLimit; + } + + public DockDronePayload setThermalIsothermLowerLimit(Integer thermalIsothermLowerLimit) { + this.thermalIsothermLowerLimit = thermalIsothermLowerLimit; + return this; + } + + public SwitchActionEnum getThermalIsothermState() { + return thermalIsothermState; + } + + public DockDronePayload setThermalIsothermState(SwitchActionEnum thermalIsothermState) { + this.thermalIsothermState = thermalIsothermState; + return this; + } + + public Integer getThermalIsothermUpperLimit() { + return thermalIsothermUpperLimit; + } + + public DockDronePayload setThermalIsothermUpperLimit(Integer thermalIsothermUpperLimit) { + this.thermalIsothermUpperLimit = thermalIsothermUpperLimit; + return this; + } + + public List getSmartTrackPoint() { + return smartTrackPoint; + } + + public DockDronePayload setSmartTrackPoint(List smartTrackPoint) { + this.smartTrackPoint = smartTrackPoint; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockFirmwareVersion.java b/src/main/java/com/dji/sdk/cloudapi/device/DockFirmwareVersion.java new file mode 100644 index 0000000..2f123bf --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockFirmwareVersion.java @@ -0,0 +1,57 @@ +package com.dji.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/28 + */ +public class DockFirmwareVersion { + + private String firmwareVersion; + + @JsonProperty("compatible_status") + private Boolean needCompatibleStatus; + + private Boolean firmwareUpgradeStatus; + + public DockFirmwareVersion() { + } + + @Override + public String toString() { + return "DockFirmwareVersion{" + + "firmwareVersion='" + firmwareVersion + '\'' + + ", compatibleStatus=" + needCompatibleStatus + + ", firmwareUpgradeStatus=" + firmwareUpgradeStatus + + '}'; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public DockFirmwareVersion setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } + + public Boolean getNeedCompatibleStatus() { + return needCompatibleStatus; + } + + public DockFirmwareVersion setNeedCompatibleStatus(Boolean needCompatibleStatus) { + this.needCompatibleStatus = needCompatibleStatus; + return this; + } + + public Boolean getFirmwareUpgradeStatus() { + return firmwareUpgradeStatus; + } + + public DockFirmwareVersion setFirmwareUpgradeStatus(Boolean firmwareUpgradeStatus) { + this.firmwareUpgradeStatus = firmwareUpgradeStatus; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockLiveErrorStatus.java b/src/main/java/com/dji/sdk/cloudapi/device/DockLiveErrorStatus.java new file mode 100644 index 0000000..aa67276 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockLiveErrorStatus.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.cloudapi.livestream.LiveErrorCodeEnum; +import com.dji.sdk.common.ErrorCodeSourceEnum; +import com.dji.sdk.mqtt.MqttReply; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class DockLiveErrorStatus { + + private static final int MOD = 100_000; + + private ErrorCodeSourceEnum source = ErrorCodeSourceEnum.DOCK; + + private LiveErrorCodeEnum errorCode; + + private boolean success; + + @Override + public String toString() { + return "{" + + "errorCode=" + getCode() + + ", errorMsg=" + getMessage() + + '}'; + } + + @JsonCreator + public DockLiveErrorStatus(int code) { + if (MqttReply.CODE_SUCCESS == code) { + this.success = true; + return; + } + this.source = ErrorCodeSourceEnum.find(code / MOD); + this.errorCode = LiveErrorCodeEnum.find(code % MOD); + } + + public String getMessage() { + return errorCode.getMessage(); + } + + @JsonValue + public Integer getCode() { + return source.getSource() * MOD + errorCode.getCode(); + } + + public boolean isSuccess() { + return success; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockLiveStatus.java b/src/main/java/com/dji/sdk/cloudapi/device/DockLiveStatus.java new file mode 100644 index 0000000..e4720a7 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockLiveStatus.java @@ -0,0 +1,32 @@ +package com.dji.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class DockLiveStatus { + + private List liveStatus; + + public DockLiveStatus() { + } + + @Override + public String toString() { + return "DockLiveStatus{" + + "liveStatus=" + liveStatus + + '}'; + } + + public List getLiveStatus() { + return liveStatus; + } + + public DockLiveStatus setLiveStatus(List liveStatus) { + this.liveStatus = liveStatus; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockLiveStatusData.java b/src/main/java/com/dji/sdk/cloudapi/device/DockLiveStatusData.java new file mode 100644 index 0000000..6c28087 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockLiveStatusData.java @@ -0,0 +1,81 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.cloudapi.livestream.VideoQualityEnum; +import com.dji.sdk.cloudapi.livestream.VideoTypeEnum; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class DockLiveStatusData { + + private Boolean status; + + private VideoId videoId; + + private VideoQualityEnum videoQuality; + + private VideoTypeEnum videoType; + + private DockLiveErrorStatus errorStatus; + + public DockLiveStatusData() { + } + + @Override + public String toString() { + return "DockLiveStatusData{" + + "status=" + status + + ", videoId=" + videoId + + ", videoQuality=" + videoQuality + + ", videoType=" + videoType + + ", errorStatus=" + errorStatus + + '}'; + } + + public Boolean getStatus() { + return status; + } + + public DockLiveStatusData setStatus(Boolean status) { + this.status = status; + return this; + } + + public VideoId getVideoId() { + return videoId; + } + + public DockLiveStatusData setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } + + public VideoQualityEnum getVideoQuality() { + return videoQuality; + } + + public DockLiveStatusData setVideoQuality(VideoQualityEnum videoQuality) { + this.videoQuality = videoQuality; + return this; + } + + public VideoTypeEnum getVideoType() { + return videoType; + } + + public DockLiveStatusData setVideoType(VideoTypeEnum videoType) { + this.videoType = videoType; + return this; + } + + public DockLiveErrorStatus getErrorStatus() { + return errorStatus; + } + + public DockLiveStatusData setErrorStatus(DockLiveErrorStatus errorStatus) { + this.errorStatus = errorStatus; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockMaintainStatus.java b/src/main/java/com/dji/sdk/cloudapi/device/DockMaintainStatus.java new file mode 100644 index 0000000..155842e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockMaintainStatus.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class DockMaintainStatus { + + private Integer lastMaintainFlightSorties; + + private Long lastMaintainTime; + + private MaintainTypeEnum lastMaintainType; + + private Boolean state; + + public DockMaintainStatus() { + } + + @Override + public String toString() { + return "DroneMaintainStatus{" + + "lastMaintainFlightSorties=" + lastMaintainFlightSorties + + ", lastMaintainTime=" + lastMaintainTime + + ", lastMaintainType=" + lastMaintainType + + ", state=" + state + + '}'; + } + + public Integer getLastMaintainFlightSorties() { + return lastMaintainFlightSorties; + } + + public DockMaintainStatus setLastMaintainFlightSorties(Integer lastMaintainFlightSorties) { + this.lastMaintainFlightSorties = lastMaintainFlightSorties; + return this; + } + + public Long getLastMaintainTime() { + return lastMaintainTime; + } + + public DockMaintainStatus setLastMaintainTime(Long lastMaintainTime) { + this.lastMaintainTime = lastMaintainTime; + return this; + } + + public MaintainTypeEnum getLastMaintainType() { + return lastMaintainType; + } + + public DockMaintainStatus setLastMaintainType(MaintainTypeEnum lastMaintainType) { + this.lastMaintainType = lastMaintainType; + return this; + } + + public Boolean getState() { + return state; + } + + public DockMaintainStatus setState(Boolean state) { + this.state = state; + return this; + } +} diff --git a/src/main/java/com/dji/sample/manage/model/enums/DockModeCodeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/DockModeCodeEnum.java similarity index 51% rename from src/main/java/com/dji/sample/manage/model/enums/DockModeCodeEnum.java rename to src/main/java/com/dji/sdk/cloudapi/device/DockModeCodeEnum.java index ae1aa91..882a5c6 100644 --- a/src/main/java/com/dji/sample/manage/model/enums/DockModeCodeEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockModeCodeEnum.java @@ -1,5 +1,6 @@ -package com.dji.sample.manage.model.enums; +package com.dji.sdk.cloudapi.device; +import com.dji.sdk.exception.CloudSDKException; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; @@ -20,23 +21,22 @@ public enum DockModeCodeEnum { UPGRADING(3), - WORKING(4), + WORKING(4); - DISCONNECTED(-1); + private final int code; - int val; - - DockModeCodeEnum(int val) { - this.val = val; + DockModeCodeEnum(int code) { + this.code = code; } @JsonValue - public int getVal() { - return val; + public int getCode() { + return code; } @JsonCreator - public static DockModeCodeEnum find(int val) { - return Arrays.stream(values()).filter(modeCode -> modeCode.getVal() == val).findAny().orElse(DISCONNECTED); + public static DockModeCodeEnum find(int code) { + return Arrays.stream(values()).filter(modeCode -> modeCode.code == code).findAny() + .orElseThrow(() -> new CloudSDKException(DockModeCodeEnum.class, code)); } } diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockPayload.java b/src/main/java/com/dji/sdk/cloudapi/device/DockPayload.java new file mode 100644 index 0000000..723719f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockPayload.java @@ -0,0 +1,56 @@ +package com.dji.sdk.cloudapi.device; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class DockPayload { + + private PayloadIndex payloadIndex; + + private ThermalPaletteStyleEnum[] thermalSupportedPaletteStyles; + + private Integer version; + + public DockPayload() { + } + + @Override + public String toString() { + return "DockPayload{" + + "payloadIndex=" + payloadIndex + + ", thermalSupportedPaletteStyles=" + Arrays.toString(thermalSupportedPaletteStyles) + + ", version=" + version + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public DockPayload setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ThermalPaletteStyleEnum[] getThermalSupportedPaletteStyles() { + return thermalSupportedPaletteStyles; + } + + public DockPayload setThermalSupportedPaletteStyles(ThermalPaletteStyleEnum[] thermalSupportedPaletteStyles) { + this.thermalSupportedPaletteStyles = thermalSupportedPaletteStyles; + return this; + } + + public Integer getVersion() { + return version; + } + + public DockPayload setVersion(Integer version) { + this.version = version; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockPayloadControlSource.java b/src/main/java/com/dji/sdk/cloudapi/device/DockPayloadControlSource.java new file mode 100644 index 0000000..545e129 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockPayloadControlSource.java @@ -0,0 +1,55 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class DockPayloadControlSource { + + private ControlSourceEnum controlSource; + + private PayloadIndex payloadIndex; + + private String sn; + + public DockPayloadControlSource() { + } + + @Override + public String toString() { + return "RcPayloadControlSource{" + + "controlSource=" + controlSource + + ", payloadIndex=" + payloadIndex + + ", sn='" + sn + '\'' + + '}'; + } + + public ControlSourceEnum getControlSource() { + return controlSource; + } + + public DockPayloadControlSource setControlSource(ControlSourceEnum controlSource) { + this.controlSource = controlSource; + return this; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public DockPayloadControlSource setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public String getSn() { + return sn; + } + + public DockPayloadControlSource setSn(String sn) { + this.sn = sn; + return this; + } + +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockPositionState.java b/src/main/java/com/dji/sdk/cloudapi/device/DockPositionState.java new file mode 100644 index 0000000..268f7c4 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockPositionState.java @@ -0,0 +1,81 @@ +package com.dji.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 0.3 + * @date 2022/1/27 + */ +public class DockPositionState { + + @JsonProperty("is_calibration") + private Boolean calibration; + + private Integer gpsNumber; + + private PositionFixedEnum isFixed; + + private Integer quality; + + private Integer rtkNumber; + + public DockPositionState() { + } + + @Override + public String toString() { + return "DockPositionState{" + + "Calibration=" + calibration + + ", gpsNumber=" + gpsNumber + + ", isFixed=" + isFixed + + ", quality=" + quality + + ", rtkNumber=" + rtkNumber + + '}'; + } + + public Boolean getCalibration() { + return calibration; + } + + public DockPositionState setCalibration(Boolean calibration) { + calibration = calibration; + return this; + } + + public Integer getGpsNumber() { + return gpsNumber; + } + + public DockPositionState setGpsNumber(Integer gpsNumber) { + this.gpsNumber = gpsNumber; + return this; + } + + public PositionFixedEnum getIsFixed() { + return isFixed; + } + + public DockPositionState setIsFixed(PositionFixedEnum isFixed) { + this.isFixed = isFixed; + return this; + } + + public Integer getQuality() { + return quality; + } + + public DockPositionState setQuality(Integer quality) { + this.quality = quality; + return this; + } + + public Integer getRtkNumber() { + return rtkNumber; + } + + public DockPositionState setRtkNumber(Integer rtkNumber) { + this.rtkNumber = rtkNumber; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockSubDevice.java b/src/main/java/com/dji/sdk/cloudapi/device/DockSubDevice.java new file mode 100644 index 0000000..ef5daf6 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockSubDevice.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/11 + */ +public class DockSubDevice { + + private String deviceSn; + + private Boolean deviceOnlineStatus; + + private Boolean devicePaired; + + private DeviceEnum deviceModelKey; + + public DockSubDevice() { + } + + @Override + public String toString() { + return "DockSubDevice{" + + "deviceSn='" + deviceSn + '\'' + + ", deviceOnlineStatus=" + deviceOnlineStatus + + ", devicePaired=" + devicePaired + + ", deviceModelKey=" + deviceModelKey + + '}'; + } + + public String getDeviceSn() { + return deviceSn; + } + + public DockSubDevice setDeviceSn(String deviceSn) { + this.deviceSn = deviceSn; + return this; + } + + public Boolean getDeviceOnlineStatus() { + return deviceOnlineStatus; + } + + public DockSubDevice setDeviceOnlineStatus(Boolean deviceOnlineStatus) { + this.deviceOnlineStatus = deviceOnlineStatus; + return this; + } + + public Boolean getDevicePaired() { + return devicePaired; + } + + public DockSubDevice setDevicePaired(Boolean devicePaired) { + this.devicePaired = devicePaired; + return this; + } + + public DeviceEnum getDeviceModelKey() { + return deviceModelKey; + } + + public DockSubDevice setDeviceModelKey(DeviceEnum deviceModelKey) { + this.deviceModelKey = deviceModelKey; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DockWpmzVersion.java b/src/main/java/com/dji/sdk/cloudapi/device/DockWpmzVersion.java new file mode 100644 index 0000000..29c6bef --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DockWpmzVersion.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class DockWpmzVersion { + + private String wpmzVersion; + + public DockWpmzVersion() { + } + + @Override + public String toString() { + return "DockWpmzVersion{" + + "wpmzVersion='" + wpmzVersion + '\'' + + '}'; + } + + public String getWpmzVersion() { + return wpmzVersion; + } + + public DockWpmzVersion setWpmzVersion(String wpmzVersion) { + this.wpmzVersion = wpmzVersion; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DrcStateEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/DrcStateEnum.java new file mode 100644 index 0000000..ee9b36f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DrcStateEnum.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/2/28 + */ +public enum DrcStateEnum { + + DISCONNECTED(0), + + CONNECTING(1), + + CONNECTED(2); + + private final int state; + + DrcStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static DrcStateEnum find(int state) { + return Arrays.stream(values()).filter(drcState -> drcState.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(DrcStateEnum.class, state)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DroneBattery.java b/src/main/java/com/dji/sdk/cloudapi/device/DroneBattery.java new file mode 100644 index 0000000..b40e770 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DroneBattery.java @@ -0,0 +1,80 @@ +package com.dji.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 0.3 + * @date 2022/1/27 + */ +public class DroneBattery { + + private List batteries; + + private Integer capacityPercent; + + private Integer landingPower; + + private Integer remainFlightTime; + + private Integer returnHomePower; + + public DroneBattery() { + } + + @Override + public String toString() { + return "DroneBattery{" + + "batteries=" + batteries + + ", capacityPercent=" + capacityPercent + + ", landingPower=" + landingPower + + ", remainFlightTime=" + remainFlightTime + + ", returnHomePower=" + returnHomePower + + '}'; + } + + public List getBatteries() { + return batteries; + } + + public DroneBattery setBatteries(List batteries) { + this.batteries = batteries; + return this; + } + + public Integer getCapacityPercent() { + return capacityPercent; + } + + public DroneBattery setCapacityPercent(Integer capacityPercent) { + this.capacityPercent = capacityPercent; + return this; + } + + public Integer getLandingPower() { + return landingPower; + } + + public DroneBattery setLandingPower(Integer landingPower) { + this.landingPower = landingPower; + return this; + } + + public Integer getRemainFlightTime() { + return remainFlightTime; + } + + public DroneBattery setRemainFlightTime(Integer remainFlightTime) { + this.remainFlightTime = remainFlightTime; + return this; + } + + public Integer getReturnHomePower() { + return returnHomePower; + } + + public DroneBattery setReturnHomePower(Integer returnHomePower) { + this.returnHomePower = returnHomePower; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DroneBatteryMaintenance.java b/src/main/java/com/dji/sdk/cloudapi/device/DroneBatteryMaintenance.java new file mode 100644 index 0000000..22d1833 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DroneBatteryMaintenance.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class DroneBatteryMaintenance { + + private BatteryIndexEnum index; + + private Integer capacityPercent; + + private Integer voltage; + + private Float temperature; + + public DroneBatteryMaintenance() { + } + + @Override + public String toString() { + return "DroneBatteryMaintenance{" + + "index=" + index + + ", capacityPercent=" + capacityPercent + + ", voltage=" + voltage + + ", temperature=" + temperature + + '}'; + } + + public BatteryIndexEnum getIndex() { + return index; + } + + public DroneBatteryMaintenance setIndex(BatteryIndexEnum index) { + this.index = index; + return this; + } + + public Integer getCapacityPercent() { + return capacityPercent; + } + + public DroneBatteryMaintenance setCapacityPercent(Integer capacityPercent) { + this.capacityPercent = capacityPercent; + return this; + } + + public Integer getVoltage() { + return voltage; + } + + public DroneBatteryMaintenance setVoltage(Integer voltage) { + this.voltage = voltage; + return this; + } + + public Float getTemperature() { + return temperature; + } + + public DroneBatteryMaintenance setTemperature(Float temperature) { + this.temperature = temperature; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DroneBatteryMaintenanceInfo.java b/src/main/java/com/dji/sdk/cloudapi/device/DroneBatteryMaintenanceInfo.java new file mode 100644 index 0000000..af85d37 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DroneBatteryMaintenanceInfo.java @@ -0,0 +1,32 @@ +package com.dji.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 1.4 + * @date 2022/11/3 + */ +public class DroneBatteryMaintenanceInfo { + + private List batteries; + + public DroneBatteryMaintenanceInfo() { + } + + @Override + public String toString() { + return "DroneBatteryMaintenanceInfo{" + + "batteries=" + batteries + + '}'; + } + + public List getBatteries() { + return batteries; + } + + public DroneBatteryMaintenanceInfo setBatteries(List batteries) { + this.batteries = batteries; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DroneChargeState.java b/src/main/java/com/dji/sdk/cloudapi/device/DroneChargeState.java new file mode 100644 index 0000000..a873c76 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DroneChargeState.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/11 + */ +public class DroneChargeState { + + private Boolean state; + + private Integer capacityPercent; + + public DroneChargeState() { + } + + @Override + public String toString() { + return "DroneChargeState{" + + "state=" + state + + ", capacityPercent=" + capacityPercent + + '}'; + } + + public Boolean getState() { + return state; + } + + public DroneChargeState setState(Boolean state) { + this.state = state; + return this; + } + + public Integer getCapacityPercent() { + return capacityPercent; + } + + public DroneChargeState setCapacityPercent(Integer capacityPercent) { + this.capacityPercent = capacityPercent; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DroneMaintainStatus.java b/src/main/java/com/dji/sdk/cloudapi/device/DroneMaintainStatus.java new file mode 100644 index 0000000..3ba6af1 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DroneMaintainStatus.java @@ -0,0 +1,78 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class DroneMaintainStatus { + + private Integer lastMaintainFlightSorties; + + private Integer lastMaintainFlightTime; + + private Long lastMaintainTime; + + private MaintainTypeEnum lastMaintainType; + + private Boolean state; + + public DroneMaintainStatus() { + } + + @Override + public String toString() { + return "DroneMaintainStatus{" + + "lastMaintainFlightSorties=" + lastMaintainFlightSorties + + ", lastMaintainFlightTime=" + lastMaintainFlightTime + + ", lastMaintainTime=" + lastMaintainTime + + ", lastMaintainType=" + lastMaintainType + + ", state=" + state + + '}'; + } + + public Integer getLastMaintainFlightSorties() { + return lastMaintainFlightSorties; + } + + public DroneMaintainStatus setLastMaintainFlightSorties(Integer lastMaintainFlightSorties) { + this.lastMaintainFlightSorties = lastMaintainFlightSorties; + return this; + } + + public Integer getLastMaintainFlightTime() { + return lastMaintainFlightTime; + } + + public DroneMaintainStatus setLastMaintainFlightTime(Integer lastMaintainFlightTime) { + this.lastMaintainFlightTime = lastMaintainFlightTime; + return this; + } + + public Long getLastMaintainTime() { + return lastMaintainTime; + } + + public DroneMaintainStatus setLastMaintainTime(Long lastMaintainTime) { + this.lastMaintainTime = lastMaintainTime; + return this; + } + + public MaintainTypeEnum getLastMaintainType() { + return lastMaintainType; + } + + public DroneMaintainStatus setLastMaintainType(MaintainTypeEnum lastMaintainType) { + this.lastMaintainType = lastMaintainType; + return this; + } + + public Boolean getState() { + return state; + } + + public DroneMaintainStatus setState(Boolean state) { + this.state = state; + return this; + } +} diff --git a/src/main/java/com/dji/sample/manage/model/enums/DeviceModeCodeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/DroneModeCodeEnum.java similarity index 61% rename from src/main/java/com/dji/sample/manage/model/enums/DeviceModeCodeEnum.java rename to src/main/java/com/dji/sdk/cloudapi/device/DroneModeCodeEnum.java index 9957032..526460b 100644 --- a/src/main/java/com/dji/sample/manage/model/enums/DeviceModeCodeEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/device/DroneModeCodeEnum.java @@ -1,5 +1,6 @@ -package com.dji.sample.manage.model.enums; +package com.dji.sdk.cloudapi.device; +import com.dji.sdk.exception.CloudSDKException; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; @@ -10,7 +11,7 @@ import java.util.Arrays; * @version 1.4 * @date 2023/3/9 */ -public enum DeviceModeCodeEnum { +public enum DroneModeCodeEnum { IDLE(0), @@ -46,19 +47,20 @@ public enum DeviceModeCodeEnum { VIRTUAL_JOYSTICK(16); - int val; + private final int code; - DeviceModeCodeEnum(int val) { - this.val = val; + DroneModeCodeEnum(int code) { + this.code = code; } @JsonValue - public int getVal() { - return val; + public int getCode() { + return code; } @JsonCreator - public static DeviceModeCodeEnum find(int value) { - return Arrays.stream(values()).filter(modeCodeEnum -> modeCodeEnum.ordinal() == value).findAny().orElse(DISCONNECTED); + public static DroneModeCodeEnum find(int code) { + return Arrays.stream(values()).filter(modeCodeEnum -> modeCodeEnum.ordinal() == code).findAny() + .orElseThrow(() -> new CloudSDKException(DroneModeCodeEnum.class, code)); } } diff --git a/src/main/java/com/dji/sdk/cloudapi/device/DronePositionState.java b/src/main/java/com/dji/sdk/cloudapi/device/DronePositionState.java new file mode 100644 index 0000000..b0d6aef --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/DronePositionState.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 0.3 + * @date 2022/1/27 + */ +public class DronePositionState { + + private Integer gpsNumber; + + private PositionFixedEnum isFixed; + + private Integer quality; + + private Integer rtkNumber; + + public DronePositionState() { + } + + @Override + public String toString() { + return "DronePositionState{" + + "gpsNumber=" + gpsNumber + + ", isFixed=" + isFixed + + ", quality=" + quality + + ", rtkNumber=" + rtkNumber + + '}'; + } + + public Integer getGpsNumber() { + return gpsNumber; + } + + public DronePositionState setGpsNumber(Integer gpsNumber) { + this.gpsNumber = gpsNumber; + return this; + } + + public PositionFixedEnum getIsFixed() { + return isFixed; + } + + public DronePositionState setIsFixed(PositionFixedEnum isFixed) { + this.isFixed = isFixed; + return this; + } + + public Integer getQuality() { + return quality; + } + + public DronePositionState setQuality(Integer quality) { + this.quality = quality; + return this; + } + + public Integer getRtkNumber() { + return rtkNumber; + } + + public DronePositionState setRtkNumber(Integer rtkNumber) { + this.rtkNumber = rtkNumber; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/ExitWaylineWhenRcLostEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/ExitWaylineWhenRcLostEnum.java new file mode 100755 index 0000000..e5f1483 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/ExitWaylineWhenRcLostEnum.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum ExitWaylineWhenRcLostEnum { + + CONTINUE(0), + + EXECUTE_RC_LOST_ACTION(1); + + private final int action; + + ExitWaylineWhenRcLostEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static ExitWaylineWhenRcLostEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(ExitWaylineWhenRcLostEnum.class, action)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/FlighttaskStepCodeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/FlighttaskStepCodeEnum.java new file mode 100644 index 0000000..00ed09f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/FlighttaskStepCodeEnum.java @@ -0,0 +1,49 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum FlighttaskStepCodeEnum { + + TASK_PREPARING(0), + + TASK_OPERATING(1), + + STATE_RECOVERING(2), + + WORKING(4), + + // TODO 确认状态 + UNKNOWN(5), + + UNKNOWN1(255), + + UNKNOWN2(256), + ; + + private final int code; + + FlighttaskStepCodeEnum(int code) { + this.code = code; + } + + @JsonValue + public int getCode() { + return code; + } + + @JsonCreator + public static FlighttaskStepCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny() + .orElseThrow(() -> new CloudSDKException(FlighttaskStepCodeEnum.class, code)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/GearEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/GearEnum.java new file mode 100644 index 0000000..b22a957 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/GearEnum.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum GearEnum { + + A(0), + + P(1), + + NAV(2), + + FPV(3), + + FARM(4), + + S(5), + + F(6), + + M(7), + + G(8), + + T(9), + ; + + private final int gear; + + GearEnum(int gear) { + this.gear = gear; + } + + @JsonValue + public int getGear() { + return gear; + } + + @JsonCreator + public static GearEnum find(int gear) { + return Arrays.stream(values()).filter(gearEnum -> gearEnum.gear == gear).findAny() + .orElseThrow(() -> new CloudSDKException(GearEnum.class, gear)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/LinkWorkModeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/LinkWorkModeEnum.java new file mode 100644 index 0000000..8e836fe --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/LinkWorkModeEnum.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public enum LinkWorkModeEnum { + + SDR_ONLY(0), + + SDR_WITH_4G(1); + + private final int mode; + + LinkWorkModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static LinkWorkModeEnum find(int mode) { + return Arrays.stream(LinkWorkModeEnum.values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(LinkWorkModeEnum.class, mode)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/LiveviewWorldRegion.java b/src/main/java/com/dji/sdk/cloudapi/device/LiveviewWorldRegion.java new file mode 100644 index 0000000..308060c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/LiveviewWorldRegion.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/8 + */ +public class LiveviewWorldRegion { + + private Float bottom; + + private Float left; + + private Float right; + + private Float top; + + public LiveviewWorldRegion() { + } + + @Override + public String toString() { + return "LiveviewWorldRegion{" + + "bottom=" + bottom + + ", left=" + left + + ", right=" + right + + ", top=" + top + + '}'; + } + + public Float getBottom() { + return bottom; + } + + public LiveviewWorldRegion setBottom(Float bottom) { + this.bottom = bottom; + return this; + } + + public Float getLeft() { + return left; + } + + public LiveviewWorldRegion setLeft(Float left) { + this.left = left; + return this; + } + + public Float getRight() { + return right; + } + + public LiveviewWorldRegion setRight(Float right) { + this.right = right; + return this; + } + + public Float getTop() { + return top; + } + + public LiveviewWorldRegion setTop(Float top) { + this.top = top; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/MaintainTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/MaintainTypeEnum.java new file mode 100644 index 0000000..a1c1f11 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/MaintainTypeEnum.java @@ -0,0 +1,46 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum MaintainTypeEnum { + + NO(0), + + DRONE_BASIC(1), + + DRONE_ROUTINE(2), + + DRONE_DEEP(3), + + DOCK_ROUTINE(17), + + DOCK_DEEP(18), + ; + + private final int type; + + MaintainTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static MaintainTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(MaintainTypeEnum.class, type)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/MeasureTargetStateEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/MeasureTargetStateEnum.java new file mode 100644 index 0000000..48566e8 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/MeasureTargetStateEnum.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum MeasureTargetStateEnum { + + NORMAL(0), + + TOO_CLOSE(1), + + TOO_FAR(2), + + NO_SIGNAL(3), + ; + + private final int state; + + MeasureTargetStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static MeasureTargetStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(MeasureTargetStateEnum.class, state)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/MediaFileDetail.java b/src/main/java/com/dji/sdk/cloudapi/device/MediaFileDetail.java new file mode 100644 index 0000000..d1e3e90 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/MediaFileDetail.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/17 + */ +public class MediaFileDetail { + + private Integer remainUpload; + + public MediaFileDetail() { + } + + @Override + public String toString() { + return "MediaFileDetail{" + + "remainUpload=" + remainUpload + + '}'; + } + + public Integer getRemainUpload() { + return remainUpload; + } + + public MediaFileDetail setRemainUpload(Integer remainUpload) { + this.remainUpload = remainUpload; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/ModeCodeReasonEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/ModeCodeReasonEnum.java new file mode 100644 index 0000000..dd8f67a --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/ModeCodeReasonEnum.java @@ -0,0 +1,79 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/2/28 + */ +public enum ModeCodeReasonEnum { + + NO_MEANING(0), + + LOW_POWER(1), + + LOW_VOLTAGE(2), + + SERIOUS_LOW_VOLTAGE(3), + + RC_CONTROL(4), + + APP_CONTROL(5), + + RC_SIGNAL_LOST(6), + + EXTERNAL_DEVICE_TRIGGERED(7), + + GEO_ZONE(8), + + HOME_POINT_TOO_CLOSED(9), + + HOME_POINT_TOO_FAR(10), + + EXECUTING_WAYPOINT_MISSION(11), + + ARRIVE_HOME_POINT(12), + + SECOND_LIMIT_LANDING(13), + + APP_FORCIBLY_BREAK_PROTECTION(14), + + PLANES_PASSING_NEARBY(15), + + HEIGHT_CONTROL_FAILED(16), + + LOW_POWER_RTH(17), + + AP_CONTROL(18), + + HARDWARE_ABNORMAL(19), + + TOUCHDOWN_AVOIDANCE_PROTECTION(20), + + CANCEL_RTH(21), + + RTH_OBSTACLE_AVOIDANCE(22), + ; + + private final int reason; + + ModeCodeReasonEnum(int reason) { + this.reason = reason; + } + + @JsonValue + public int getReason() { + return reason; + } + + @JsonCreator + public static ModeCodeReasonEnum find(int reason) { + return Arrays.stream(values()).filter(reasonEnum -> reasonEnum.reason == reason).findAny() + .orElseThrow(() -> new CloudSDKException(ModeCodeReasonEnum.class, reason)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/NetworkState.java b/src/main/java/com/dji/sdk/cloudapi/device/NetworkState.java new file mode 100644 index 0000000..dfe33b3 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/NetworkState.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/11 + */ +public class NetworkState { + + private NetworkStateTypeEnum type; + + private NetworkStateQualityEnum quality; + + private Float rate; + + public NetworkState() { + } + + @Override + public String toString() { + return "NetworkState{" + + "type=" + type + + ", quality=" + quality + + ", rate=" + rate + + '}'; + } + + public NetworkStateTypeEnum getType() { + return type; + } + + public NetworkState setType(NetworkStateTypeEnum type) { + this.type = type; + return this; + } + + public NetworkStateQualityEnum getQuality() { + return quality; + } + + public NetworkState setQuality(NetworkStateQualityEnum quality) { + this.quality = quality; + return this; + } + + public Float getRate() { + return rate; + } + + public NetworkState setRate(Float rate) { + this.rate = rate; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/NetworkStateQualityEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/NetworkStateQualityEnum.java new file mode 100644 index 0000000..6b0b447 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/NetworkStateQualityEnum.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum NetworkStateQualityEnum { + + BAD(0), + + MODERATE(1), + + GOOD(2), + ; + + private final int quality; + + NetworkStateQualityEnum(int quality) { + this.quality = quality; + } + + @JsonValue + public int getQuality() { + return quality; + } + + @JsonCreator + public static NetworkStateQualityEnum find(int quality) { + return Arrays.stream(values()).filter(qualityEnum -> qualityEnum.quality == quality).findAny() + .orElseThrow(() -> new CloudSDKException(NetworkStateQualityEnum.class, quality)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/NetworkStateTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/NetworkStateTypeEnum.java new file mode 100644 index 0000000..9f63e06 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/NetworkStateTypeEnum.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum NetworkStateTypeEnum { + + FOURTH_GENERATION(1), + + ETHERNET(2), + ; + + private final int type; + + NetworkStateTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static NetworkStateTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(NetworkStateTypeEnum.class, type)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/ObstacleAvoidance.java b/src/main/java/com/dji/sdk/cloudapi/device/ObstacleAvoidance.java new file mode 100644 index 0000000..fc49dfe --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/ObstacleAvoidance.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class ObstacleAvoidance { + + private SwitchActionEnum horizon; + + private SwitchActionEnum upside; + + private SwitchActionEnum downside; + + public ObstacleAvoidance() { + } + + @Override + public String toString() { + return "ObstacleAvoidanceSet{" + + "horizon=" + horizon + + ", upside=" + upside + + ", downside=" + downside + + '}'; + } + + public SwitchActionEnum getHorizon() { + return horizon; + } + + public ObstacleAvoidance setHorizon(SwitchActionEnum horizon) { + this.horizon = horizon; + return this; + } + + public SwitchActionEnum getUpside() { + return upside; + } + + public ObstacleAvoidance setUpside(SwitchActionEnum upside) { + this.upside = upside; + return this; + } + + public SwitchActionEnum getDownside() { + return downside; + } + + public ObstacleAvoidance setDownside(SwitchActionEnum downside) { + this.downside = downside; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/OsdCamera.java b/src/main/java/com/dji/sdk/cloudapi/device/OsdCamera.java new file mode 100644 index 0000000..0d829ba --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/OsdCamera.java @@ -0,0 +1,138 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/8 + */ +public class OsdCamera { + + private CameraModeEnum cameraMode; + + private LiveviewWorldRegion liveviewWorldRegion; + + private PayloadIndex payloadIndex; + + private CameraStateEnum photoState; + + private Integer recordTime; + + private CameraStateEnum recordingState; + + private Long remainPhotoNum; + + private Integer remainRecordDuration; + + private Float zoomFactor; + + private Float irZoomFactor; + + public OsdCamera() { + } + + @Override + public String toString() { + return "OsdCamera{" + + "cameraMode=" + cameraMode + + ", liveviewWorldRegion=" + liveviewWorldRegion + + ", payloadIndex=" + payloadIndex + + ", photoState=" + photoState + + ", recordTime=" + recordTime + + ", recordingState=" + recordingState + + ", remainPhotoNum=" + remainPhotoNum + + ", remainRecordDuration=" + remainRecordDuration + + ", zoomFactor=" + zoomFactor + + ", irZoomFactor=" + irZoomFactor + + '}'; + } + + public CameraModeEnum getCameraMode() { + return cameraMode; + } + + public OsdCamera setCameraMode(CameraModeEnum cameraMode) { + this.cameraMode = cameraMode; + return this; + } + + public LiveviewWorldRegion getLiveviewWorldRegion() { + return liveviewWorldRegion; + } + + public OsdCamera setLiveviewWorldRegion(LiveviewWorldRegion liveviewWorldRegion) { + this.liveviewWorldRegion = liveviewWorldRegion; + return this; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public OsdCamera setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public CameraStateEnum getPhotoState() { + return photoState; + } + + public OsdCamera setPhotoState(CameraStateEnum photoState) { + this.photoState = photoState; + return this; + } + + public Integer getRecordTime() { + return recordTime; + } + + public OsdCamera setRecordTime(Integer recordTime) { + this.recordTime = recordTime; + return this; + } + + public CameraStateEnum getRecordingState() { + return recordingState; + } + + public OsdCamera setRecordingState(CameraStateEnum recordingState) { + this.recordingState = recordingState; + return this; + } + + public Long getRemainPhotoNum() { + return remainPhotoNum; + } + + public OsdCamera setRemainPhotoNum(Long remainPhotoNum) { + this.remainPhotoNum = remainPhotoNum; + return this; + } + + public Integer getRemainRecordDuration() { + return remainRecordDuration; + } + + public OsdCamera setRemainRecordDuration(Integer remainRecordDuration) { + this.remainRecordDuration = remainRecordDuration; + return this; + } + + public Float getZoomFactor() { + return zoomFactor; + } + + public OsdCamera setZoomFactor(Float zoomFactor) { + this.zoomFactor = zoomFactor; + return this; + } + + public Float getIrZoomFactor() { + return irZoomFactor; + } + + public OsdCamera setIrZoomFactor(Float irZoomFactor) { + this.irZoomFactor = irZoomFactor; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/OsdDock.java b/src/main/java/com/dji/sdk/cloudapi/device/OsdDock.java new file mode 100644 index 0000000..1ea119b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/OsdDock.java @@ -0,0 +1,474 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/3 + */ +public class OsdDock { + + private NetworkState networkState; + + private Boolean droneInDock; + + private DroneChargeState droneChargeState; + + private RainfallEnum rainfall; + + private Float windSpeed; + + private Float environmentTemperature; + + private Float temperature; + + private Integer humidity; + + private Float latitude; + + private Float longitude; + + private Float height; + + private AlternateLandPoint alternateLandPoint; + + private Long firstPowerOn; + + private DockPositionState positionState; + + private Storage storage; + + private DockModeCodeEnum modeCode; + + private CoverStateEnum coverState; + + private Boolean supplementLightState; + + private Boolean emergencyStopState; + + private AirConditioner airConditioner; + + private BatteryStoreModeEnum batteryStoreMode; + + private Boolean alarmState; + + private PutterStateEnum putterState; + + private DockSubDevice subDevice; + + private Integer jobNumber; + + private Long accTime; + + private Long activationTime; + + private OsdDockMaintainStatus maintainStatus; + + private Integer electricSupplyVoltage; + + private Integer workingVoltage; + + private Integer workingCurrent; + + private BackupBattery backupBattery; + + private DroneBatteryMaintenanceInfo droneBatteryMaintenanceInfo; + + private FlighttaskStepCodeEnum flighttaskStepCode; + + private Integer flighttaskPrepareCapacity; + + private MediaFileDetail mediaFileDetail; + + private WirelessLink wirelessLink; + + private DrcStateEnum drcState; + + public OsdDock() { + } + + @Override + public String toString() { + return "OsdDock{" + + "networkState=" + networkState + + ", droneInDock=" + droneInDock + + ", droneChargeState=" + droneChargeState + + ", rainfall=" + rainfall + + ", windSpeed=" + windSpeed + + ", environmentTemperature=" + environmentTemperature + + ", temperature=" + temperature + + ", humidity=" + humidity + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + ", alternateLandPoint=" + alternateLandPoint + + ", firstPowerOn=" + firstPowerOn + + ", positionState=" + positionState + + ", storage=" + storage + + ", modeCode=" + modeCode + + ", coverState=" + coverState + + ", supplementLightState=" + supplementLightState + + ", emergencyStopState=" + emergencyStopState + + ", airConditioner=" + airConditioner + + ", batteryStoreMode=" + batteryStoreMode + + ", alarmState=" + alarmState + + ", putterState=" + putterState + + ", subDevice=" + subDevice + + ", jobNumber=" + jobNumber + + ", accTime=" + accTime + + ", activationTime=" + activationTime + + ", maintainStatus=" + maintainStatus + + ", electricSupplyVoltage=" + electricSupplyVoltage + + ", workingVoltage=" + workingVoltage + + ", workingCurrent=" + workingCurrent + + ", backupBattery=" + backupBattery + + ", droneBatteryMaintenanceInfo=" + droneBatteryMaintenanceInfo + + ", flighttaskStepCode=" + flighttaskStepCode + + ", flighttaskPrepareCapacity=" + flighttaskPrepareCapacity + + ", mediaFileDetail=" + mediaFileDetail + + ", wirelessLink=" + wirelessLink + + ", drcState=" + drcState + + '}'; + } + + public NetworkState getNetworkState() { + return networkState; + } + + public OsdDock setNetworkState(NetworkState networkState) { + this.networkState = networkState; + return this; + } + + public Boolean getDroneInDock() { + return droneInDock; + } + + public OsdDock setDroneInDock(Boolean droneInDock) { + this.droneInDock = droneInDock; + return this; + } + + public DroneChargeState getDroneChargeState() { + return droneChargeState; + } + + public OsdDock setDroneChargeState(DroneChargeState droneChargeState) { + this.droneChargeState = droneChargeState; + return this; + } + + public RainfallEnum getRainfall() { + return rainfall; + } + + public OsdDock setRainfall(RainfallEnum rainfall) { + this.rainfall = rainfall; + return this; + } + + public Float getWindSpeed() { + return windSpeed; + } + + public OsdDock setWindSpeed(Float windSpeed) { + this.windSpeed = windSpeed; + return this; + } + + public Float getEnvironmentTemperature() { + return environmentTemperature; + } + + public OsdDock setEnvironmentTemperature(Float environmentTemperature) { + this.environmentTemperature = environmentTemperature; + return this; + } + + public Float getTemperature() { + return temperature; + } + + public OsdDock setTemperature(Float temperature) { + this.temperature = temperature; + return this; + } + + public Integer getHumidity() { + return humidity; + } + + public OsdDock setHumidity(Integer humidity) { + this.humidity = humidity; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public OsdDock setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public OsdDock setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public OsdDock setHeight(Float height) { + this.height = height; + return this; + } + + public AlternateLandPoint getAlternateLandPoint() { + return alternateLandPoint; + } + + public OsdDock setAlternateLandPoint(AlternateLandPoint alternateLandPoint) { + this.alternateLandPoint = alternateLandPoint; + return this; + } + + public Long getFirstPowerOn() { + return firstPowerOn; + } + + public OsdDock setFirstPowerOn(Long firstPowerOn) { + this.firstPowerOn = firstPowerOn; + return this; + } + + public DockPositionState getPositionState() { + return positionState; + } + + public OsdDock setPositionState(DockPositionState positionState) { + this.positionState = positionState; + return this; + } + + public Storage getStorage() { + return storage; + } + + public OsdDock setStorage(Storage storage) { + this.storage = storage; + return this; + } + + public DockModeCodeEnum getModeCode() { + return modeCode; + } + + public OsdDock setModeCode(DockModeCodeEnum modeCode) { + this.modeCode = modeCode; + return this; + } + + public CoverStateEnum getCoverState() { + return coverState; + } + + public OsdDock setCoverState(CoverStateEnum coverState) { + this.coverState = coverState; + return this; + } + + public Boolean getSupplementLightState() { + return supplementLightState; + } + + public OsdDock setSupplementLightState(Boolean supplementLightState) { + this.supplementLightState = supplementLightState; + return this; + } + + public Boolean getEmergencyStopState() { + return emergencyStopState; + } + + public OsdDock setEmergencyStopState(Boolean emergencyStopState) { + this.emergencyStopState = emergencyStopState; + return this; + } + + public AirConditioner getAirConditioner() { + return airConditioner; + } + + public OsdDock setAirConditioner(AirConditioner airConditioner) { + this.airConditioner = airConditioner; + return this; + } + + public BatteryStoreModeEnum getBatteryStoreMode() { + return batteryStoreMode; + } + + public OsdDock setBatteryStoreMode(BatteryStoreModeEnum batteryStoreMode) { + this.batteryStoreMode = batteryStoreMode; + return this; + } + + public Boolean getAlarmState() { + return alarmState; + } + + public OsdDock setAlarmState(Boolean alarmState) { + this.alarmState = alarmState; + return this; + } + + public PutterStateEnum getPutterState() { + return putterState; + } + + public OsdDock setPutterState(PutterStateEnum putterState) { + this.putterState = putterState; + return this; + } + + public DockSubDevice getSubDevice() { + return subDevice; + } + + public OsdDock setSubDevice(DockSubDevice subDevice) { + this.subDevice = subDevice; + return this; + } + + public Integer getJobNumber() { + return jobNumber; + } + + public OsdDock setJobNumber(Integer jobNumber) { + this.jobNumber = jobNumber; + return this; + } + + public Long getAccTime() { + return accTime; + } + + public OsdDock setAccTime(Long accTime) { + this.accTime = accTime; + return this; + } + + public Long getActivationTime() { + return activationTime; + } + + public OsdDock setActivationTime(Long activationTime) { + this.activationTime = activationTime; + return this; + } + + public OsdDockMaintainStatus getMaintainStatus() { + return maintainStatus; + } + + public OsdDock setMaintainStatus(OsdDockMaintainStatus maintainStatus) { + this.maintainStatus = maintainStatus; + return this; + } + + public Integer getElectricSupplyVoltage() { + return electricSupplyVoltage; + } + + public OsdDock setElectricSupplyVoltage(Integer electricSupplyVoltage) { + this.electricSupplyVoltage = electricSupplyVoltage; + return this; + } + + public Integer getWorkingVoltage() { + return workingVoltage; + } + + public OsdDock setWorkingVoltage(Integer workingVoltage) { + this.workingVoltage = workingVoltage; + return this; + } + + public Integer getWorkingCurrent() { + return workingCurrent; + } + + public OsdDock setWorkingCurrent(Integer workingCurrent) { + this.workingCurrent = workingCurrent; + return this; + } + + public BackupBattery getBackupBattery() { + return backupBattery; + } + + public OsdDock setBackupBattery(BackupBattery backupBattery) { + this.backupBattery = backupBattery; + return this; + } + + public DroneBatteryMaintenanceInfo getDroneBatteryMaintenanceInfo() { + return droneBatteryMaintenanceInfo; + } + + public OsdDock setDroneBatteryMaintenanceInfo(DroneBatteryMaintenanceInfo droneBatteryMaintenanceInfo) { + this.droneBatteryMaintenanceInfo = droneBatteryMaintenanceInfo; + return this; + } + + public FlighttaskStepCodeEnum getFlighttaskStepCode() { + return flighttaskStepCode; + } + + public OsdDock setFlighttaskStepCode(FlighttaskStepCodeEnum flighttaskStepCode) { + this.flighttaskStepCode = flighttaskStepCode; + return this; + } + + public Integer getFlighttaskPrepareCapacity() { + return flighttaskPrepareCapacity; + } + + public OsdDock setFlighttaskPrepareCapacity(Integer flighttaskPrepareCapacity) { + this.flighttaskPrepareCapacity = flighttaskPrepareCapacity; + return this; + } + + public MediaFileDetail getMediaFileDetail() { + return mediaFileDetail; + } + + public OsdDock setMediaFileDetail(MediaFileDetail mediaFileDetail) { + this.mediaFileDetail = mediaFileDetail; + return this; + } + + public WirelessLink getWirelessLink() { + return wirelessLink; + } + + public OsdDock setWirelessLink(WirelessLink wirelessLink) { + this.wirelessLink = wirelessLink; + return this; + } + + public DrcStateEnum getDrcState() { + return drcState; + } + + public OsdDock setDrcState(DrcStateEnum drcState) { + this.drcState = drcState; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/OsdDockDrone.java b/src/main/java/com/dji/sdk/cloudapi/device/OsdDockDrone.java new file mode 100644 index 0000000..d7e2176 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/OsdDockDrone.java @@ -0,0 +1,469 @@ +package com.dji.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class OsdDockDrone { + + private Float attitudeHead; + + private Double attitudePitch; + + private Double attitudeRoll; + + private Float elevation; + + private DroneBattery battery; + + private String firmwareVersion; + + private GearEnum gear; + + private Float height; + + private Float homeDistance; + + private Float horizontalSpeed; + + private Float latitude; + + private Float longitude; + + private DroneModeCodeEnum modeCode; + + private Double totalFlightDistance; + + private Float totalFlightTime; + + private Float verticalSpeed; + + private WindDirectionEnum windDirection; + + private Float windSpeed; + + private DronePositionState positionState; + + @JsonProperty(PayloadModelEnum.PAYLOAD_KEY) + private List payloads; + + private Storage storage; + + private SwitchActionEnum nightLightsState; + + private Integer heightLimit; + + private DockDistanceLimitStatus distanceLimitStatus; + + private ObstacleAvoidance obstacleAvoidance; + + private Long activationTime; + + private List cameras; + + private RcLostActionEnum rcLostAction; + + private Integer rthAltitude; + + private Integer totalFlightSorties; + + private ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost; + + private String country; + + private Boolean ridState; + + @JsonProperty("is_near_area_limit") + private Boolean nearAreaLimit; + + @JsonProperty("is_near_height_limit") + private Boolean nearHeightLimit; + + private OsdDroneMaintainStatus maintainStatus; + + private String trackId; + + public OsdDockDrone() { + } + + @Override + public String toString() { + return "OsdDockDrone{" + + "attitudeHead=" + attitudeHead + + ", attitudePitch=" + attitudePitch + + ", attitudeRoll=" + attitudeRoll + + ", elevation=" + elevation + + ", battery=" + battery + + ", firmwareVersion='" + firmwareVersion + '\'' + + ", gear=" + gear + + ", height=" + height + + ", homeDistance=" + homeDistance + + ", horizontalSpeed=" + horizontalSpeed + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", modeCode=" + modeCode + + ", totalFlightDistance=" + totalFlightDistance + + ", totalFlightTime=" + totalFlightTime + + ", verticalSpeed=" + verticalSpeed + + ", windDirection=" + windDirection + + ", windSpeed=" + windSpeed + + ", positionState=" + positionState + + ", payloads=" + payloads + + ", storage=" + storage + + ", nightLightsState=" + nightLightsState + + ", heightLimit=" + heightLimit + + ", distanceLimitStatus=" + distanceLimitStatus + + ", obstacleAvoidance=" + obstacleAvoidance + + ", activationTime=" + activationTime + + ", cameras=" + cameras + + ", rcLostAction=" + rcLostAction + + ", rthAltitude=" + rthAltitude + + ", totalFlightSorties=" + totalFlightSorties + + ", exitWaylineWhenRcLost=" + exitWaylineWhenRcLost + + ", country='" + country + '\'' + + ", ridState=" + ridState + + ", nearAreaLimit=" + nearAreaLimit + + ", nearHeightLimit=" + nearHeightLimit + + ", maintainStatus=" + maintainStatus + + ", trackId='" + trackId + '\'' + + '}'; + } + + public Float getAttitudeHead() { + return attitudeHead; + } + + public OsdDockDrone setAttitudeHead(Float attitudeHead) { + this.attitudeHead = attitudeHead; + return this; + } + + public Double getAttitudePitch() { + return attitudePitch; + } + + public OsdDockDrone setAttitudePitch(Double attitudePitch) { + this.attitudePitch = attitudePitch; + return this; + } + + public Double getAttitudeRoll() { + return attitudeRoll; + } + + public OsdDockDrone setAttitudeRoll(Double attitudeRoll) { + this.attitudeRoll = attitudeRoll; + return this; + } + + public Float getElevation() { + return elevation; + } + + public OsdDockDrone setElevation(Float elevation) { + this.elevation = elevation; + return this; + } + + public DroneBattery getBattery() { + return battery; + } + + public OsdDockDrone setBattery(DroneBattery battery) { + this.battery = battery; + return this; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public OsdDockDrone setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } + + public GearEnum getGear() { + return gear; + } + + public OsdDockDrone setGear(GearEnum gear) { + this.gear = gear; + return this; + } + + public Float getHeight() { + return height; + } + + public OsdDockDrone setHeight(Float height) { + this.height = height; + return this; + } + + public Float getHomeDistance() { + return homeDistance; + } + + public OsdDockDrone setHomeDistance(Float homeDistance) { + this.homeDistance = homeDistance; + return this; + } + + public Float getHorizontalSpeed() { + return horizontalSpeed; + } + + public OsdDockDrone setHorizontalSpeed(Float horizontalSpeed) { + this.horizontalSpeed = horizontalSpeed; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public OsdDockDrone setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public OsdDockDrone setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public DroneModeCodeEnum getModeCode() { + return modeCode; + } + + public OsdDockDrone setModeCode(DroneModeCodeEnum modeCode) { + this.modeCode = modeCode; + return this; + } + + public Double getTotalFlightDistance() { + return totalFlightDistance; + } + + public OsdDockDrone setTotalFlightDistance(Double totalFlightDistance) { + this.totalFlightDistance = totalFlightDistance; + return this; + } + + public Float getTotalFlightTime() { + return totalFlightTime; + } + + public OsdDockDrone setTotalFlightTime(Float totalFlightTime) { + this.totalFlightTime = totalFlightTime; + return this; + } + + public Float getVerticalSpeed() { + return verticalSpeed; + } + + public OsdDockDrone setVerticalSpeed(Float verticalSpeed) { + this.verticalSpeed = verticalSpeed; + return this; + } + + public WindDirectionEnum getWindDirection() { + return windDirection; + } + + public OsdDockDrone setWindDirection(WindDirectionEnum windDirection) { + this.windDirection = windDirection; + return this; + } + + public Float getWindSpeed() { + return windSpeed; + } + + public OsdDockDrone setWindSpeed(Float windSpeed) { + this.windSpeed = windSpeed; + return this; + } + + public DronePositionState getPositionState() { + return positionState; + } + + public OsdDockDrone setPositionState(DronePositionState positionState) { + this.positionState = positionState; + return this; + } + + public List getPayloads() { + return payloads; + } + + public OsdDockDrone setPayloads(List payloads) { + this.payloads = payloads; + return this; + } + + public Storage getStorage() { + return storage; + } + + public OsdDockDrone setStorage(Storage storage) { + this.storage = storage; + return this; + } + + public SwitchActionEnum getNightLightsState() { + return nightLightsState; + } + + public OsdDockDrone setNightLightsState(SwitchActionEnum nightLightsState) { + this.nightLightsState = nightLightsState; + return this; + } + + public Integer getHeightLimit() { + return heightLimit; + } + + public OsdDockDrone setHeightLimit(Integer heightLimit) { + this.heightLimit = heightLimit; + return this; + } + + public DockDistanceLimitStatus getDistanceLimitStatus() { + return distanceLimitStatus; + } + + public OsdDockDrone setDistanceLimitStatus(DockDistanceLimitStatus distanceLimitStatus) { + this.distanceLimitStatus = distanceLimitStatus; + return this; + } + + public ObstacleAvoidance getObstacleAvoidance() { + return obstacleAvoidance; + } + + public OsdDockDrone setObstacleAvoidance(ObstacleAvoidance obstacleAvoidance) { + this.obstacleAvoidance = obstacleAvoidance; + return this; + } + + public Long getActivationTime() { + return activationTime; + } + + public OsdDockDrone setActivationTime(Long activationTime) { + this.activationTime = activationTime; + return this; + } + + public List getCameras() { + return cameras; + } + + public OsdDockDrone setCameras(List cameras) { + this.cameras = cameras; + return this; + } + + public RcLostActionEnum getRcLostAction() { + return rcLostAction; + } + + public OsdDockDrone setRcLostAction(RcLostActionEnum rcLostAction) { + this.rcLostAction = rcLostAction; + return this; + } + + public Integer getRthAltitude() { + return rthAltitude; + } + + public OsdDockDrone setRthAltitude(Integer rthAltitude) { + this.rthAltitude = rthAltitude; + return this; + } + + public Integer getTotalFlightSorties() { + return totalFlightSorties; + } + + public OsdDockDrone setTotalFlightSorties(Integer totalFlightSorties) { + this.totalFlightSorties = totalFlightSorties; + return this; + } + + public ExitWaylineWhenRcLostEnum getExitWaylineWhenRcLost() { + return exitWaylineWhenRcLost; + } + + public OsdDockDrone setExitWaylineWhenRcLost(ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost) { + this.exitWaylineWhenRcLost = exitWaylineWhenRcLost; + return this; + } + + public String getCountry() { + return country; + } + + public OsdDockDrone setCountry(String country) { + this.country = country; + return this; + } + + public Boolean getRidState() { + return ridState; + } + + public OsdDockDrone setRidState(Boolean ridState) { + this.ridState = ridState; + return this; + } + + public Boolean getNearAreaLimit() { + return nearAreaLimit; + } + + public OsdDockDrone setNearAreaLimit(Boolean nearAreaLimit) { + this.nearAreaLimit = nearAreaLimit; + return this; + } + + public Boolean getNearHeightLimit() { + return nearHeightLimit; + } + + public OsdDockDrone setNearHeightLimit(Boolean nearHeightLimit) { + this.nearHeightLimit = nearHeightLimit; + return this; + } + + public OsdDroneMaintainStatus getMaintainStatus() { + return maintainStatus; + } + + public OsdDockDrone setMaintainStatus(OsdDroneMaintainStatus maintainStatus) { + this.maintainStatus = maintainStatus; + return this; + } + + public String getTrackId() { + return trackId; + } + + public OsdDockDrone setTrackId(String trackId) { + this.trackId = trackId; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/OsdDockMaintainStatus.java b/src/main/java/com/dji/sdk/cloudapi/device/OsdDockMaintainStatus.java new file mode 100644 index 0000000..65951b6 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/OsdDockMaintainStatus.java @@ -0,0 +1,32 @@ +package com.dji.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class OsdDockMaintainStatus { + + private List maintainStatusArray; + + public OsdDockMaintainStatus() { + } + + @Override + public String toString() { + return "OsdDroneMaintainStatus{" + + "maintainStatusArray=" + maintainStatusArray + + '}'; + } + + public List getMaintainStatusArray() { + return maintainStatusArray; + } + + public OsdDockMaintainStatus setMaintainStatusArray(List maintainStatusArray) { + this.maintainStatusArray = maintainStatusArray; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/OsdDroneMaintainStatus.java b/src/main/java/com/dji/sdk/cloudapi/device/OsdDroneMaintainStatus.java new file mode 100644 index 0000000..91208d6 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/OsdDroneMaintainStatus.java @@ -0,0 +1,32 @@ +package com.dji.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class OsdDroneMaintainStatus { + + private List maintainStatusArray; + + public OsdDroneMaintainStatus() { + } + + @Override + public String toString() { + return "OsdDroneMaintainStatus{" + + "maintainStatusArray=" + maintainStatusArray + + '}'; + } + + public List getMaintainStatusArray() { + return maintainStatusArray; + } + + public OsdDroneMaintainStatus setMaintainStatusArray(List maintainStatusArray) { + this.maintainStatusArray = maintainStatusArray; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/OsdRcDrone.java b/src/main/java/com/dji/sdk/cloudapi/device/OsdRcDrone.java new file mode 100644 index 0000000..feb3127 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/OsdRcDrone.java @@ -0,0 +1,311 @@ +package com.dji.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class OsdRcDrone { + + private Float attitudeHead; + + private Double attitudePitch; + + private Double attitudeRoll; + + private Float elevation; + + private DroneBattery battery; + + private String firmwareVersion; + + private GearEnum gear; + + private Float height; + + private Float homeDistance; + + private Float horizontalSpeed; + + private Float latitude; + + private Float longitude; + + private DroneModeCodeEnum modeCode; + + private Double totalFlightDistance; + + private Float totalFlightTime; + + private Float verticalSpeed; + + private WindDirectionEnum windDirection; + + private Float windSpeed; + + private DronePositionState positionState; + + @JsonProperty(PayloadModelEnum.PAYLOAD_KEY) + private List payloads; + + private Storage storage; + + private Integer heightLimit; + + private RcDistanceLimitStatus distanceLimitStatus; + + private String trackId; + + public OsdRcDrone() { + } + + @Override + public String toString() { + return "OsdRcDrone{" + + "attitudeHead=" + attitudeHead + + ", attitudePitch=" + attitudePitch + + ", attitudeRoll=" + attitudeRoll + + ", elevation=" + elevation + + ", battery=" + battery + + ", firmwareVersion='" + firmwareVersion + '\'' + + ", gear=" + gear + + ", height=" + height + + ", homeDistance=" + homeDistance + + ", horizontalSpeed=" + horizontalSpeed + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", modeCode=" + modeCode + + ", totalFlightDistance=" + totalFlightDistance + + ", totalFlightTime=" + totalFlightTime + + ", verticalSpeed=" + verticalSpeed + + ", windDirection=" + windDirection + + ", windSpeed=" + windSpeed + + ", positionState=" + positionState + + ", payloads=" + payloads + + ", storage=" + storage + + ", heightLimit=" + heightLimit + + ", distanceLimitStatus=" + distanceLimitStatus + + ", trackId='" + trackId + '\'' + + '}'; + } + + public Float getAttitudeHead() { + return attitudeHead; + } + + public OsdRcDrone setAttitudeHead(Float attitudeHead) { + this.attitudeHead = attitudeHead; + return this; + } + + public Double getAttitudePitch() { + return attitudePitch; + } + + public OsdRcDrone setAttitudePitch(Double attitudePitch) { + this.attitudePitch = attitudePitch; + return this; + } + + public Double getAttitudeRoll() { + return attitudeRoll; + } + + public OsdRcDrone setAttitudeRoll(Double attitudeRoll) { + this.attitudeRoll = attitudeRoll; + return this; + } + + public Float getElevation() { + return elevation; + } + + public OsdRcDrone setElevation(Float elevation) { + this.elevation = elevation; + return this; + } + + public DroneBattery getBattery() { + return battery; + } + + public OsdRcDrone setBattery(DroneBattery battery) { + this.battery = battery; + return this; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public OsdRcDrone setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } + + public GearEnum getGear() { + return gear; + } + + public OsdRcDrone setGear(GearEnum gear) { + this.gear = gear; + return this; + } + + public Float getHeight() { + return height; + } + + public OsdRcDrone setHeight(Float height) { + this.height = height; + return this; + } + + public Float getHomeDistance() { + return homeDistance; + } + + public OsdRcDrone setHomeDistance(Float homeDistance) { + this.homeDistance = homeDistance; + return this; + } + + public Float getHorizontalSpeed() { + return horizontalSpeed; + } + + public OsdRcDrone setHorizontalSpeed(Float horizontalSpeed) { + this.horizontalSpeed = horizontalSpeed; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public OsdRcDrone setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public OsdRcDrone setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public DroneModeCodeEnum getModeCode() { + return modeCode; + } + + public OsdRcDrone setModeCode(DroneModeCodeEnum modeCode) { + this.modeCode = modeCode; + return this; + } + + public Double getTotalFlightDistance() { + return totalFlightDistance; + } + + public OsdRcDrone setTotalFlightDistance(Double totalFlightDistance) { + this.totalFlightDistance = totalFlightDistance; + return this; + } + + public Float getTotalFlightTime() { + return totalFlightTime; + } + + public OsdRcDrone setTotalFlightTime(Float totalFlightTime) { + this.totalFlightTime = totalFlightTime; + return this; + } + + public Float getVerticalSpeed() { + return verticalSpeed; + } + + public OsdRcDrone setVerticalSpeed(Float verticalSpeed) { + this.verticalSpeed = verticalSpeed; + return this; + } + + public WindDirectionEnum getWindDirection() { + return windDirection; + } + + public OsdRcDrone setWindDirection(WindDirectionEnum windDirection) { + this.windDirection = windDirection; + return this; + } + + public Float getWindSpeed() { + return windSpeed; + } + + public OsdRcDrone setWindSpeed(Float windSpeed) { + this.windSpeed = windSpeed; + return this; + } + + public DronePositionState getPositionState() { + return positionState; + } + + public OsdRcDrone setPositionState(DronePositionState positionState) { + this.positionState = positionState; + return this; + } + + public List getPayloads() { + return payloads; + } + + public OsdRcDrone setPayloads(List payloads) { + this.payloads = payloads; + return this; + } + + public Storage getStorage() { + return storage; + } + + public OsdRcDrone setStorage(Storage storage) { + this.storage = storage; + return this; + } + + public Integer getHeightLimit() { + return heightLimit; + } + + public OsdRcDrone setHeightLimit(Integer heightLimit) { + this.heightLimit = heightLimit; + return this; + } + + public RcDistanceLimitStatus getDistanceLimitStatus() { + return distanceLimitStatus; + } + + public OsdRcDrone setDistanceLimitStatus(RcDistanceLimitStatus distanceLimitStatus) { + this.distanceLimitStatus = distanceLimitStatus; + return this; + } + + public String getTrackId() { + return trackId; + } + + public OsdRcDrone setTrackId(String trackId) { + this.trackId = trackId; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/OsdRemoteControl.java b/src/main/java/com/dji/sdk/cloudapi/device/OsdRemoteControl.java new file mode 100644 index 0000000..5493751 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/OsdRemoteControl.java @@ -0,0 +1,78 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class OsdRemoteControl { + + private Float latitude; + + private Float longitude; + + private Float height; + + private Integer capacityPercent; + + private WirelessLink wirelessLink; + + public OsdRemoteControl() { + } + + @Override + public String toString() { + return "OsdRemoteControl{" + + "latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + ", capacityPercent=" + capacityPercent + + ", wirelessLink=" + wirelessLink + + '}'; + } + + public Float getLatitude() { + return latitude; + } + + public OsdRemoteControl setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public OsdRemoteControl setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public OsdRemoteControl setHeight(Float height) { + this.height = height; + return this; + } + + public Integer getCapacityPercent() { + return capacityPercent; + } + + public OsdRemoteControl setCapacityPercent(Integer capacityPercent) { + this.capacityPercent = capacityPercent; + return this; + } + + public WirelessLink getWirelessLink() { + return wirelessLink; + } + + public OsdRemoteControl setWirelessLink(WirelessLink wirelessLink) { + this.wirelessLink = wirelessLink; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/PayloadFirmwareVersion.java b/src/main/java/com/dji/sdk/cloudapi/device/PayloadFirmwareVersion.java new file mode 100644 index 0000000..9fac3a1 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/PayloadFirmwareVersion.java @@ -0,0 +1,53 @@ +package com.dji.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonCreator; + +import java.util.Map; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/28 + */ +public class PayloadFirmwareVersion { + + private PayloadPositionEnum position; + + private String firmwareVersion; + + public PayloadFirmwareVersion() { + } + + @JsonCreator + public PayloadFirmwareVersion(Map map) { + Map.Entry entry = (Map.Entry) map.entrySet().toArray()[0]; + this.position = PayloadPositionEnum.find(Integer.parseInt(entry.getKey().split("-")[1])); + this.firmwareVersion = ((Map) entry.getValue()).values().toArray(String[]::new)[0]; + } + + @Override + public String toString() { + return "PayloadFirmwareVersion{" + + "position=" + position + + ", firmwareVersion='" + firmwareVersion + '\'' + + '}'; + } + + public PayloadPositionEnum getPosition() { + return position; + } + + public PayloadFirmwareVersion setPosition(PayloadPositionEnum position) { + this.position = position; + return this; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public PayloadFirmwareVersion setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/PayloadIndex.java b/src/main/java/com/dji/sdk/cloudapi/device/PayloadIndex.java new file mode 100644 index 0000000..c3c842f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/PayloadIndex.java @@ -0,0 +1,75 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class PayloadIndex { + + @NotNull + private DeviceTypeEnum type; + + @NotNull + private DeviceSubTypeEnum subType; + + @NotNull + private PayloadPositionEnum position; + + public PayloadIndex() { + } + + @JsonCreator + public PayloadIndex(String payloadIndex) { + Objects.requireNonNull(payloadIndex); + int[] payloadIndexArr = Arrays.stream(payloadIndex.split("-")).mapToInt(Integer::parseInt).toArray(); + if (payloadIndexArr.length != 3) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + this.type = DeviceTypeEnum.find(payloadIndexArr[0]); + this.subType = DeviceSubTypeEnum.find(payloadIndexArr[1]); + this.position = PayloadPositionEnum.find(payloadIndexArr[2]); + } + + @Override + @JsonValue + public String toString() { + return String.format("%s-%s-%s", type.getType(), subType.getSubType(), position.getPosition()); + } + + public DeviceTypeEnum getType() { + return type; + } + + public PayloadIndex setType(DeviceTypeEnum type) { + this.type = type; + return this; + } + + public DeviceSubTypeEnum getSubType() { + return subType; + } + + public PayloadIndex setSubType(DeviceSubTypeEnum subType) { + this.subType = subType; + return this; + } + + public PayloadPositionEnum getPosition() { + return position; + } + + public PayloadIndex setPosition(PayloadPositionEnum position) { + this.position = position; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/PayloadModelEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/PayloadModelEnum.java new file mode 100644 index 0000000..e1c86c1 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/PayloadModelEnum.java @@ -0,0 +1,77 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; + +import java.util.Arrays; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/29 + */ +public enum PayloadModelEnum { + + Z30("Z30", "20-0"), + + XT2("XT2", "26-0"), + + XTS("XTS", "41-0"), + + H20("H20", "42-0"), + + H20T("H20T", "43-0"), + + P1("P1", "50-65535"), + + M30("M30", "52-0"), + + M30T("M30T", "53-0"), + + H20N("H20N", "61-0"), + + DOCK("DOCK", "165-0"), + + L1("L1", "90742-0"); + + public static final String PAYLOAD_KEY = "payload"; + + private final String model; + + private final String index; + + PayloadModelEnum(String model, String index) { + this.model = model; + this.index = index; + } + + public String getModel() { + return model; + } + + public String getIndex() { + return index; + } + + public static Set getAllModelWithPosition() { + Set position = Arrays.stream(PayloadPositionEnum.values()).map(PayloadPositionEnum::getPosition) + .map(String::valueOf).collect(Collectors.toSet()); + return Arrays.stream(values()).map(PayloadModelEnum::getModel).map(m -> position.stream().map(p -> m.concat("-").concat(p))) + .flatMap(Function.identity()).collect(Collectors.toSet()); + } + + public static Set getAllIndexWithPosition() { + Set position = Arrays.stream(PayloadPositionEnum.values()).map(PayloadPositionEnum::getPosition) + .map(String::valueOf).collect(Collectors.toSet()); + return Arrays.stream(values()).map(PayloadModelEnum::getIndex).map(m -> position.stream().map(p -> m.concat("-").concat(p))) + .flatMap(Function.identity()).collect(Collectors.toSet()); + } + + public static PayloadModelEnum find(String model) { + return Arrays.stream(values()).filter(modelEnum -> modelEnum.model.equals(model)).findAny() + .orElseThrow(() -> new CloudSDKException(PayloadModelEnum.class, model)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/PayloadPositionEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/PayloadPositionEnum.java new file mode 100644 index 0000000..a4bbab9 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/PayloadPositionEnum.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/25 + */ +public enum PayloadPositionEnum { + + FRONT_LEFT(0), + + FRONT_RIGHT(1), + + TOP(2), + + FPV(7); + + private final int position; + + PayloadPositionEnum(int position) { + this.position = position; + } + + @JsonValue + public int getPosition() { + return position; + } + + @JsonCreator + public static PayloadPositionEnum find(int position) { + return Arrays.stream(values()).filter(positionEnum -> positionEnum.position == position).findAny() + .orElseThrow(() -> new CloudSDKException(PayloadPositionEnum.class, position)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/PositionFixedEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/PositionFixedEnum.java new file mode 100644 index 0000000..7761bdb --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/PositionFixedEnum.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum PositionFixedEnum { + + NOT_START(0), + + FIXING(1), + + SUCCESSFUL(2), + + FAILED(3), + ; + + private final int fixed; + + PositionFixedEnum(int fixed) { + this.fixed = fixed; + } + + @JsonValue + public int getFixed() { + return fixed; + } + + @JsonCreator + public static PositionFixedEnum find(int fixed) { + return Arrays.stream(values()).filter(fixedEnum -> fixedEnum.fixed == fixed).findAny() + .orElseThrow(() -> new CloudSDKException(PositionFixedEnum.class, fixed)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/PutterStateEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/PutterStateEnum.java new file mode 100644 index 0000000..6ce47dc --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/PutterStateEnum.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum PutterStateEnum { + + CLOSED(0), + + OPENED(1), + + HALF_OPEN(2), + + ABNORMAL(3), + ; + + private final int state; + + PutterStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static PutterStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(PutterStateEnum.class, state)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/RainfallEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/RainfallEnum.java new file mode 100644 index 0000000..7d46b8e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/RainfallEnum.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum RainfallEnum { + + NO(0), + + LIGHT(1), + + MODERATE(2), + + HEAVY(3), + ; + + private final int rain; + + RainfallEnum(int rain) { + this.rain = rain; + } + + @JsonValue + public int getRain() { + return rain; + } + + @JsonCreator + public static RainfallEnum find(int rain) { + return Arrays.stream(values()).filter(rainEnum -> rainEnum.rain == rain).findAny() + .orElseThrow(() -> new CloudSDKException(RainfallEnum.class, rain)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/RcDistanceLimitStatus.java b/src/main/java/com/dji/sdk/cloudapi/device/RcDistanceLimitStatus.java new file mode 100644 index 0000000..e84edbb --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/RcDistanceLimitStatus.java @@ -0,0 +1,43 @@ +package com.dji.sdk.cloudapi.device; + +/** + * The state of the drone's limited distance + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class RcDistanceLimitStatus { + + private Integer state; + + private Integer distanceLimit; + + public RcDistanceLimitStatus() { + } + + @Override + public String toString() { + return "RcDistanceLimitStatusSet{" + + "state=" + state + + ", distanceLimit=" + distanceLimit + + '}'; + } + + public Integer getState() { + return state; + } + + public RcDistanceLimitStatus setState(Integer state) { + this.state = state; + return this; + } + + public Integer getDistanceLimit() { + return distanceLimit; + } + + public RcDistanceLimitStatus setDistanceLimit(Integer distanceLimit) { + this.distanceLimit = distanceLimit; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/RcDroneControlSource.java b/src/main/java/com/dji/sdk/cloudapi/device/RcDroneControlSource.java new file mode 100644 index 0000000..6939ac3 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/RcDroneControlSource.java @@ -0,0 +1,92 @@ +package com.dji.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class RcDroneControlSource { + + private ControlSourceEnum controlSource; + + private Float homeLatitude; + + private Float homeLongitude; + + private Integer lowBatteryWarningThreshold; + + private Integer seriousLowBatteryWarningThreshold; + + private List payloads; + + public RcDroneControlSource() { + } + + @Override + public String toString() { + return "RcDroneControlSource{" + + "controlSource=" + controlSource + + ", homeLatitude=" + homeLatitude + + ", homeLongitude=" + homeLongitude + + ", lowBatteryWarningThreshold=" + lowBatteryWarningThreshold + + ", seriousLowBatteryWarningThreshold=" + seriousLowBatteryWarningThreshold + + ", payloads=" + payloads + + '}'; + } + + public ControlSourceEnum getControlSource() { + return controlSource; + } + + public RcDroneControlSource setControlSource(ControlSourceEnum controlSource) { + this.controlSource = controlSource; + return this; + } + + public Float getHomeLatitude() { + return homeLatitude; + } + + public RcDroneControlSource setHomeLatitude(Float homeLatitude) { + this.homeLatitude = homeLatitude; + return this; + } + + public Float getHomeLongitude() { + return homeLongitude; + } + + public RcDroneControlSource setHomeLongitude(Float homeLongitude) { + this.homeLongitude = homeLongitude; + return this; + } + + public Integer getLowBatteryWarningThreshold() { + return lowBatteryWarningThreshold; + } + + public RcDroneControlSource setLowBatteryWarningThreshold(Integer lowBatteryWarningThreshold) { + this.lowBatteryWarningThreshold = lowBatteryWarningThreshold; + return this; + } + + public Integer getSeriousLowBatteryWarningThreshold() { + return seriousLowBatteryWarningThreshold; + } + + public RcDroneControlSource setSeriousLowBatteryWarningThreshold(Integer seriousLowBatteryWarningThreshold) { + this.seriousLowBatteryWarningThreshold = seriousLowBatteryWarningThreshold; + return this; + } + + public List getPayloads() { + return payloads; + } + + public RcDroneControlSource setPayloads(List payloads) { + this.payloads = payloads; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/RcDronePayload.java b/src/main/java/com/dji/sdk/cloudapi/device/RcDronePayload.java new file mode 100644 index 0000000..30610ff --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/RcDronePayload.java @@ -0,0 +1,140 @@ +package com.dji.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/6 + */ +public class RcDronePayload { + + private PayloadIndex payloadIndex; + + private Float gimbalPitch; + + private Float gimbalRoll; + + private Float gimbalYaw; + + private Float measureTargetAltitude; + + private Float measureTargetDistance; + + private Float measureTargetLatitude; + + private Float measureTargetLongitude; + + private MeasureTargetStateEnum measureTargetErrorState; + + private List smartTrackPoint; + + public RcDronePayload() { + } + + @Override + public String toString() { + return "RcDronePayload{" + + "payloadIndex=" + payloadIndex + + ", gimbalPitch=" + gimbalPitch + + ", gimbalRoll=" + gimbalRoll + + ", gimbalYaw=" + gimbalYaw + + ", measureTargetAltitude=" + measureTargetAltitude + + ", measureTargetDistance=" + measureTargetDistance + + ", measureTargetLatitude=" + measureTargetLatitude + + ", measureTargetLongitude=" + measureTargetLongitude + + ", measureTargetErrorState=" + measureTargetErrorState + + ", smartTrackPoint=" + smartTrackPoint + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public RcDronePayload setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public Float getGimbalPitch() { + return gimbalPitch; + } + + public RcDronePayload setGimbalPitch(Float gimbalPitch) { + this.gimbalPitch = gimbalPitch; + return this; + } + + public Float getGimbalRoll() { + return gimbalRoll; + } + + public RcDronePayload setGimbalRoll(Float gimbalRoll) { + this.gimbalRoll = gimbalRoll; + return this; + } + + public Float getGimbalYaw() { + return gimbalYaw; + } + + public RcDronePayload setGimbalYaw(Float gimbalYaw) { + this.gimbalYaw = gimbalYaw; + return this; + } + + public Float getMeasureTargetAltitude() { + return measureTargetAltitude; + } + + public RcDronePayload setMeasureTargetAltitude(Float measureTargetAltitude) { + this.measureTargetAltitude = measureTargetAltitude; + return this; + } + + public Float getMeasureTargetDistance() { + return measureTargetDistance; + } + + public RcDronePayload setMeasureTargetDistance(Float measureTargetDistance) { + this.measureTargetDistance = measureTargetDistance; + return this; + } + + public Float getMeasureTargetLatitude() { + return measureTargetLatitude; + } + + public RcDronePayload setMeasureTargetLatitude(Float measureTargetLatitude) { + this.measureTargetLatitude = measureTargetLatitude; + return this; + } + + public Float getMeasureTargetLongitude() { + return measureTargetLongitude; + } + + public RcDronePayload setMeasureTargetLongitude(Float measureTargetLongitude) { + this.measureTargetLongitude = measureTargetLongitude; + return this; + } + + public MeasureTargetStateEnum getMeasureTargetErrorState() { + return measureTargetErrorState; + } + + public RcDronePayload setMeasureTargetErrorState(MeasureTargetStateEnum measureTargetErrorState) { + this.measureTargetErrorState = measureTargetErrorState; + return this; + } + + public List getSmartTrackPoint() { + return smartTrackPoint; + } + + public RcDronePayload setSmartTrackPoint(List smartTrackPoint) { + this.smartTrackPoint = smartTrackPoint; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/RcFirmwareVersion.java b/src/main/java/com/dji/sdk/cloudapi/device/RcFirmwareVersion.java new file mode 100644 index 0000000..f9f3a19 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/RcFirmwareVersion.java @@ -0,0 +1,31 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/28 + */ +public class RcFirmwareVersion { + + private String firmwareVersion; + + public RcFirmwareVersion() { + } + + @Override + public String toString() { + return "RcFirmwareVersion{" + + "firmwareVersion='" + firmwareVersion + '\'' + + '}'; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public RcFirmwareVersion setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/RcLiveStatus.java b/src/main/java/com/dji/sdk/cloudapi/device/RcLiveStatus.java new file mode 100644 index 0000000..19a4262 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/RcLiveStatus.java @@ -0,0 +1,32 @@ +package com.dji.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class RcLiveStatus { + + private List liveStatus; + + public RcLiveStatus() { + } + + @Override + public String toString() { + return "RcLiveStatus{" + + "liveStatus=" + liveStatus + + '}'; + } + + public List getLiveStatus() { + return liveStatus; + } + + public RcLiveStatus setLiveStatus(List liveStatus) { + this.liveStatus = liveStatus; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/RcLiveStatusData.java b/src/main/java/com/dji/sdk/cloudapi/device/RcLiveStatusData.java new file mode 100644 index 0000000..05c779a --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/RcLiveStatusData.java @@ -0,0 +1,56 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.cloudapi.livestream.VideoQualityEnum; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class RcLiveStatusData { + + private Boolean status; + + private VideoId videoId; + + private VideoQualityEnum videoQuality; + + public RcLiveStatusData() { + } + + @Override + public String toString() { + return "RcLiveStatusData{" + + "status=" + status + + ", videoId=" + videoId + + ", videoQuality=" + videoQuality + + '}'; + } + + public Boolean getStatus() { + return status; + } + + public RcLiveStatusData setStatus(Boolean status) { + this.status = status; + return this; + } + + public VideoId getVideoId() { + return videoId; + } + + public RcLiveStatusData setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } + + public VideoQualityEnum getVideoQuality() { + return videoQuality; + } + + public RcLiveStatusData setVideoQuality(VideoQualityEnum videoQuality) { + this.videoQuality = videoQuality; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/RcLostActionEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/RcLostActionEnum.java new file mode 100644 index 0000000..04f1c08 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/RcLostActionEnum.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public enum RcLostActionEnum { + + HOVER(0), + + LAND(1), + + RETURN_HOME(2); + + private final int action; + + RcLostActionEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static RcLostActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.ordinal() == action).findAny() + .orElseThrow(() -> new CloudSDKException(RcLostActionEnum.class, action)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/RcPayloadControlSource.java b/src/main/java/com/dji/sdk/cloudapi/device/RcPayloadControlSource.java new file mode 100644 index 0000000..7eed484 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/RcPayloadControlSource.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class RcPayloadControlSource { + + private ControlSourceEnum controlSource; + + private PayloadIndex payloadIndex; + + private String sn; + + private String firmwareVersion; + + public RcPayloadControlSource() { + } + + @Override + public String toString() { + return "RcPayloadControlSource{" + + "controlSource=" + controlSource + + ", payloadIndex=" + payloadIndex + + ", sn='" + sn + '\'' + + ", firmwareVersion='" + firmwareVersion + '\'' + + '}'; + } + + public ControlSourceEnum getControlSource() { + return controlSource; + } + + public RcPayloadControlSource setControlSource(ControlSourceEnum controlSource) { + this.controlSource = controlSource; + return this; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public RcPayloadControlSource setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public String getSn() { + return sn; + } + + public RcPayloadControlSource setSn(String sn) { + this.sn = sn; + return this; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public RcPayloadControlSource setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/device/SmartTrackPoint.java b/src/main/java/com/dji/sdk/cloudapi/device/SmartTrackPoint.java new file mode 100644 index 0000000..acb7517 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/SmartTrackPoint.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class SmartTrackPoint { + + private TrackTargetModeEnum trackTargetMode; + + private Float trackLatitude; + + private Float trackLongitude; + + private Float trackAltitude; + + public SmartTrackPoint() { + } + + @Override + public String toString() { + return "SmartTrackPoint{" + + "trackTargetMode=" + trackTargetMode + + ", trackLatitude=" + trackLatitude + + ", trackLongitude=" + trackLongitude + + ", trackAltitude=" + trackAltitude + + '}'; + } + + public TrackTargetModeEnum getTrackTargetMode() { + return trackTargetMode; + } + + public SmartTrackPoint setTrackTargetMode(TrackTargetModeEnum trackTargetMode) { + this.trackTargetMode = trackTargetMode; + return this; + } + + public Float getTrackLatitude() { + return trackLatitude; + } + + public SmartTrackPoint setTrackLatitude(Float trackLatitude) { + this.trackLatitude = trackLatitude; + return this; + } + + public Float getTrackLongitude() { + return trackLongitude; + } + + public SmartTrackPoint setTrackLongitude(Float trackLongitude) { + this.trackLongitude = trackLongitude; + return this; + } + + public Float getTrackAltitude() { + return trackAltitude; + } + + public SmartTrackPoint setTrackAltitude(Float trackAltitude) { + this.trackAltitude = trackAltitude; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/Storage.java b/src/main/java/com/dji/sdk/cloudapi/device/Storage.java new file mode 100644 index 0000000..a6575db --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/Storage.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/11 + */ +public class Storage { + + private Long total; + + private Long used; + + public Storage() { + } + + @Override + public String toString() { + return "Storage{" + + "total=" + total + + ", used=" + used + + '}'; + } + + public Long getTotal() { + return total; + } + + public Storage setTotal(Long total) { + this.total = total; + return this; + } + + public Long getUsed() { + return used; + } + + public Storage setUsed(Long used) { + this.used = used; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/SwitchActionEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/SwitchActionEnum.java new file mode 100644 index 0000000..ee36d80 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/SwitchActionEnum.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/28 + */ +public enum SwitchActionEnum { + + DISABLE(0), + + ENABLE(1); + + private final int action; + + SwitchActionEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static SwitchActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(SwitchActionEnum.class, action)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/ThermalGainModeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/ThermalGainModeEnum.java new file mode 100644 index 0000000..0bd3a8e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/ThermalGainModeEnum.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum ThermalGainModeEnum { + + AUTOMATIC(0), + + LOW(1), + + HIGH(2), + ; + + private final int mode; + + ThermalGainModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static ThermalGainModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(ThermalGainModeEnum.class, mode)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/ThermalPaletteStyleEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/ThermalPaletteStyleEnum.java new file mode 100644 index 0000000..b63c6eb --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/ThermalPaletteStyleEnum.java @@ -0,0 +1,72 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum ThermalPaletteStyleEnum { + + WHITE_HOT(0), + + BLACK_HOT(1), + + RED_HOT(2), + + GREEN_HOT(3), + + FUSION(4), + + RAINBOW(5), + + IRONBOW1(6), + + IRONBOW2(7), + + ICE_FIRE(8), + + SEPIA(9), + + GLOWBOW(10), + + COLOR1(11), + + COLOR2(12), + + RAIN(13), + + HOT_SPOT(14), + + RAINBOW2(15), + + GRAY(16), + + METAL(17), + + COLD_SPOT(18), + ; + + private final int style; + + ThermalPaletteStyleEnum(int style) { + this.style = style; + } + + @JsonValue + public int getStyle() { + return style; + } + + @JsonCreator + public static ThermalPaletteStyleEnum find(int style) { + return Arrays.stream(values()).filter(styleEnum -> styleEnum.style == style).findAny() + .orElseThrow(() -> new CloudSDKException(ThermalPaletteStyleEnum.class, style)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/TrackTargetModeEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/TrackTargetModeEnum.java new file mode 100644 index 0000000..9dbeb0c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/TrackTargetModeEnum.java @@ -0,0 +1,39 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum TrackTargetModeEnum { + + NORMAL(1), + + LOW_CREDIBILITY(2), + + PREDICTED(3), + ; + private final int mode; + + TrackTargetModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static TrackTargetModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(TrackTargetModeEnum.class, mode)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/UpdateTopo.java b/src/main/java/com/dji/sdk/cloudapi/device/UpdateTopo.java new file mode 100644 index 0000000..eb9feaf --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/UpdateTopo.java @@ -0,0 +1,105 @@ +package com.dji.sdk.cloudapi.device; + + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/26 + */ +public class UpdateTopo { + + private DeviceDomainEnum domain; + + private DeviceTypeEnum type; + + private DeviceSubTypeEnum subType; + + private String deviceSecret; + + private String nonce; + + private String thingVersion; + + private List subDevices; + + public UpdateTopo() { + } + + @Override + public String toString() { + return "UpdateTopo{" + + "domain=" + domain + + ", type=" + type + + ", subType=" + subType + + ", deviceSecret='" + deviceSecret + '\'' + + ", nonce='" + nonce + '\'' + + ", thingVersion=" + thingVersion + + ", subDevices=" + subDevices + + '}'; + } + + public DeviceDomainEnum getDomain() { + return domain; + } + + public UpdateTopo setDomain(DeviceDomainEnum domain) { + this.domain = domain; + return this; + } + + public DeviceTypeEnum getType() { + return type; + } + + public UpdateTopo setType(DeviceTypeEnum type) { + this.type = type; + return this; + } + + public DeviceSubTypeEnum getSubType() { + return subType; + } + + public UpdateTopo setSubType(DeviceSubTypeEnum subType) { + this.subType = subType; + return this; + } + + public String getDeviceSecret() { + return deviceSecret; + } + + public UpdateTopo setDeviceSecret(String deviceSecret) { + this.deviceSecret = deviceSecret; + return this; + } + + public String getNonce() { + return nonce; + } + + public UpdateTopo setNonce(String nonce) { + this.nonce = nonce; + return this; + } + + public String getThingVersion() { + return thingVersion; + } + + public UpdateTopo setThingVersion(String thingVersion) { + this.thingVersion = thingVersion; + return this; + } + + public List getSubDevices() { + return subDevices; + } + + public UpdateTopo setSubDevices(List subDevices) { + this.subDevices = subDevices; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/UpdateTopoSubDevice.java b/src/main/java/com/dji/sdk/cloudapi/device/UpdateTopoSubDevice.java new file mode 100644 index 0000000..4ba2734 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/UpdateTopoSubDevice.java @@ -0,0 +1,114 @@ +package com.dji.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/26 + */ +public class UpdateTopoSubDevice { + + private String sn; + + private DeviceDomainEnum domain; + + private DeviceTypeEnum type; + + private DeviceSubTypeEnum subType; + + private ControlSourceEnum index; + + private String deviceSecret; + + private String nonce; + + private String thingVersion; + + public UpdateTopoSubDevice() { + } + + @Override + public String toString() { + return "UpdateTopoSubDevice{" + + "sn='" + sn + '\'' + + ", domain=" + domain + + ", type=" + type + + ", subType=" + subType + + ", index=" + index + + ", deviceSecret='" + deviceSecret + '\'' + + ", nonce='" + nonce + '\'' + + ", thingVersion=" + thingVersion + + '}'; + } + + public String getSn() { + return sn; + } + + public UpdateTopoSubDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public DeviceDomainEnum getDomain() { + return domain; + } + + public UpdateTopoSubDevice setDomain(DeviceDomainEnum domain) { + this.domain = domain; + return this; + } + + public DeviceTypeEnum getType() { + return type; + } + + public UpdateTopoSubDevice setType(DeviceTypeEnum type) { + this.type = type; + return this; + } + + public DeviceSubTypeEnum getSubType() { + return subType; + } + + public UpdateTopoSubDevice setSubType(DeviceSubTypeEnum subType) { + this.subType = subType; + return this; + } + + public ControlSourceEnum getIndex() { + return index; + } + + public UpdateTopoSubDevice setIndex(ControlSourceEnum index) { + this.index = index; + return this; + } + + public String getDeviceSecret() { + return deviceSecret; + } + + public UpdateTopoSubDevice setDeviceSecret(String deviceSecret) { + this.deviceSecret = deviceSecret; + return this; + } + + public String getNonce() { + return nonce; + } + + public UpdateTopoSubDevice setNonce(String nonce) { + this.nonce = nonce; + return this; + } + + public String getThingVersion() { + return thingVersion; + } + + public UpdateTopoSubDevice setThingVersion(String thingVersion) { + this.thingVersion = thingVersion; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/VideoId.java b/src/main/java/com/dji/sdk/cloudapi/device/VideoId.java new file mode 100644 index 0000000..a61b77b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/VideoId.java @@ -0,0 +1,82 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.cloudapi.livestream.VideoTypeEnum; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import org.springframework.util.StringUtils; + +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/25 + */ +public class VideoId { + + @NotNull + private String droneSn; + + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private VideoTypeEnum videoType = VideoTypeEnum.NORMAL; + + public VideoId() { + } + + @JsonCreator + public VideoId(String videoId) { + if (!StringUtils.hasText(videoId)) { + return; + } + String[] videoIdArr = Arrays.stream(videoId.split("/")).toArray(String[]::new); + if (videoIdArr.length != 3) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + this.droneSn = videoIdArr[0]; + this.payloadIndex = new PayloadIndex(videoIdArr[1]); + this.videoType = VideoTypeEnum.find(videoIdArr[2].split("-")[0]); + } + + @Override + @JsonValue + public String toString() { + if (Objects.isNull(payloadIndex)) { + return ""; + } + return String.format("%s/%s/%s-0", droneSn, payloadIndex.toString(), videoType.getType()); + } + + public String getDroneSn() { + return droneSn; + } + + public VideoId setDroneSn(String droneSn) { + this.droneSn = droneSn; + return this; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public VideoId setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public VideoTypeEnum getVideoType() { + return videoType; + } + + public VideoId setVideoType(VideoTypeEnum videoType) { + this.videoType = videoType; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/WindDirectionEnum.java b/src/main/java/com/dji/sdk/cloudapi/device/WindDirectionEnum.java new file mode 100644 index 0000000..18ddf94 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/WindDirectionEnum.java @@ -0,0 +1,52 @@ +package com.dji.sdk.cloudapi.device; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum WindDirectionEnum { + + NO(0), + + NORTH(1), + + NORTHEAST(2), + + EAST(3), + + SOUTHEAST(4), + + SOUTH(5), + + SOUTHWEST(6), + + WEST(7), + + NORTHWEST(8), + ; + + private final int direction; + + WindDirectionEnum(int direction) { + this.direction = direction; + } + + @JsonValue + public int getDirection() { + return direction; + } + + @JsonCreator + public static WindDirectionEnum find(int direction) { + return Arrays.stream(values()).filter(directionEnum -> directionEnum.direction == direction).findAny() + .orElseThrow(() -> new CloudSDKException(WindDirectionEnum.class, direction)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/WirelessLink.java b/src/main/java/com/dji/sdk/cloudapi/device/WirelessLink.java new file mode 100644 index 0000000..8938821 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/WirelessLink.java @@ -0,0 +1,145 @@ +package com.dji.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/3 + */ +public class WirelessLink { + + @JsonProperty("4g_freq_band") + private Float fourthGenerationFreqBand; + + @JsonProperty("4g_gnd_quality") + private Integer fourthGenerationGndQuality; + + @JsonProperty("4g_link_state") + private Boolean fourthGenerationLinkState; + + @JsonProperty("4g_quality") + private Integer fourthGenerationQuality; + + @JsonProperty("4g_uav_quality") + private Integer fourthGenerationUavQuality; + + private Integer dongleNumber; + + private LinkWorkModeEnum linkWorkmode; + + private Float sdrFreqBand; + + private Boolean sdrLinkState; + + private Integer sdrQuality; + + public WirelessLink() { + } + + @Override + public String toString() { + return "WirelessLink{" + + "fourthGenerationFreqBand=" + fourthGenerationFreqBand + + ", fourthGenerationGndQuality=" + fourthGenerationGndQuality + + ", fourthGenerationLinkState=" + fourthGenerationLinkState + + ", fourthGenerationQuality=" + fourthGenerationQuality + + ", fourthGenerationUavQuality=" + fourthGenerationUavQuality + + ", dongleNumber=" + dongleNumber + + ", linkWorkmode=" + linkWorkmode + + ", sdrFreqBand=" + sdrFreqBand + + ", sdrLinkState=" + sdrLinkState + + ", sdrQuality=" + sdrQuality + + '}'; + } + + public Float getFourthGenerationFreqBand() { + return fourthGenerationFreqBand; + } + + public WirelessLink setFourthGenerationFreqBand(Float fourthGenerationFreqBand) { + this.fourthGenerationFreqBand = fourthGenerationFreqBand; + return this; + } + + public Integer getFourthGenerationGndQuality() { + return fourthGenerationGndQuality; + } + + public WirelessLink setFourthGenerationGndQuality(Integer fourthGenerationGndQuality) { + this.fourthGenerationGndQuality = fourthGenerationGndQuality; + return this; + } + + public Boolean getFourthGenerationLinkState() { + return fourthGenerationLinkState; + } + + public WirelessLink setFourthGenerationLinkState(Boolean fourthGenerationLinkState) { + this.fourthGenerationLinkState = fourthGenerationLinkState; + return this; + } + + public Integer getFourthGenerationQuality() { + return fourthGenerationQuality; + } + + public WirelessLink setFourthGenerationQuality(Integer fourthGenerationQuality) { + this.fourthGenerationQuality = fourthGenerationQuality; + return this; + } + + public Integer getFourthGenerationUavQuality() { + return fourthGenerationUavQuality; + } + + public WirelessLink setFourthGenerationUavQuality(Integer fourthGenerationUavQuality) { + this.fourthGenerationUavQuality = fourthGenerationUavQuality; + return this; + } + + public Integer getDongleNumber() { + return dongleNumber; + } + + public WirelessLink setDongleNumber(Integer dongleNumber) { + this.dongleNumber = dongleNumber; + return this; + } + + public LinkWorkModeEnum getLinkWorkmode() { + return linkWorkmode; + } + + public WirelessLink setLinkWorkmode(LinkWorkModeEnum linkWorkmode) { + this.linkWorkmode = linkWorkmode; + return this; + } + + public Float getSdrFreqBand() { + return sdrFreqBand; + } + + public WirelessLink setSdrFreqBand(Float sdrFreqBand) { + this.sdrFreqBand = sdrFreqBand; + return this; + } + + public Boolean getSdrLinkState() { + return sdrLinkState; + } + + public WirelessLink setSdrLinkState(Boolean sdrLinkState) { + this.sdrLinkState = sdrLinkState; + return this; + } + + public Integer getSdrQuality() { + return sdrQuality; + } + + public WirelessLink setSdrQuality(Integer sdrQuality) { + this.sdrQuality = sdrQuality; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/device/api/AbstractDeviceService.java b/src/main/java/com/dji/sdk/cloudapi/device/api/AbstractDeviceService.java new file mode 100644 index 0000000..b8b5352 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/device/api/AbstractDeviceService.java @@ -0,0 +1,177 @@ +package com.dji.sdk.cloudapi.device.api; + +import com.dji.sdk.cloudapi.device.*; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.osd.TopicOsdRequest; +import com.dji.sdk.mqtt.state.TopicStateRequest; +import com.dji.sdk.mqtt.status.TopicStatusRequest; +import com.dji.sdk.mqtt.status.TopicStatusResponse; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AbstractDeviceService { + + /** + * osd dock + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_OSD_DOCK) + public void osdDock(TopicOsdRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("osdDock not implemented"); + } + + /** + * osd dock drone + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_OSD_DOCK_DRONE) + public void osdDockDrone(TopicOsdRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("osdDockDrone not implemented"); + } + + /** + * osd remote control + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_OSD_RC) + public void osdRemoteControl(TopicOsdRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("osdRemoteControl not implemented"); + } + + /** + * osd remote control drone + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_OSD_RC_DRONE) + public void osdRcDrone(TopicOsdRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("osdRcDrone not implemented"); + } + + /** + * Gateway device + sub device online + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATUS_ONLINE, outputChannel = ChannelName.OUTBOUND_STATUS) + public TopicStatusResponse updateTopoOnline(TopicStatusRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("updateTopoOnline not implemented"); + } + + /** + * Sub device offline + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATUS_OFFLINE, outputChannel = ChannelName.OUTBOUND_STATUS) + public TopicStatusResponse updateTopoOffline(TopicStatusRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("updateTopoOffline not implemented"); + } + + /** + * Firmware version update for dock and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_FIRMWARE_VERSION) + public void dockFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockFirmwareVersionUpdate not implemented"); + } + + /** + * Firmware version update for remote control and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_RC_FIRMWARE_VERSION) + public void rcFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("rcFirmwareVersionUpdate not implemented"); + } + + /** + * Drone control source update for dock and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_CONTROL_SOURCE) + public void dockControlSourceUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockControlSourceUpdate not implemented"); + } + + /** + * Drone control source update for remote control and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_RC_CONTROL_SOURCE) + public void rcControlSourceUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("rcControlSourceUpdate not implemented"); + } + + /** + * Live status update for dock and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_LIVE_STATUS) + public void dockLiveStatusUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockLiveStatusUpdate not implemented"); + } + + /** + * Live status source update for remote control and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_RC_LIVE_STATUS) + public void rcLiveStatusUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("rcLiveStatusUpdate not implemented"); + } + + /** + * Payload firmware version update for remote control and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_RC_PAYLOAD_FIRMWARE) + public void rcPayloadFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("rcPayloadFirmwareVersionUpdate not implemented"); + } + + /** + * Wpmz firmware version update for drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_WPMZ_VERSION) + public void dockWpmzVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockWpmzVersionUpdate not implemented"); + } + + /** + * Styles supported by the IR palette + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_WPMZ_VERSION) + public void dockPayload(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockPayload not implemented"); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/FirmwareErrorCodeEnum.java b/src/main/java/com/dji/sdk/cloudapi/firmware/FirmwareErrorCodeEnum.java new file mode 100644 index 0000000..957f4d5 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/FirmwareErrorCodeEnum.java @@ -0,0 +1,97 @@ +package com.dji.sdk.cloudapi.firmware; + +import com.dji.sdk.common.IErrorInfo; +import com.dji.sdk.mqtt.events.IEventsErrorCode; +import com.dji.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum FirmwareErrorCodeEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + WRONG_TYPE(312001, "Consistency Upgrade was trrigered, but device didn't request."), + + READY_1_FAILED(312002, "Failed to upgrade. Please try again."), + + VALIDATION_FAILED(312003, "Failed to upgrade. Please try again."), + + READY_2_FAILED(312004, "Failed to upgrade. Please try again."), + + WRONG_PROTOCOL(312010, "The upgrade request is different from the API."), + + WRONG_PARAMETER(312012, "Please check the parameters and try again."), + + COMMAND_1_FAILED(312013, "Failed to upgrade. Please try again."), + + UPDATING(312014, "Updating device firmware. Wait until update completed."), + + WORKING(312015, "Device can not upgrade during the flight. Please wait and try again."), + + TRANSMISSION_ERROR(312016, "Update failed. Dock and aircraft transmission error. Restart dock and aircraft and try again."), + + VERSION_CHECK_FAILED(312017, "Failed to check the version."), + + COMMAND_2_FAILED(312018, "Failed to upgrade. Please try again."), + + COMMAND_3_FAILED(312019, "Failed to upgrade. Please try again."), + + COMMAND_4_FAILED(312020, "Failed to upgrade. Please try again."), + + COMMAND_5_FAILED(312021, "Failed to upgrade. Please try again."), + + AIRCRAFT_NOT_FOUND(312022, "Failed to power on aircraft, or aircraft not connected. Check if aircraft is inside dock, battery installed, and dock and aircraft linked."), + + AIRCRAFT_OUTSIDE(312023, "Failed to push driving rods back into place. Unable to update aircraft firmware. Check if emergency stop button is pressed down or driving rods are stuck."), + + COMMAND_6_FAILED(312024, "Failed to upgrade. Please try again."), + + DELETE_FAILED(312025, "Failed to delete old firmware package."), + + DECOMPRESSION_FAILED(312026, "Failed to decompress the offline upgrade package."), + + NO_AIRCRAFT_DETECTED(312027, "Failed to update firmware. Aircraft not detected inside dock."), + + DEVICE_RESTART_1(312028, "Failed to update firmware. Device restarted during update."), + + DEVICE_RESTART_2(312029, "Restarting device. Unable to update firmware."), + + FOURTH_GENERATION_IS_ENABLE(312030, "Aircraft enhanced transmission enabled. Failed to update firmware. Disable 4G transmission and try again."), + + LOW_POWER(312704, "Aircraft battery level too low. Wait until aircraft is charged to above 20% and try again."), + + UNKNOWN(-1, "UNKNOWN"), + ; + + + private final String msg; + + private final int code; + + FirmwareErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + /** + * @param code error code + * @return enumeration object + */ + public static FirmwareErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/FirmwareMethodEnum.java b/src/main/java/com/dji/sdk/cloudapi/firmware/FirmwareMethodEnum.java new file mode 100644 index 0000000..5c0370c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/FirmwareMethodEnum.java @@ -0,0 +1,24 @@ +package com.dji.sdk.cloudapi.firmware; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum FirmwareMethodEnum { + + OTA_CREATE("ota_create"); + + private final String method; + + FirmwareMethodEnum(String method) { + this.method = method; + } + + @JsonValue + public String getMethod() { + return method; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/FirmwareUpgradeTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/firmware/FirmwareUpgradeTypeEnum.java new file mode 100644 index 0000000..a5dc5e7 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/FirmwareUpgradeTypeEnum.java @@ -0,0 +1,44 @@ +package com.dji.sdk.cloudapi.firmware; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/15 + */ +public enum FirmwareUpgradeTypeEnum { + + /** + * to upgraded + */ + NORMAL_UPGRADE(2), + + /** + * A consistency upgrade is required. + */ + CONSISTENT_UPGRADE(3); + + private final int type; + + FirmwareUpgradeTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static FirmwareUpgradeTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(FirmwareUpgradeTypeEnum.class, type)); + + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/OtaCreateDevice.java b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaCreateDevice.java new file mode 100644 index 0000000..bef65e7 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaCreateDevice.java @@ -0,0 +1,113 @@ +package com.dji.sdk.cloudapi.firmware; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/16 + */ +public class OtaCreateDevice { + + @NotNull + private String sn; + + @NotNull + @Pattern(regexp = "^\\d{2}\\.\\d{2}\\.\\d{4}$") + private String productVersion; + + @NotNull + private String fileUrl; + + @NotNull + private String md5; + + @NotNull + private Long fileSize; + + @NotNull + private FirmwareUpgradeTypeEnum firmwareUpgradeType; + + @NotNull + private String fileName; + + public OtaCreateDevice() { + } + + @Override + public String toString() { + return "OtaCreateDevice{" + + "sn='" + sn + '\'' + + ", productVersion='" + productVersion + '\'' + + ", fileUrl='" + fileUrl + '\'' + + ", md5='" + md5 + '\'' + + ", fileSize=" + fileSize + + ", firmwareUpgradeType=" + firmwareUpgradeType + + ", fileName='" + fileName + '\'' + + '}'; + } + + public String getSn() { + return sn; + } + + public OtaCreateDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public String getProductVersion() { + return productVersion; + } + + public OtaCreateDevice setProductVersion(String productVersion) { + this.productVersion = productVersion; + return this; + } + + public String getFileUrl() { + return fileUrl; + } + + public OtaCreateDevice setFileUrl(String fileUrl) { + this.fileUrl = fileUrl; + return this; + } + + public String getMd5() { + return md5; + } + + public OtaCreateDevice setMd5(String md5) { + this.md5 = md5; + return this; + } + + public Long getFileSize() { + return fileSize; + } + + public OtaCreateDevice setFileSize(Long fileSize) { + this.fileSize = fileSize; + return this; + } + + public FirmwareUpgradeTypeEnum getFirmwareUpgradeType() { + return firmwareUpgradeType; + } + + public OtaCreateDevice setFirmwareUpgradeType(FirmwareUpgradeTypeEnum firmwareUpgradeType) { + this.firmwareUpgradeType = firmwareUpgradeType; + return this; + } + + public String getFileName() { + return fileName; + } + + public OtaCreateDevice setFileName(String fileName) { + this.fileName = fileName; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/OtaCreateRequest.java b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaCreateRequest.java new file mode 100644 index 0000000..1c43792 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaCreateRequest.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.firmware; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/28 + */ +public class OtaCreateRequest extends BaseModel { + + @Size(min = 1, max = 2) + @NotNull + @Valid + private List devices; + + public OtaCreateRequest() { + } + + @Override + public String toString() { + return "OtaCreateRequest{" + + "devices=" + devices + + '}'; + } + + public List getDevices() { + return devices; + } + + public OtaCreateRequest setDevices(List devices) { + this.devices = devices; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/OtaCreateResponse.java b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaCreateResponse.java new file mode 100644 index 0000000..66d28c3 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaCreateResponse.java @@ -0,0 +1,33 @@ +package com.dji.sdk.cloudapi.firmware; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class OtaCreateResponse { + + /** + * Mission status + **/ + private OtaProgressStatusEnum status; + + public OtaCreateResponse() { + } + + @Override + public String toString() { + return "OtaCreateResponse{" + + "status=" + status + + '}'; + } + + public OtaProgressStatusEnum getStatus() { + return status; + } + + public OtaCreateResponse setStatus(OtaProgressStatusEnum status) { + this.status = status; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgress.java b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgress.java new file mode 100644 index 0000000..e3fe097 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgress.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.firmware; + +/** + * @author sean + * @version 1.2 + * @date 2022/7/29 + */ +public class OtaProgress { + + private OtaProgressStatusEnum status; + + private OtaProgressData progress; + + private OtaProgressExt ext; + + public OtaProgress() { + } + + @Override + public String toString() { + return "OtaProgress{" + + "status=" + status + + ", progress=" + progress + + ", ext=" + ext + + '}'; + } + + public OtaProgressStatusEnum getStatus() { + return status; + } + + public OtaProgress setStatus(OtaProgressStatusEnum status) { + this.status = status; + return this; + } + + public OtaProgressData getProgress() { + return progress; + } + + public OtaProgress setProgress(OtaProgressData progress) { + this.progress = progress; + return this; + } + + public OtaProgressExt getExt() { + return ext; + } + + public OtaProgress setExt(OtaProgressExt ext) { + this.ext = ext; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressData.java b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressData.java new file mode 100644 index 0000000..997cce1 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressData.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.firmware; + +/** + * @author sean + * @version 1.2 + * @date 2022/7/29 + */ +public class OtaProgressData { + + private Integer percent; + + private OtaProgressStepEnum currentStep; + + public OtaProgressData() { + } + + @Override + public String toString() { + return "OtaProgressData{" + + "percent=" + percent + + ", currentStep=" + currentStep + + '}'; + } + + public Integer getPercent() { + return percent; + } + + public OtaProgressData setPercent(Integer percent) { + this.percent = percent; + return this; + } + + public OtaProgressStepEnum getCurrentStep() { + return currentStep; + } + + public OtaProgressData setCurrentStep(OtaProgressStepEnum currentStep) { + this.currentStep = currentStep; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressExt.java b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressExt.java new file mode 100644 index 0000000..1eb2f30 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressExt.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.firmware; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/30 + */ +public class OtaProgressExt { + + private Long rate; + + public OtaProgressExt() { + } + + @Override + public String toString() { + return "OtaProgressExt{" + + "rate=" + rate + + '}'; + } + + public Long getRate() { + return rate; + } + + public OtaProgressExt setRate(Long rate) { + this.rate = rate; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressStatusEnum.java b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressStatusEnum.java new file mode 100644 index 0000000..1a304b4 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressStatusEnum.java @@ -0,0 +1,57 @@ +package com.dji.sdk.cloudapi.firmware; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/17 + */ +public enum OtaProgressStatusEnum { + + SENT("sent", false), + + IN_PROGRESS("in_progress", false), + + OK("ok", true), + + PAUSED("paused", false), + + REJECTED("rejected", true), + + FAILED("failed", true), + + CANCELED("canceled", true), + + TIMEOUT("timeout", true); + + private final String status; + + private final boolean end; + + OtaProgressStatusEnum(String status, boolean end) { + this.status = status; + this.end = end; + } + + @JsonValue + public String getStatus() { + return status; + } + + public boolean isEnd() { + return end; + } + + @JsonCreator + public static OtaProgressStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(OtaProgressStatusEnum.class, status)); + } +} + + diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressStepEnum.java b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressStepEnum.java new file mode 100644 index 0000000..6369879 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/OtaProgressStepEnum.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.firmware; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/28 + */ +public enum OtaProgressStepEnum { + + DOWNLOADING(1), + + UPGRADING(2); + + private final int step; + + OtaProgressStepEnum(int step) { + this.step = step; + } + + @JsonValue + public int getStep() { + return step; + } + + @JsonCreator + public static OtaProgressStepEnum find(int step) { + return Arrays.stream(values()).filter(stepEnum -> stepEnum.step == step).findAny() + .orElseThrow(() -> new CloudSDKException(OtaProgressStepEnum.class, step)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/firmware/api/AbstractFirmwareService.java b/src/main/java/com/dji/sdk/cloudapi/firmware/api/AbstractFirmwareService.java new file mode 100644 index 0000000..44766de --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/firmware/api/AbstractFirmwareService.java @@ -0,0 +1,57 @@ +package com.dji.sdk.cloudapi.firmware.api; + +import com.dji.sdk.cloudapi.firmware.FirmwareMethodEnum; +import com.dji.sdk.cloudapi.firmware.OtaCreateRequest; +import com.dji.sdk.cloudapi.firmware.OtaCreateResponse; +import com.dji.sdk.cloudapi.firmware.OtaProgress; +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.services.ServicesPublish; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import com.fasterxml.jackson.core.type.TypeReference; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import javax.annotation.Resource; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/28 + */ +public abstract class AbstractFirmwareService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Firmware upgrade progress + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_OTA_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse otaProgress(TopicEventsRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("otaProgress not implemented"); + } + + /** + * Firmware upgrade + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse> otaCreate(GatewayManager gateway, OtaCreateRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + FirmwareMethodEnum.OTA_CREATE.getMethod(), + request); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/DeviceHms.java b/src/main/java/com/dji/sdk/cloudapi/hms/DeviceHms.java new file mode 100644 index 0000000..a55586c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/DeviceHms.java @@ -0,0 +1,104 @@ +package com.dji.sdk.cloudapi.hms; + +import com.dji.sdk.cloudapi.device.DeviceEnum; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/6 + */ +public class DeviceHms { + + private String code; + + private DeviceEnum deviceType; + + private Boolean imminent; + + private Boolean inTheSky; + + private HmsLevelEnum level; + + private HmsModuleEnum module; + + private DeviceHmsArgs args; + + public DeviceHms() { + } + + @Override + public String toString() { + return "DeviceHms{" + + "code='" + code + '\'' + + ", deviceType=" + deviceType + + ", imminent=" + imminent + + ", inTheSky=" + inTheSky + + ", level=" + level + + ", module=" + module + + ", args=" + args + + '}'; + } + + public String getCode() { + return code; + } + + public DeviceHms setCode(String code) { + this.code = code; + return this; + } + + public DeviceEnum getDeviceType() { + return deviceType; + } + + public DeviceHms setDeviceType(DeviceEnum deviceType) { + this.deviceType = deviceType; + return this; + } + + public Boolean getImminent() { + return imminent; + } + + public DeviceHms setImminent(Boolean imminent) { + this.imminent = imminent; + return this; + } + + public Boolean getInTheSky() { + return inTheSky; + } + + public DeviceHms setInTheSky(Boolean inTheSky) { + this.inTheSky = inTheSky; + return this; + } + + public HmsLevelEnum getLevel() { + return level; + } + + public DeviceHms setLevel(HmsLevelEnum level) { + this.level = level; + return this; + } + + public HmsModuleEnum getModule() { + return module; + } + + public DeviceHms setModule(HmsModuleEnum module) { + this.module = module; + return this; + } + + public DeviceHmsArgs getArgs() { + return args; + } + + public DeviceHms setArgs(DeviceHmsArgs args) { + this.args = args; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/DeviceHmsArgs.java b/src/main/java/com/dji/sdk/cloudapi/hms/DeviceHmsArgs.java new file mode 100644 index 0000000..3c9493e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/DeviceHmsArgs.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.hms; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/6 + */ +public class DeviceHmsArgs { + + private Long componentIndex; + + private Integer sensorIndex; + + private Integer alarmId; + + public DeviceHmsArgs() { + } + + @Override + public String toString() { + return "DeviceHmsArgs{" + + "componentIndex=" + componentIndex + + ", sensorIndex=" + sensorIndex + + ", alarmId=" + alarmId + + '}'; + } + + public Long getComponentIndex() { + return componentIndex; + } + + public DeviceHmsArgs setComponentIndex(Long componentIndex) { + this.componentIndex = componentIndex; + return this; + } + + public Integer getSensorIndex() { + return sensorIndex; + } + + public DeviceHmsArgs setSensorIndex(Integer sensorIndex) { + this.sensorIndex = sensorIndex; + return this; + } + + public Integer getAlarmId() { + return alarmId; + } + + public DeviceHmsArgs setAlarmId(Integer alarmId) { + this.alarmId = alarmId; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/Hms.java b/src/main/java/com/dji/sdk/cloudapi/hms/Hms.java new file mode 100644 index 0000000..8f6dd83 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/Hms.java @@ -0,0 +1,32 @@ +package com.dji.sdk.cloudapi.hms; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public class Hms { + + private List list; + + public Hms() { + } + + @Override + public String toString() { + return "Hms{" + + "list=" + list + + '}'; + } + + public List getList() { + return list; + } + + public Hms setList(List list) { + this.list = list; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/HmsBatteryIndexEnum.java b/src/main/java/com/dji/sdk/cloudapi/hms/HmsBatteryIndexEnum.java new file mode 100644 index 0000000..9583f4e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/HmsBatteryIndexEnum.java @@ -0,0 +1,48 @@ +package com.dji.sdk.cloudapi.hms; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsBatteryIndexEnum { + + LEFT(0, "left", "左"), + + RIGHT(1, "right", "右"); + + private final int val; + + private final String en; + + private final String zh; + + HmsBatteryIndexEnum(int val, String en, String zh) { + this.val = val; + this.en = en; + this.zh = zh; + } + + @JsonValue + public int getVal() { + return val; + } + + public String getEn() { + return en; + } + + public String getZh() { + return zh; + } + + public static HmsBatteryIndexEnum find(int val) { + return Arrays.stream(HmsBatteryIndexEnum.values()).filter(battery -> battery.val == val).findAny() + .orElseThrow(() -> new CloudSDKException(HmsBatteryIndexEnum.class, val)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/HmsChargingRodIndexEnum.java b/src/main/java/com/dji/sdk/cloudapi/hms/HmsChargingRodIndexEnum.java new file mode 100644 index 0000000..08751d2 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/HmsChargingRodIndexEnum.java @@ -0,0 +1,50 @@ +package com.dji.sdk.cloudapi.hms; + +import com.dji.sdk.exception.CloudSDKException; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsChargingRodIndexEnum { + + FRONT(0, "front", "前"), + + BACK(1, "back", "后"), + + LEFT(2, "left", "左"), + + RIGHT(3, "right", "右"); + + private final int val; + + private final String en; + + private final String zh; + + HmsChargingRodIndexEnum(int val, String en, String zh) { + this.val = val; + this.en = en; + this.zh = zh; + } + + public int getVal() { + return val; + } + + public String getEn() { + return en; + } + + public String getZh() { + return zh; + } + + public static HmsChargingRodIndexEnum find(int val) { + return Arrays.stream(HmsChargingRodIndexEnum.values()).filter(rod -> rod.val == val).findAny() + .orElseThrow(() -> new CloudSDKException(HmsChargingRodIndexEnum.class, val)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/HmsDockCoverIndexEnum.java b/src/main/java/com/dji/sdk/cloudapi/hms/HmsDockCoverIndexEnum.java new file mode 100644 index 0000000..fdd417e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/HmsDockCoverIndexEnum.java @@ -0,0 +1,48 @@ +package com.dji.sdk.cloudapi.hms; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsDockCoverIndexEnum { + + LEFT(0, "left", "左"), + + RIGHT(1, "right", "右"); + + private final int val; + + private final String en; + + private final String zh; + + HmsDockCoverIndexEnum(int val, String en, String zh) { + this.val = val; + this.en = en; + this.zh = zh; + } + + @JsonValue + public int getVal() { + return val; + } + + public String getEn() { + return en; + } + + public String getZh() { + return zh; + } + + public static HmsDockCoverIndexEnum find(int val) { + return Arrays.stream(HmsDockCoverIndexEnum.values()).filter(dockCover -> dockCover.val == val).findAny() + .orElseThrow(() -> new CloudSDKException(HmsDockCoverIndexEnum.class, val)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/HmsFaqIdEnum.java b/src/main/java/com/dji/sdk/cloudapi/hms/HmsFaqIdEnum.java new file mode 100644 index 0000000..065920f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/HmsFaqIdEnum.java @@ -0,0 +1,43 @@ +package com.dji.sdk.cloudapi.hms; + +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsFaqIdEnum { + + DOCK_TIP("dock_tip_", DeviceDomainEnum.DOCK), + + FPV_TIP("fpv_tip_", DeviceDomainEnum.DRONE); + + private final String text; + + private final DeviceDomainEnum domain; + + @JsonValue + public String getText() { + return text; + } + + public DeviceDomainEnum getDomain() { + return domain; + } + + HmsFaqIdEnum(String text, DeviceDomainEnum domain) { + this.text = text; + this.domain = domain; + } + + public static HmsFaqIdEnum find(DeviceDomainEnum domain) { + return Arrays.stream(values()).filter(faqIdEnum -> faqIdEnum.domain == domain).findAny() + .orElseThrow(() -> new CloudSDKException(HmsFaqIdEnum.class, domain)); + } +} + diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/HmsFormatKeyEnum.java b/src/main/java/com/dji/sdk/cloudapi/hms/HmsFormatKeyEnum.java new file mode 100644 index 0000000..58f5772 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/HmsFormatKeyEnum.java @@ -0,0 +1,44 @@ +package com.dji.sdk.cloudapi.hms; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsFormatKeyEnum { + + ALARM_ID("%alarmid"), + + COMPONENT_INDEX("%component_index"), + + INDEX("%index"), + + BATTERY_INDEX("%battery_index"), + + DOCK_COVER_INDEX("%dock_cover_index"), + + CHARGING_ROD_INDEX("%charging_rod_index"); + +// public static final char KEY_START = '%'; + + private final String key; + + HmsFormatKeyEnum(String key) { + this.key = key; + } + + @JsonValue + public String getKey() { + return key; + } + + public static HmsFormatKeyEnum find(String key) { + return Arrays.stream(HmsFormatKeyEnum.values()).filter(format -> format.getKey().equals(key)).findAny() + .orElseThrow(() -> new CloudSDKException(HmsFormatKeyEnum.class, key)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/HmsInTheSkyEnum.java b/src/main/java/com/dji/sdk/cloudapi/hms/HmsInTheSkyEnum.java new file mode 100644 index 0000000..ba995d9 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/HmsInTheSkyEnum.java @@ -0,0 +1,24 @@ +package com.dji.sdk.cloudapi.hms; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsInTheSkyEnum { + + IN_THE_SKY("_in_the_sky"); + + private final String text; + + HmsInTheSkyEnum(String text) { + this.text = text; + } + + @JsonValue + public String getText() { + return text; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/HmsLevelEnum.java b/src/main/java/com/dji/sdk/cloudapi/hms/HmsLevelEnum.java new file mode 100644 index 0000000..d1ce59a --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/HmsLevelEnum.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.hms; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public enum HmsLevelEnum { + + INFORM(0), + + NOTICE(1), + + ALARM(2); + + private final int level; + + HmsLevelEnum(int level) { + this.level = level; + } + + @JsonValue + public int getLevel() { + return level; + } + + @JsonCreator + public static HmsLevelEnum find(int level) { + return Arrays.stream(values()).filter(levelEnum -> levelEnum.level == level).findAny() + .orElseThrow(() -> new CloudSDKException(HmsLevelEnum.class, level)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/HmsMessageLanguageEnum.java b/src/main/java/com/dji/sdk/cloudapi/hms/HmsMessageLanguageEnum.java new file mode 100644 index 0000000..1ac863a --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/HmsMessageLanguageEnum.java @@ -0,0 +1,23 @@ +package com.dji.sdk.cloudapi.hms; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsMessageLanguageEnum { + + EN("en"), + + ZH("zh"); + + private final String language; + + HmsMessageLanguageEnum(String language) { + this.language = language; + } + + public String getLanguage() { + return language; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/HmsModuleEnum.java b/src/main/java/com/dji/sdk/cloudapi/hms/HmsModuleEnum.java new file mode 100644 index 0000000..0697b0a --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/HmsModuleEnum.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.hms; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public enum HmsModuleEnum { + + FLIGHT_MISSION(0), + + DEVICE_MANAGEMENT(1), + + MEDIA(2), + + HMS(3); + + private final int module; + + HmsModuleEnum(int module) { + this.module = module; + } + + @JsonValue + public int getModule() { + return module; + } + + @JsonCreator + public static HmsModuleEnum find(int module) { + return Arrays.stream(values()).filter(moduleEnum -> moduleEnum.module == module).findAny() + .orElseThrow(() -> new CloudSDKException(HmsModuleEnum.class, module)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/hms/api/AbstractHmsService.java b/src/main/java/com/dji/sdk/cloudapi/hms/api/AbstractHmsService.java new file mode 100644 index 0000000..97b1c1b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/hms/api/AbstractHmsService.java @@ -0,0 +1,27 @@ +package com.dji.sdk.cloudapi.hms.api; + +import com.dji.sdk.cloudapi.hms.Hms; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.MessageHeaders; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public abstract class AbstractHmsService { + + /** + * Reporting of hms + * @param response + * @param headers + * @return + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_HMS) + public void hms(TopicEventsRequest response, MessageHeaders headers) { + throw new UnsupportedOperationException("hms not implemented"); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacity.java b/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacity.java new file mode 100644 index 0000000..c36b39c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacity.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.livestream; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class DockLiveCapacity { + + /** + * Total number of video streams available for livestreaming. + * Indicates the total number of all available live video streams owned by the aircraft or device. + */ + private Integer availableVideoNumber; + + /** + * Maximum total number of video streams that can be lived stream simultaneously. + */ + private Integer coexistVideoNumberMax; + + /** + * Device live streaming capability list + */ + private List deviceList; + + public DockLiveCapacity() { + } + + @Override + public String toString() { + return "DockLiveCapacity{" + + "availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", deviceList=" + deviceList + + '}'; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public DockLiveCapacity setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public DockLiveCapacity setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public List getDeviceList() { + return deviceList; + } + + public DockLiveCapacity setDeviceList(List deviceList) { + this.deviceList = deviceList; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacityCamera.java b/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacityCamera.java new file mode 100644 index 0000000..e182409 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacityCamera.java @@ -0,0 +1,80 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.dji.sdk.cloudapi.device.PayloadIndex; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class DockLiveCapacityCamera { + + /** + * Total number of video streams that can be used for livestreaming + * Total number of video streams that the camera can live stream + */ + private Integer availableVideoNumber; + + /** + * Maximum number of video streams that the camera can live stream at the same time. + */ + private Integer coexistVideoNumberMax; + + /** + * Camera index, composed of product type enumeration and gimbal index. + */ + private PayloadIndex cameraIndex; + + private List videoList; + + public DockLiveCapacityCamera() { + } + + @Override + public String toString() { + return "DockLiveCapacityCamera{" + + "availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", cameraIndex=" + cameraIndex + + ", videoList=" + videoList + + '}'; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public DockLiveCapacityCamera setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public DockLiveCapacityCamera setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public PayloadIndex getCameraIndex() { + return cameraIndex; + } + + public DockLiveCapacityCamera setCameraIndex(PayloadIndex cameraIndex) { + this.cameraIndex = cameraIndex; + return this; + } + + public List getVideoList() { + return videoList; + } + + public DockLiveCapacityCamera setVideoList(List videoList) { + this.videoList = videoList; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacityDevice.java b/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacityDevice.java new file mode 100644 index 0000000..f421132 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacityDevice.java @@ -0,0 +1,81 @@ +package com.dji.sdk.cloudapi.livestream; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class DockLiveCapacityDevice { + + /** + * Device serial number + */ + private String sn; + + /** + * Total number of video streams that can be used for livestreaming + * Total number of video streams used for livestreaming that belongs to devices. + */ + private Integer availableVideoNumber; + + /** + * Maximum number of video streams that can be used for livestreaming at the same time + */ + private Integer coexistVideoNumberMax; + + /** + * Camera list on the device + */ + private List cameraList; + + public DockLiveCapacityDevice() { + } + + @Override + public String toString() { + return "DockLiveCapacityDevice{" + + "sn='" + sn + '\'' + + ", availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", cameraList=" + cameraList + + '}'; + } + + public String getSn() { + return sn; + } + + public DockLiveCapacityDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public DockLiveCapacityDevice setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public DockLiveCapacityDevice setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public List getCameraList() { + return cameraList; + } + + public DockLiveCapacityDevice setCameraList(List cameraList) { + this.cameraList = cameraList; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacityVideo.java b/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacityVideo.java new file mode 100644 index 0000000..46821e9 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/DockLiveCapacityVideo.java @@ -0,0 +1,56 @@ +package com.dji.sdk.cloudapi.livestream; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class DockLiveCapacityVideo { + + private String videoIndex; + + private VideoTypeEnum videoType; + + private List switchableVideoTypes; + + public DockLiveCapacityVideo() { + } + + @Override + public String toString() { + return "DockLiveCapacityVideo{" + + "videoIndex='" + videoIndex + '\'' + + ", videoType=" + videoType + + ", switchableVideoTypes=" + switchableVideoTypes + + '}'; + } + + public String getVideoIndex() { + return videoIndex; + } + + public DockLiveCapacityVideo setVideoIndex(String videoIndex) { + this.videoIndex = videoIndex; + return this; + } + + public VideoTypeEnum getVideoType() { + return videoType; + } + + public DockLiveCapacityVideo setVideoType(VideoTypeEnum videoType) { + this.videoType = videoType; + return this; + } + + public List getSwitchableVideoTypes() { + return switchableVideoTypes; + } + + public DockLiveCapacityVideo setSwitchableVideoTypes(List switchableVideoTypes) { + this.switchableVideoTypes = switchableVideoTypes; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/DockLivestreamAbilityUpdate.java b/src/main/java/com/dji/sdk/cloudapi/livestream/DockLivestreamAbilityUpdate.java new file mode 100644 index 0000000..87d1e55 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/DockLivestreamAbilityUpdate.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.livestream; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class DockLivestreamAbilityUpdate { + + private DockLiveCapacity liveCapacity; + + public DockLivestreamAbilityUpdate() { + } + + @Override + public String toString() { + return "DockLivestreamAbilityUpdate{" + + "liveCapacity=" + liveCapacity + + '}'; + } + + public DockLiveCapacity getLiveCapacity() { + return liveCapacity; + } + + public DockLivestreamAbilityUpdate setLiveCapacity(DockLiveCapacity liveCapacity) { + this.liveCapacity = liveCapacity; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/LensChangeVideoTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/livestream/LensChangeVideoTypeEnum.java new file mode 100644 index 0000000..57dcbe0 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/LensChangeVideoTypeEnum.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/25 + */ +public enum LensChangeVideoTypeEnum { + + ZOOM("zoom"), + + WIDE("wide"), + + IR("ir"); + + private final String type; + + LensChangeVideoTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static LensChangeVideoTypeEnum find(String videoType) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(videoType)).findAny() + .orElseThrow(() -> new CloudSDKException(LensChangeVideoTypeEnum.class , videoType)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/LiveErrorCodeEnum.java b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveErrorCodeEnum.java new file mode 100644 index 0000000..f45ea11 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveErrorCodeEnum.java @@ -0,0 +1,80 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.dji.sdk.common.IErrorInfo; +import com.dji.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum LiveErrorCodeEnum implements IServicesErrorCode, IErrorInfo { + + NO_AIRCRAFT(13001, "No aircraft."), + + NO_CAMERA(13002, "No camera."), + + LIVE_STREAM_ALREADY_STARTED(13003, "The camera has started live streaming."), + + FUNCTION_NOT_SUPPORT(13004, "The function is not supported."), + + STRATEGY_NOT_SUPPORT(13005, "The strategy is not supported."), + + NOT_IN_CAMERA_INTERFACE(13006, "The current app is not in the camera interface."), + + NO_FLIGHT_CONTROL(13007, "The remote control has no flight control rights and cannot respond to control commands"), + + NO_STREAM_DATA(13008, "The current app has no stream data."), + + TOO_FREQUENT(13009, "The operation is too frequent."), + + ENABLE_FAILED(13010, "Please check whether the live stream service is normal."), + + NO_LIVE_STREAM(13011, "There are no live stream currently."), + + SWITCH_NOT_SUPPORT(13012, "There is already another camera in the live stream. It's not support to switch the stream directly."), + + URL_TYPE_NOT_SUPPORTED(13013, "This url type is not supported."), + + ERROR_PARAMETERS(13014, "The live stream parameters are abnormal or incomplete."), + + NETWORK_CONGESTION(13015, "Please check the network."), + + ERROR_FRAME(13016, "Live decoding failed."), + + DEVICE_UNKNOWN(13099, "Unknown error inside the device."), + + UNKNOWN(-1, "UNKNOWN"), + ; + + + private final String msg; + + private final int code; + + LiveErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + /** + * @param code error code + * @return enumeration object + */ + public static LiveErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/LiveLensChangeRequest.java b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveLensChangeRequest.java new file mode 100644 index 0000000..ff498b9 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveLensChangeRequest.java @@ -0,0 +1,53 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.dji.sdk.cloudapi.device.VideoId; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class LiveLensChangeRequest extends BaseModel { + + @NotNull + private LensChangeVideoTypeEnum videoType; + + /** + * The format is #{uav_sn}/#{camera_id}/#{video_index}, + * drone serial number/payload and mounted location enumeration value/payload lens numbering + */ + @NotNull + private VideoId videoId; + + public LiveLensChangeRequest() { + } + + @Override + public String toString() { + return "LiveLensChangeRequest{" + + "videoType=" + videoType + + ", videoId=" + videoId + + '}'; + } + + public LensChangeVideoTypeEnum getVideoType() { + return videoType; + } + + public LiveLensChangeRequest setVideoType(LensChangeVideoTypeEnum videoType) { + this.videoType = videoType; + return this; + } + + public VideoId getVideoId() { + return videoId; + } + + public LiveLensChangeRequest setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/LiveSetQualityRequest.java b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveSetQualityRequest.java new file mode 100644 index 0000000..541b25e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveSetQualityRequest.java @@ -0,0 +1,53 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.dji.sdk.cloudapi.device.VideoId; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class LiveSetQualityRequest extends BaseModel { + + /** + * The format is #{uav_sn}/#{camera_id}/#{video_index}, + * drone serial number/payload and mounted location enumeration value/payload lens numbering + */ + @NotNull + private VideoId videoId; + + @NotNull + private VideoQualityEnum videoQuality; + + public LiveSetQualityRequest() { + } + + @Override + public String toString() { + return "LiveSetQualityRequest{" + + "videoId=" + videoId + + ", videoQuality=" + videoQuality + + '}'; + } + + public VideoId getVideoId() { + return videoId; + } + + public LiveSetQualityRequest setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } + + public VideoQualityEnum getVideoQuality() { + return videoQuality; + } + + public LiveSetQualityRequest setVideoQuality(VideoQualityEnum videoQuality) { + this.videoQuality = videoQuality; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/LiveStartPushRequest.java b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveStartPushRequest.java new file mode 100644 index 0000000..8748869 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveStartPushRequest.java @@ -0,0 +1,93 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.dji.sdk.cloudapi.device.VideoId; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class LiveStartPushRequest extends BaseModel { + + @NotNull + private UrlTypeEnum urlType; + + /** + * RTMP: (rtmp://xxxxxxx) Example: rtmp://192.168.1.1:8080/live + * RTSP:(uerName&password&port) Example: userName=dji-cloud-api&password=123456&port=8080 + * GB28181:(serverIP&serverPort&serverID&agentID&agentPassword&localPort&channel) + * Example: serverIP=192.168.1.1&serverPort=8080&serverID=34000000000000000000&agentID= + * 300000000010000000000&agentPassword=0000000&localPort=7060&channel=340000000000000000000 + * AGORA:(channel&sn&token&uid) + * Example: channel=1ZNDH360010162_39-0-7&sn=1ZNDH360010162&token=006dca67721582a48768ec4d8 + * 17b7b25a86IAB4cw2JgN6iX8BpTPdc3e4S1Iendz94IFJ56aSXKvzAJei27MqF2zyCIgCLIIoBt41+YAQAAQC3jX + * 5gAgC3jX5gAwC3jX5gBAC3jX5g&uid=50000 + * Notice: The token generated by Shengwang may have special characters such as '+' ' ', + * and need to do url encode, otherwise there will be a parsing error on the PILOT side + */ + @NotBlank + private String url; + + /** + * The format is #{uav_sn}/#{camera_id}/#{video_index}, + * drone serial number/payload and mounted location enumeration value/payload lens numbering + */ + @NotNull + private VideoId videoId; + + @NotNull + private VideoQualityEnum videoQuality; + + public LiveStartPushRequest() { + } + + @Override + public String toString() { + return "LiveStartPushRequest{" + + "urlType=" + urlType + + ", url='" + url + '\'' + + ", videoId=" + videoId + + ", videoQuality=" + videoQuality + + '}'; + } + + public UrlTypeEnum getUrlType() { + return urlType; + } + + public LiveStartPushRequest setUrlType(UrlTypeEnum urlType) { + this.urlType = urlType; + return this; + } + + public String getUrl() { + return url; + } + + public LiveStartPushRequest setUrl(String url) { + this.url = url; + return this; + } + + public VideoId getVideoId() { + return videoId; + } + + public LiveStartPushRequest setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } + + public VideoQualityEnum getVideoQuality() { + return videoQuality; + } + + public LiveStartPushRequest setVideoQuality(VideoQualityEnum videoQuality) { + this.videoQuality = videoQuality; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/LiveStopPushRequest.java b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveStopPushRequest.java new file mode 100644 index 0000000..9107c53 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveStopPushRequest.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.dji.sdk.cloudapi.device.VideoId; +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class LiveStopPushRequest extends BaseModel { + + /** + * The format is #{uav_sn}/#{camera_id}/#{video_index}, + * drone serial number/payload and mounted location enumeration value/payload lens numbering + */ + @NotNull + private VideoId videoId; + + public LiveStopPushRequest() { + } + + @Override + public String toString() { + return "LiveStopPushRequest{" + + "videoId=" + videoId + + '}'; + } + + public VideoId getVideoId() { + return videoId; + } + + public LiveStopPushRequest setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/LiveStreamMethodEnum.java b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveStreamMethodEnum.java new file mode 100644 index 0000000..46e9273 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/LiveStreamMethodEnum.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum LiveStreamMethodEnum { + + LIVE_START_PUSH("live_start_push"), + + LIVE_STOP_PUSH("live_stop_push"), + + LIVE_SET_QUALITY("live_set_quality"), + + LIVE_LENS_CHANGE("live_lens_change"); + + private final String method; + + LiveStreamMethodEnum(String method) { + this.method = method; + } + + @JsonValue + public String getMethod() { + return method; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacity.java b/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacity.java new file mode 100644 index 0000000..f11fe80 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacity.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.livestream; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class RcLiveCapacity { + + /** + * Total number of video streams available for livestreaming. + * Indicates the total number of all available live video streams owned by the aircraft or device. + */ + private Integer availableVideoNumber; + + /** + * Maximum total number of video streams that can be lived stream simultaneously. + */ + private Integer coexistVideoNumberMax; + + /** + * Device live streaming capability list + */ + private List deviceList; + + public RcLiveCapacity() { + } + + @Override + public String toString() { + return "RcLiveCapacity{" + + "availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", deviceList=" + deviceList + + '}'; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public RcLiveCapacity setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public RcLiveCapacity setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public List getDeviceList() { + return deviceList; + } + + public RcLiveCapacity setDeviceList(List deviceList) { + this.deviceList = deviceList; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacityCamera.java b/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacityCamera.java new file mode 100644 index 0000000..7ca3b66 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacityCamera.java @@ -0,0 +1,80 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.dji.sdk.cloudapi.device.PayloadIndex; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class RcLiveCapacityCamera { + + /** + * Total number of video streams that can be used for livestreaming + * Total number of video streams that the camera can live stream + */ + private Integer availableVideoNumber; + + /** + * Maximum number of video streams that the camera can live stream at the same time. + */ + private Integer coexistVideoNumberMax; + + /** + * Camera index, composed of product type enumeration and gimbal index. + */ + private PayloadIndex cameraIndex; + + private List videoList; + + public RcLiveCapacityCamera() { + } + + @Override + public String toString() { + return "CapacityCameraReceiver{" + + "availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", cameraIndex=" + cameraIndex + + ", videoList=" + videoList + + '}'; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public RcLiveCapacityCamera setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public RcLiveCapacityCamera setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public PayloadIndex getCameraIndex() { + return cameraIndex; + } + + public RcLiveCapacityCamera setCameraIndex(PayloadIndex cameraIndex) { + this.cameraIndex = cameraIndex; + return this; + } + + public List getVideoList() { + return videoList; + } + + public RcLiveCapacityCamera setVideoList(List videoList) { + this.videoList = videoList; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacityDevice.java b/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacityDevice.java new file mode 100644 index 0000000..831bfc4 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacityDevice.java @@ -0,0 +1,81 @@ +package com.dji.sdk.cloudapi.livestream; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class RcLiveCapacityDevice { + + /** + * Device serial number + */ + private String sn; + + /** + * Total number of video streams that can be used for livestreaming + * Total number of video streams used for livestreaming that belongs to devices. + */ + private Integer availableVideoNumber; + + /** + * Maximum number of video streams that can be used for livestreaming at the same time + */ + private Integer coexistVideoNumberMax; + + /** + * Camera list on the device + */ + private List cameraList; + + public RcLiveCapacityDevice() { + } + + @Override + public String toString() { + return "CapacityDeviceReceiver{" + + "sn='" + sn + '\'' + + ", availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", cameraList=" + cameraList + + '}'; + } + + public String getSn() { + return sn; + } + + public RcLiveCapacityDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public RcLiveCapacityDevice setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public RcLiveCapacityDevice setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public List getCameraList() { + return cameraList; + } + + public RcLiveCapacityDevice setCameraList(List cameraList) { + this.cameraList = cameraList; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacityVideo.java b/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacityVideo.java new file mode 100644 index 0000000..640a631 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/RcLiveCapacityVideo.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.livestream; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class RcLiveCapacityVideo { + + private String videoIndex; + + private VideoTypeEnum videoType; + + public RcLiveCapacityVideo() { + } + + @Override + public String toString() { + return "CapacityVideoReceiver{" + + "videoIndex='" + videoIndex + '\'' + + ", videoType=" + videoType + + '}'; + } + + public String getVideoIndex() { + return videoIndex; + } + + public RcLiveCapacityVideo setVideoIndex(String videoIndex) { + this.videoIndex = videoIndex; + return this; + } + + public VideoTypeEnum getVideoType() { + return videoType; + } + + public RcLiveCapacityVideo setVideoType(VideoTypeEnum videoType) { + this.videoType = videoType; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/RcLivestreamAbilityUpdate.java b/src/main/java/com/dji/sdk/cloudapi/livestream/RcLivestreamAbilityUpdate.java new file mode 100644 index 0000000..25bf191 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/RcLivestreamAbilityUpdate.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.livestream; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class RcLivestreamAbilityUpdate { + + private RcLiveCapacity liveCapacity; + + public RcLivestreamAbilityUpdate() { + } + + @Override + public String toString() { + return "RcLivestreamAbilityUpdate{" + + "liveCapacity=" + liveCapacity + + '}'; + } + + public RcLiveCapacity getLiveCapacity() { + return liveCapacity; + } + + public RcLivestreamAbilityUpdate setLiveCapacity(RcLiveCapacity liveCapacity) { + this.liveCapacity = liveCapacity; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/UrlTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/livestream/UrlTypeEnum.java new file mode 100644 index 0000000..dc59a10 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/UrlTypeEnum.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/22 + */ +public enum UrlTypeEnum { + + AGORA(0), + + RTMP(1), + + RTSP(2), + + GB28181(3); + + private final int type; + + UrlTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static UrlTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(UrlTypeEnum.class, type)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/VideoQualityEnum.java b/src/main/java/com/dji/sdk/cloudapi/livestream/VideoQualityEnum.java new file mode 100644 index 0000000..df4479d --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/VideoQualityEnum.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 0.1 + * @date 2021/11/26 + */ +public enum VideoQualityEnum { + + AUTO (0), + + SMOOTH(1), + + STANDARD_DEFINITION(2), + + HIGH_DEFINITION(3), + + ULTRA_HD(4); + + private final int quality; + + VideoQualityEnum(int quality) { + this.quality = quality; + } + + @JsonValue + public int getQuality() { + return quality; + } + + @JsonCreator + public static VideoQualityEnum find(int quality) { + return Arrays.stream(values()).filter(qualityEnum -> qualityEnum.quality == quality).findAny() + .orElseThrow(() -> new CloudSDKException(VideoQualityEnum.class, quality)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/VideoTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/livestream/VideoTypeEnum.java new file mode 100644 index 0000000..256a1d1 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/VideoTypeEnum.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.livestream; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/25 + */ +public enum VideoTypeEnum { + + ZOOM("zoom"), + + WIDE("wide"), + + THERMAL("thermal"), + + NORMAL("normal"), + + IR("ir"); + + private final String type; + + VideoTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static VideoTypeEnum find(String videoType) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(videoType)).findAny() + .orElseThrow(() -> new CloudSDKException(VideoTypeEnum.class , videoType)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/livestream/api/AbstractLivestreamService.java b/src/main/java/com/dji/sdk/cloudapi/livestream/api/AbstractLivestreamService.java new file mode 100644 index 0000000..24597ea --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/livestream/api/AbstractLivestreamService.java @@ -0,0 +1,101 @@ +package com.dji.sdk.cloudapi.livestream.api; + +import com.dji.sdk.cloudapi.livestream.*; +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.services.ServicesPublish; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import com.dji.sdk.mqtt.state.TopicStateRequest; +import com.fasterxml.jackson.core.type.TypeReference; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import javax.annotation.Resource; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public abstract class AbstractLivestreamService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Livestream ability update for remote control + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_LIVESTREAM_ABILITY_UPDATE) + public void dockLivestreamAbilityUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockLivestreamAbilityUpdate not implemented"); + } + + /** + * Livestream ability update for dock + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_RC_LIVESTREAM_ABILITY_UPDATE) + public void rcLivestreamAbilityUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("rcLivestreamAbilityUpdate not implemented"); + } + + /** + * Start livestreaming + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse> liveStartPush(GatewayManager gateway, LiveStartPushRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + LiveStreamMethodEnum.LIVE_START_PUSH.getMethod(), + request); + } + + /** + * Stop livestreaming + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse liveStopPush(GatewayManager gateway, LiveStopPushRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + LiveStreamMethodEnum.LIVE_STOP_PUSH.getMethod(), + request); + } + + /** + * Set livestream quality + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse liveSetQuality(GatewayManager gateway, LiveSetQualityRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + LiveStreamMethodEnum.LIVE_SET_QUALITY.getMethod(), + request); + } + + /** + * Set livestream lens + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse liveLensChange(GatewayManager gateway, LiveLensChangeRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + LiveStreamMethodEnum.LIVE_LENS_CHANGE.getMethod(), + request); + } + + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadListFile.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadListFile.java new file mode 100644 index 0000000..40693e5 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadListFile.java @@ -0,0 +1,68 @@ +package com.dji.sdk.cloudapi.log; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public class FileUploadListFile { + + private String deviceSn; + + private List list; + + private LogModuleEnum module; + + private Integer result; + + public FileUploadListFile() { + } + + @Override + public String toString() { + return "FileUploadListFile{" + + "deviceSn='" + deviceSn + '\'' + + ", list=" + list + + ", module=" + module + + ", result=" + result + + '}'; + } + + public String getDeviceSn() { + return deviceSn; + } + + public FileUploadListFile setDeviceSn(String deviceSn) { + this.deviceSn = deviceSn; + return this; + } + + public List getList() { + return list; + } + + public FileUploadListFile setList(List list) { + this.list = list; + return this; + } + + public LogModuleEnum getModule() { + return module; + } + + public FileUploadListFile setModule(LogModuleEnum module) { + this.module = module; + return this; + } + + public Integer getResult() { + return result; + } + + public FileUploadListFile setResult(Integer result) { + this.result = result; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadListRequest.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadListRequest.java new file mode 100644 index 0000000..229fd4c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadListRequest.java @@ -0,0 +1,43 @@ +package com.dji.sdk.cloudapi.log; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class FileUploadListRequest extends BaseModel { + + /** + * Filter list of file + **/ + @NotNull + @Valid + @Size(min = 1, max = 2) + private List moduleList; + + public FileUploadListRequest() { + } + + @Override + public String toString() { + return "FileUploadListRequest{" + + "moduleList=" + moduleList + + '}'; + } + + public List getModuleList() { + return moduleList; + } + + public FileUploadListRequest setModuleList(List moduleList) { + this.moduleList = moduleList; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadListResponse.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadListResponse.java new file mode 100644 index 0000000..f814723 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadListResponse.java @@ -0,0 +1,32 @@ +package com.dji.sdk.cloudapi.log; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class FileUploadListResponse { + + private List files; + + public FileUploadListResponse() { + } + + @Override + public String toString() { + return "FileUploadListResponse{" + + "files=" + files + + '}'; + } + + public List getFiles() { + return files; + } + + public FileUploadListResponse setFiles(List files) { + this.files = files; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadProgress.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadProgress.java new file mode 100644 index 0000000..d06d24a --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadProgress.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.log; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +public class FileUploadProgress { + + private FileUploadProgressExt ext; + + private FileUploadStatusEnum status; + + public FileUploadProgress() { + } + + @Override + public String toString() { + return "FileUploadProgress{" + + "ext=" + ext + + ", status=" + status + + '}'; + } + + public FileUploadProgressExt getExt() { + return ext; + } + + public FileUploadProgress setExt(FileUploadProgressExt ext) { + this.ext = ext; + return this; + } + + public FileUploadStatusEnum getStatus() { + return status; + } + + public FileUploadProgress setStatus(FileUploadStatusEnum status) { + this.status = status; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadProgressExt.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadProgressExt.java new file mode 100644 index 0000000..55c4748 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadProgressExt.java @@ -0,0 +1,32 @@ +package com.dji.sdk.cloudapi.log; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +public class FileUploadProgressExt { + + private List files; + + public FileUploadProgressExt() { + } + + @Override + public String toString() { + return "FileUploadProgressExt{" + + "files=" + files + + '}'; + } + + public List getFiles() { + return files; + } + + public FileUploadProgressExt setFiles(List files) { + this.files = files; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadProgressFile.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadProgressFile.java new file mode 100644 index 0000000..30181ab --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadProgressFile.java @@ -0,0 +1,90 @@ +package com.dji.sdk.cloudapi.log; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +public class FileUploadProgressFile { + + private LogModuleEnum module; + + private Long size; + + private String deviceSn; + + private String key; + + private String fingerprint; + + private LogFileProgress progress; + + public FileUploadProgressFile() { + } + + @Override + public String toString() { + return "FileUploadProgressFile{" + + "module=" + module + + ", size=" + size + + ", deviceSn='" + deviceSn + '\'' + + ", key='" + key + '\'' + + ", fingerprint='" + fingerprint + '\'' + + ", progress=" + progress + + '}'; + } + + public LogModuleEnum getModule() { + return module; + } + + public FileUploadProgressFile setModule(LogModuleEnum module) { + this.module = module; + return this; + } + + public Long getSize() { + return size; + } + + public FileUploadProgressFile setSize(Long size) { + this.size = size; + return this; + } + + public String getDeviceSn() { + return deviceSn; + } + + public FileUploadProgressFile setDeviceSn(String deviceSn) { + this.deviceSn = deviceSn; + return this; + } + + public String getKey() { + return key; + } + + public FileUploadProgressFile setKey(String key) { + this.key = key; + return this; + } + + public String getFingerprint() { + return fingerprint; + } + + public FileUploadProgressFile setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + return this; + } + + public LogFileProgress getProgress() { + return progress; + } + + public FileUploadProgressFile setProgress(LogFileProgress progress) { + this.progress = progress; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStartFile.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStartFile.java new file mode 100644 index 0000000..751e38f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStartFile.java @@ -0,0 +1,75 @@ +package com.dji.sdk.cloudapi.log; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public class FileUploadStartFile { + + @NotNull + private String deviceSn; + + @NotNull + @Valid + private List list; + + @NotNull + private LogModuleEnum module; + + @NotNull + private String objectKey; + + public FileUploadStartFile() { + } + + @Override + public String toString() { + return "FileUploadStartFile{" + + "deviceSn='" + deviceSn + '\'' + + ", list=" + list + + ", module=" + module + + ", objectKey='" + objectKey + '\'' + + '}'; + } + + public String getDeviceSn() { + return deviceSn; + } + + public FileUploadStartFile setDeviceSn(String deviceSn) { + this.deviceSn = deviceSn; + return this; + } + + public List getList() { + return list; + } + + public FileUploadStartFile setList(List list) { + this.list = list; + return this; + } + + public LogModuleEnum getModule() { + return module; + } + + public FileUploadStartFile setModule(LogModuleEnum module) { + this.module = module; + return this; + } + + public String getObjectKey() { + return objectKey; + } + + public FileUploadStartFile setObjectKey(String objectKey) { + this.objectKey = objectKey; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStartParam.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStartParam.java new file mode 100644 index 0000000..df0e6af --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStartParam.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.log; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public class FileUploadStartParam { + + @NotNull + @Size(min = 1, max = 2) + @Valid + private List files; + + public FileUploadStartParam() { + } + + @Override + public String toString() { + return "FileUploadStartParam{" + + "files=" + files + + '}'; + } + + public List getFiles() { + return files; + } + + public FileUploadStartParam setFiles(List files) { + this.files = files; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStartRequest.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStartRequest.java new file mode 100644 index 0000000..366836a --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStartRequest.java @@ -0,0 +1,138 @@ +package com.dji.sdk.cloudapi.log; + +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/8 + */ +public class FileUploadStartRequest extends BaseModel { + + @NotNull + private String bucket; + + @NotNull + @Valid + private CredentialsToken credentials; + + @NotNull + private String endpoint; + + @NotNull + private String fileStoreDir; + + @NotNull + private OssTypeEnum provider; + + @NotNull + private String fileType = "text_log"; + + @NotNull + @Valid + private FileUploadStartParam params; + + @NotNull + private String region; + + public FileUploadStartRequest(StsCredentialsResponse sts) { + this.bucket = sts.getBucket(); + long expire = sts.getCredentials().getExpire(); + sts.getCredentials().setExpire(System.currentTimeMillis() + (expire - 60) * 1000); + this.credentials = sts.getCredentials(); + this.endpoint = sts.getEndpoint(); + this.fileStoreDir = sts.getObjectKeyPrefix(); + this.provider = sts.getProvider(); + this.region = sts.getRegion(); + } + + public FileUploadStartRequest() { + } + + @Override + public String toString() { + return "FileUploadStartRequest{" + + "bucket='" + bucket + '\'' + + ", credentials=" + credentials + + ", endpoint='" + endpoint + '\'' + + ", fileStoreDir='" + fileStoreDir + '\'' + + ", provider=" + provider + + ", fileType='" + fileType + '\'' + + ", params=" + params + + ", region='" + region + '\'' + + '}'; + } + + public String getBucket() { + return bucket; + } + + public FileUploadStartRequest setBucket(String bucket) { + this.bucket = bucket; + return this; + } + + public CredentialsToken getCredentials() { + return credentials; + } + + public FileUploadStartRequest setCredentials(CredentialsToken credentials) { + this.credentials = credentials; + return this; + } + + public String getEndpoint() { + return endpoint; + } + + public FileUploadStartRequest setEndpoint(String endpoint) { + this.endpoint = endpoint; + return this; + } + + public String getFileStoreDir() { + return fileStoreDir; + } + + public FileUploadStartRequest setFileStoreDir(String fileStoreDir) { + this.fileStoreDir = fileStoreDir; + return this; + } + + public OssTypeEnum getProvider() { + return provider; + } + + public FileUploadStartRequest setProvider(OssTypeEnum provider) { + this.provider = provider; + return this; + } + + public String getFileType() { + return fileType; + } + + public FileUploadStartParam getParams() { + return params; + } + + public FileUploadStartRequest setParams(FileUploadStartParam params) { + this.params = params; + return this; + } + + public String getRegion() { + return region; + } + + public FileUploadStartRequest setRegion(String region) { + this.region = region; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStatusEnum.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStatusEnum.java new file mode 100644 index 0000000..b2f87c8 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadStatusEnum.java @@ -0,0 +1,61 @@ +package com.dji.sdk.cloudapi.log; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public enum FileUploadStatusEnum { + + FILE_PULL("file_pull", false), + + FILE_ZIP("file_zip", false), + + FILE_UPLOADING("file_uploading", false), + + SENT("sent", false), + + IN_PROGRESS("in_progress", false), + + OK("ok", true), + + PAUSED("paused", false), + + REJECTED("rejected", true), + + FAILED("failed", true), + + CANCELED("canceled", true), + + TIMEOUT("timeout", true); + + private final String status; + + private final boolean end; + + FileUploadStatusEnum(String status, boolean end) { + this.status = status; + this.end = end; + } + + public boolean isEnd() { + return end; + } + + @JsonValue + public String getStatus() { + return status; + } + + @JsonCreator + public static FileUploadStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(FileUploadStatusEnum.class, status)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadUpdateRequest.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadUpdateRequest.java new file mode 100644 index 0000000..ce62daf --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadUpdateRequest.java @@ -0,0 +1,56 @@ +package com.dji.sdk.cloudapi.log; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class FileUploadUpdateRequest extends BaseModel { + + /** + * Filter list of file + **/ + @NotNull + @Valid + @Size(min = 1, max = 2) + private List moduleList; + + @NotNull + private FileUploadUpdateStatusEnum status; + + public FileUploadUpdateRequest() { + } + + @Override + public String toString() { + return "FileUploadUpdateRequest{" + + "moduleList=" + moduleList + + ", status=" + status + + '}'; + } + + public List getModuleList() { + return moduleList; + } + + public FileUploadUpdateRequest setModuleList(List moduleList) { + this.moduleList = moduleList; + return this; + } + + public FileUploadUpdateStatusEnum getStatus() { + return status; + } + + public FileUploadUpdateRequest setStatus(FileUploadUpdateStatusEnum status) { + this.status = status; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/FileUploadUpdateStatusEnum.java b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadUpdateStatusEnum.java new file mode 100644 index 0000000..64ac6c3 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/FileUploadUpdateStatusEnum.java @@ -0,0 +1,34 @@ +package com.dji.sdk.cloudapi.log; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public enum FileUploadUpdateStatusEnum { + + CANCEL("cancel"); + + private final String status; + + FileUploadUpdateStatusEnum(String status) { + this.status = status; + } + + @JsonValue + public String getStatus() { + return status; + } + + @JsonCreator + public static FileUploadUpdateStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(FileUploadUpdateStatusEnum.class, status)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/LogErrorCodeEnum.java b/src/main/java/com/dji/sdk/cloudapi/log/LogErrorCodeEnum.java new file mode 100644 index 0000000..7f70da1 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/LogErrorCodeEnum.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.log; + +import com.dji.sdk.common.IErrorInfo; +import com.dji.sdk.mqtt.events.IEventsErrorCode; +import com.dji.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum LogErrorCodeEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + DEVICE_RESTART(324001, "Device restart interrupts log export."), + + EXPORT_TIMEOUT(324012, "Compressing logs timed out. Too many logs selected. Unselect some logs and try again."), + + PULL_FAILED(324013, "Failed to obtain device log list. Try again later."), + + EMPTY_LOG_LIST(324014, "Device log list is empty. Refresh page or restart dock and try again."), + + AIRCRAFT_SHUTDOWN(324015, "Aircraft powered off or not connected. Unable to obtain log list. Make sure aircraft is inside dock. Remotely power on aircraft and try again."), + + INSUFFICIENT_STORAGE_SPACE(324016, "Insufficient dock storage space. Failed to compress logs. Clear space or try again later."), + + NO_LOG(324017, "Failed to compress logs. Unable to obtain logs of selected aircraft. Refresh page or restart dock and try again."), + + COMPRESSION_FAILED(324018, "Failed to compress logs and submit issue report. Try again later or restart dock and try again."), + + UPLOAD_FAILED(324019, "Due to network anomalies at the airport, the log upload has failed. Please retry later."), + + UNKNOWN(-1, "UNKNOWN"), + + ; + + + private final String msg; + + private final int code; + + LogErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + /** + * @param code error code + * @return enumeration object + */ + public static LogErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/LogFileIndex.java b/src/main/java/com/dji/sdk/cloudapi/log/LogFileIndex.java new file mode 100644 index 0000000..b830901 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/LogFileIndex.java @@ -0,0 +1,72 @@ +package com.dji.sdk.cloudapi.log; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public class LogFileIndex { + + @NotNull + private Integer bootIndex; + + @NotNull + private Long endTime; + + @NotNull + private Long startTime; + + @NotNull + private Long size; + + public LogFileIndex() { + } + + @Override + public String toString() { + return "LogFileIndex{" + + "bootIndex=" + bootIndex + + ", endTime=" + endTime + + ", startTime=" + startTime + + ", size=" + size + + '}'; + } + + public Integer getBootIndex() { + return bootIndex; + } + + public LogFileIndex setBootIndex(Integer bootIndex) { + this.bootIndex = bootIndex; + return this; + } + + public Long getEndTime() { + return endTime; + } + + public LogFileIndex setEndTime(Long endTime) { + this.endTime = endTime; + return this; + } + + public Long getStartTime() { + return startTime; + } + + public LogFileIndex setStartTime(Long startTime) { + this.startTime = startTime; + return this; + } + + public Long getSize() { + return size; + } + + public LogFileIndex setSize(Long size) { + this.size = size; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/LogFileProgress.java b/src/main/java/com/dji/sdk/cloudapi/log/LogFileProgress.java new file mode 100644 index 0000000..c60da51 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/LogFileProgress.java @@ -0,0 +1,102 @@ +package com.dji.sdk.cloudapi.log; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +public class LogFileProgress { + + private Integer currentStep; + + private Integer totalStep; + + private Integer progress; + + private Long finishTime; + + private Float uploadRate; + + private FileUploadStatusEnum status; + + private Integer result; + + public LogFileProgress() { + } + + @Override + public String toString() { + return "LogFileProgress{" + + "currentStep=" + currentStep + + ", totalStep=" + totalStep + + ", progress=" + progress + + ", finishTime=" + finishTime + + ", uploadRate=" + uploadRate + + ", status=" + status + + ", result=" + result + + '}'; + } + + public Integer getCurrentStep() { + return currentStep; + } + + public LogFileProgress setCurrentStep(Integer currentStep) { + this.currentStep = currentStep; + return this; + } + + public Integer getTotalStep() { + return totalStep; + } + + public LogFileProgress setTotalStep(Integer totalStep) { + this.totalStep = totalStep; + return this; + } + + public Integer getProgress() { + return progress; + } + + public LogFileProgress setProgress(Integer progress) { + this.progress = progress; + return this; + } + + public Long getFinishTime() { + return finishTime; + } + + public LogFileProgress setFinishTime(Long finishTime) { + this.finishTime = finishTime; + return this; + } + + public Float getUploadRate() { + return uploadRate; + } + + public LogFileProgress setUploadRate(Float uploadRate) { + this.uploadRate = uploadRate; + return this; + } + + public FileUploadStatusEnum getStatus() { + return status; + } + + public LogFileProgress setStatus(FileUploadStatusEnum status) { + this.status = status; + return this; + } + + public Integer getResult() { + return result; + } + + public LogFileProgress setResult(Integer result) { + this.result = result; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/LogMethodEnum.java b/src/main/java/com/dji/sdk/cloudapi/log/LogMethodEnum.java new file mode 100644 index 0000000..025d387 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/LogMethodEnum.java @@ -0,0 +1,25 @@ +package com.dji.sdk.cloudapi.log; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum LogMethodEnum { + + FILE_UPLOAD_LIST("fileupload_list"), + + FILE_UPLOAD_START("fileupload_start"), + + FILE_UPLOAD_UPDATE("fileupload_update"); + + private final String method; + + LogMethodEnum(String method) { + this.method = method; + } + + public String getMethod() { + return method; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/LogModuleEnum.java b/src/main/java/com/dji/sdk/cloudapi/log/LogModuleEnum.java new file mode 100644 index 0000000..2354933 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/LogModuleEnum.java @@ -0,0 +1,36 @@ +package com.dji.sdk.cloudapi.log; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public enum LogModuleEnum { + + DRONE("0"), + + DOCK ("3"); + + private final String domain; + + LogModuleEnum(String domain) { + this.domain = domain; + } + + @JsonCreator + public static LogModuleEnum find(String domain) { + return Arrays.stream(values()).filter(domainEnum -> domainEnum.domain.equals(domain)).findAny() + .orElseThrow(() -> new CloudSDKException(LogModuleEnum.class, domain)); + } + + @JsonValue + public String getDomain() { + return domain; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/log/api/AbstractLogService.java b/src/main/java/com/dji/sdk/cloudapi/log/api/AbstractLogService.java new file mode 100644 index 0000000..8958fa8 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/log/api/AbstractLogService.java @@ -0,0 +1,81 @@ +package com.dji.sdk.cloudapi.log.api; + +import com.dji.sdk.cloudapi.log.*; +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.services.ServicesPublish; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import com.fasterxml.jackson.core.type.TypeReference; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import javax.annotation.Resource; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/28 + */ +public abstract class AbstractLogService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Inform of file uploading progress + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FILEUPLOAD_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse fileuploadProgress(TopicEventsRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("fileuploadProgress not implemented"); + } + + /** + * Get file list of uploadable device + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse> fileuploadList(GatewayManager gateway, FileUploadListRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + LogMethodEnum.FILE_UPLOAD_LIST.getMethod(), + request); + } + + /** + * Start the log file uploading + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse fileuploadStart(GatewayManager gateway, FileUploadStartRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + LogMethodEnum.FILE_UPLOAD_START.getMethod(), + request); + } + + /** + * Update the uploding state + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse fileuploadUpdate(GatewayManager gateway, FileUploadUpdateRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + LogMethodEnum.FILE_UPLOAD_UPDATE.getMethod(), + request); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/CreateMapElementRequest.java b/src/main/java/com/dji/sdk/cloudapi/map/CreateMapElementRequest.java new file mode 100644 index 0000000..8c5947c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/CreateMapElementRequest.java @@ -0,0 +1,68 @@ +package com.dji.sdk.cloudapi.map; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "Create element request data") +public class CreateMapElementRequest { + + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "element id", format = "uuid") + private String id; + + @Schema(description = "element name", example = "PILOT 1") + @NotNull + private String name; + + @NotNull + @Valid + private ElementResource resource; + + public CreateMapElementRequest() { + } + + @Override + public String toString() { + return "CreateMapElementRequest{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", resource=" + resource + + '}'; + } + + public String getId() { + return id; + } + + public CreateMapElementRequest setId(String id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public CreateMapElementRequest setName(String name) { + this.name = name; + return this; + } + + public ElementResource getResource() { + return resource; + } + + public CreateMapElementRequest setResource(ElementResource resource) { + this.resource = resource; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/CreateMapElementResponse.java b/src/main/java/com/dji/sdk/cloudapi/map/CreateMapElementResponse.java new file mode 100644 index 0000000..26769ed --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/CreateMapElementResponse.java @@ -0,0 +1,39 @@ +package com.dji.sdk.cloudapi.map; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/16 + */ +@Schema(description = "Create element response data") +public class CreateMapElementResponse { + + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "element id", format = "uuid") + private String id; + + public CreateMapElementResponse() { + } + + @Override + public String toString() { + return "CreateMapElementResponse{" + + "id='" + id + '\'' + + '}'; + } + + public String getId() { + return id; + } + + public CreateMapElementResponse setId(String id) { + this.id = id; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/ElementContent.java b/src/main/java/com/dji/sdk/cloudapi/map/ElementContent.java new file mode 100644 index 0000000..b6aefbe --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/ElementContent.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.map; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "element content") +public class ElementContent { + + @Schema(defaultValue = "Feature", allowableValues = "Feature") + @NotNull + private String type = "Feature"; + + @NotNull + @Valid + private ElementProperty properties; + + @Valid + @NotNull + private ElementGeometryType geometry; + + public ElementContent() { + } + + @Override + public String toString() { + return "ElementContent{" + + "type='" + type + '\'' + + ", properties=" + properties + + ", geometry=" + geometry + + '}'; + } + + public String getType() { + return type; + } + + public ElementContent setType(String type) { + this.type = type; + return this; + } + + public ElementProperty getProperties() { + return properties; + } + + public ElementContent setProperties(ElementProperty properties) { + this.properties = properties; + return this; + } + + public ElementGeometryType getGeometry() { + return geometry; + } + + public ElementContent setGeometry(ElementGeometryType geometry) { + this.geometry = geometry; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/ElementCoordinate.java b/src/main/java/com/dji/sdk/cloudapi/map/ElementCoordinate.java new file mode 100644 index 0000000..8932943 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/ElementCoordinate.java @@ -0,0 +1,64 @@ +package com.dji.sdk.cloudapi.map; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "The coordinates of the element, the coordinate system is WGS84") +public class ElementCoordinate { + + @Schema(description = "longitude") + @NotNull + private Double longitude; + + @Schema(description = "latitude") + @NotNull + private Double latitude; + + @Schema(description = "altitude") + private Double altitude; + + public ElementCoordinate() { + } + + @Override + public String toString() { + return "ElementCoordinate{" + + "longitude=" + longitude + + ", latitude=" + latitude + + ", altitude=" + altitude + + '}'; + } + + public Double getLongitude() { + return longitude; + } + + public ElementCoordinate setLongitude(Double longitude) { + this.longitude = longitude; + return this; + } + + public Double getLatitude() { + return latitude; + } + + public ElementCoordinate setLatitude(Double latitude) { + this.latitude = latitude; + return this; + } + + public Double getAltitude() { + return altitude; + } + + public ElementCoordinate setAltitude(Double altitude) { + this.altitude = altitude; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/ElementGeometryType.java b/src/main/java/com/dji/sdk/cloudapi/map/ElementGeometryType.java new file mode 100644 index 0000000..0086762 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/ElementGeometryType.java @@ -0,0 +1,53 @@ +package com.dji.sdk.cloudapi.map; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", + include = JsonTypeInfo.As.EXISTING_PROPERTY, defaultImpl = ElementGeometryType.class) +@JsonSubTypes({ + @JsonSubTypes.Type(value = ElementPointGeometry.class, name = "Point"), + @JsonSubTypes.Type(value = ElementLineStringGeometry.class, name = "LineString"), + @JsonSubTypes.Type(value = ElementPolygonGeometry.class, name = "Polygon") +}) +@Schema(oneOf = {ElementPointGeometry.class, ElementLineStringGeometry.class, ElementPolygonGeometry.class}) +public abstract class ElementGeometryType { + + private String type; + + ElementGeometryType(String type) { + this.type = type; + } + + public ElementGeometryType() { + } + + public String getType() { + return type; + } + + public ElementGeometryType setType(String type) { + this.type = type; + return this; + } + + /** + * Convert coordinate data into objects and then add them to the collection. + * @return + */ + public abstract List convertToList(); + + /** + * Converts coordinates in a collection of objects to a specific type. + * @param coordinateList + */ + public abstract void adapterCoordinateType(List coordinateList); +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/ElementLineStringGeometry.java b/src/main/java/com/dji/sdk/cloudapi/map/ElementLineStringGeometry.java new file mode 100644 index 0000000..5aef1cf --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/ElementLineStringGeometry.java @@ -0,0 +1,81 @@ +package com.dji.sdk.cloudapi.map; + +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import io.swagger.v3.oas.annotations.media.Schema; +import org.springframework.util.CollectionUtils; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "line geometry") +public class ElementLineStringGeometry extends ElementGeometryType { + + @Schema(example = "LineString") + @NotNull + private String type = ElementResourceTypeEnum.LINE_STRING.getTypeName(); + + @Schema(example = "[[113.943109, 22.577378]]") + @NotNull + @Size(min = 2) + private Double[][] coordinates; + + public ElementLineStringGeometry() { + super(); + } + + @Override + public List convertToList() { + if (this.coordinates.length < 2) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + List coordinateList = new ArrayList<>(); + for (Double[] coordinate : this.coordinates) { + coordinateList.add(new ElementCoordinate() + .setLongitude(coordinate[0]) + .setLatitude(coordinate[1])); + } + return coordinateList; + } + + @Override + public void adapterCoordinateType(List coordinateList) { + if (CollectionUtils.isEmpty(coordinateList) || coordinateList.size() < 2) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + this.coordinates = new Double[coordinateList.size()][2]; + for (int i = 0; i < this.coordinates.length; i++) { + this.coordinates[i][0] = coordinateList.get(i).getLongitude(); + this.coordinates[i][1] = coordinateList.get(i).getLatitude(); + } + } + + @Override + public String toString() { + return "ElementLineStringGeometry{" + + "coordinates=" + Arrays.toString(coordinates) + + '}'; + } + + public Double[][] getCoordinates() { + return coordinates; + } + + public ElementLineStringGeometry setCoordinates(Double[][] coordinates) { + this.coordinates = coordinates; + return this; + } + + @Override + public String getType() { + return type; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/ElementPointGeometry.java b/src/main/java/com/dji/sdk/cloudapi/map/ElementPointGeometry.java new file mode 100644 index 0000000..5bed461 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/ElementPointGeometry.java @@ -0,0 +1,77 @@ +package com.dji.sdk.cloudapi.map; + +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import io.swagger.v3.oas.annotations.media.Schema; +import org.springframework.util.CollectionUtils; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "point geometry") +public class ElementPointGeometry extends ElementGeometryType { + + @Schema(example = "Point") + @NotNull + private String type = ElementResourceTypeEnum.POINT.getTypeName(); + + @Schema(example = "[113.943109, 22.577378]") + @NotNull + @Size(min = 2, max = 3) + private Double[] coordinates; + + public ElementPointGeometry() { + super(); + } + + @Override + public List convertToList() { + List coordinateList = new ArrayList<>(); + coordinateList.add(new ElementCoordinate() + .setLongitude(this.coordinates[0]) + .setLatitude(this.coordinates[1]) + .setAltitude(this.coordinates.length == 3 ? this.coordinates[2] : null)); + return coordinateList; + } + + @Override + public void adapterCoordinateType(List coordinateList) { + if (CollectionUtils.isEmpty(coordinateList)) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + this.coordinates = new Double[]{ + coordinateList.get(0).getLongitude(), + coordinateList.get(0).getLatitude(), + coordinateList.get(0).getAltitude() + }; + } + + @Override + public String toString() { + return "ElementPointGeometry{" + + "coordinates=" + Arrays.toString(coordinates) + + '}'; + } + + public Double[] getCoordinates() { + return coordinates; + } + + public ElementPointGeometry setCoordinates(Double[] coordinates) { + this.coordinates = coordinates; + return this; + } + + @Override + public String getType() { + return type; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/ElementPolygonGeometry.java b/src/main/java/com/dji/sdk/cloudapi/map/ElementPolygonGeometry.java new file mode 100644 index 0000000..7068c9d --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/ElementPolygonGeometry.java @@ -0,0 +1,82 @@ +package com.dji.sdk.cloudapi.map; + +import com.dji.sample.map.model.enums.ElementTypeEnum; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import io.swagger.v3.oas.annotations.media.Schema; +import org.springframework.util.CollectionUtils; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "polygon geometry") +public class ElementPolygonGeometry extends ElementGeometryType { + + @Schema(example = "Polygon") + @NotNull + private String type = ElementTypeEnum.POLYGON.getDesc(); + + @Schema(example = "[[[113.943109, 22.577378]]]") + @NotNull + @Size(min = 1, max = 1) + private Double[][][] coordinates; + + public ElementPolygonGeometry() { + super(); + } + + @Override + public List convertToList() { + if (this.coordinates[0].length < 3) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + List coordinateList = new ArrayList<>(); + for (Double[] coordinate : this.coordinates[0]) { + coordinateList.add(new ElementCoordinate() + .setLongitude(coordinate[0]) + .setLatitude(coordinate[1])); + } + return coordinateList; + } + + @Override + public void adapterCoordinateType(List coordinateList) { + if (CollectionUtils.isEmpty(coordinateList) || coordinateList.size() < 3) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + this.coordinates = new Double[1][coordinateList.size()][2]; + for (int i = 0; i < this.coordinates[0].length; i++) { + this.coordinates[0][i][0] = coordinateList.get(i).getLongitude(); + this.coordinates[0][i][1] = coordinateList.get(i).getLatitude(); + } + } + + @Override + public String toString() { + return "ElementPolygonGeometry{" + + "coordinates=" + Arrays.toString(coordinates) + + '}'; + } + + public Double[][][] getCoordinates() { + return coordinates; + } + + public ElementPolygonGeometry setCoordinates(Double[][][] coordinates) { + this.coordinates = coordinates; + return this; + } + + @Override + public String getType() { + return type; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/ElementProperty.java b/src/main/java/com/dji/sdk/cloudapi/map/ElementProperty.java new file mode 100644 index 0000000..d3a35aa --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/ElementProperty.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.map; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "properties of the element") +public class ElementProperty { + + @NotNull + @Schema(description = "element color", example = "#2D8CF0") + @Pattern(regexp = "^#[0-9a-fA-F]{6}$") + private String color; + + @JsonProperty("clampToGround") + @Schema(description = "Whether it is on the ground.") + private Boolean clampToGround; + + public ElementProperty() { + } + + @Override + public String toString() { + return "ElementProperty{" + + "color='" + color + '\'' + + ", clampToGround=" + clampToGround + + '}'; + } + + public String getColor() { + return color; + } + + public ElementProperty setColor(String color) { + this.color = color; + return this; + } + + public Boolean getClampToGround() { + return clampToGround; + } + + public ElementProperty setClampToGround(Boolean clampToGround) { + this.clampToGround = clampToGround; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/ElementResource.java b/src/main/java/com/dji/sdk/cloudapi/map/ElementResource.java new file mode 100644 index 0000000..33571d2 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/ElementResource.java @@ -0,0 +1,67 @@ +package com.dji.sdk.cloudapi.map; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Schema(description = "element resource") +public class ElementResource { + + @NotNull + @Schema(type = "int", enumAsRef = true) + private ElementResourceTypeEnum type; + + @Schema(description = "the user who created the element", example = "pilot") + @JsonProperty(value = "user_name") + private String username; + + @NotNull + @Valid + private ElementContent content; + + public ElementResource() { + } + + @Override + public String toString() { + return "ElementResource{" + + "type=" + type + + ", username='" + username + '\'' + + ", content=" + content + + '}'; + } + + public ElementResourceTypeEnum getType() { + return type; + } + + public ElementResource setType(ElementResourceTypeEnum type) { + this.type = type; + return this; + } + + public String getUsername() { + return username; + } + + public ElementResource setUsername(String username) { + this.username = username; + return this; + } + + public ElementContent getContent() { + return content; + } + + public ElementResource setContent(ElementContent content) { + this.content = content; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/ElementResourceTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/map/ElementResourceTypeEnum.java new file mode 100644 index 0000000..423be37 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/ElementResourceTypeEnum.java @@ -0,0 +1,48 @@ +package com.dji.sdk.cloudapi.map; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(enumAsRef = true, description = "

0: Point

1: LineString

2: Polygon

", allowableValues = {"0", "1", "2"}) +public enum ElementResourceTypeEnum { + + POINT(0, "Point"), + + LINE_STRING(1, "LineString"), + + POLYGON(2, "Polygon"); + + private final int type; + + private final String typeName; + + ElementResourceTypeEnum(int type, String typeName) { + this.type = type; + this.typeName = typeName; + } + + public String getTypeName() { + return typeName; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static ElementResourceTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(ElementResourceTypeEnum.class, type)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/GetMapElementsResponse.java b/src/main/java/com/dji/sdk/cloudapi/map/GetMapElementsResponse.java new file mode 100644 index 0000000..d2b0c71 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/GetMapElementsResponse.java @@ -0,0 +1,100 @@ +package com.dji.sdk.cloudapi.map; + +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Schema(description = "element group data") +public class GetMapElementsResponse extends BaseModel { + + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "group id", format = "uuid") + private String id; + + @NotNull + @Schema(description = "group name", example = "Pilot Share Layer") + private String name; + + @NotNull + private GroupTypeEnum type; + + @NotNull + @Valid + @Schema(description = "data collection of elements") + private List elements; + + @JsonProperty(value = "is_lock") + @NotNull + @Schema(description = "Whether the element group is locked.") + private Boolean lock; + + public GetMapElementsResponse() { + } + + @Override + public String toString() { + return "GetMapElementsResponse{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", type=" + type + + ", elements=" + elements + + ", lock=" + lock + + '}'; + } + + public String getId() { + return id; + } + + public GetMapElementsResponse setId(String id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public GetMapElementsResponse setName(String name) { + this.name = name; + return this; + } + + public GroupTypeEnum getType() { + return type; + } + + public GetMapElementsResponse setType(GroupTypeEnum type) { + this.type = type; + return this; + } + + public List getElements() { + return elements; + } + + public GetMapElementsResponse setElements(List elements) { + this.elements = elements; + return this; + } + + public Boolean getLock() { + return lock; + } + + public GetMapElementsResponse setLock(Boolean lock) { + this.lock = lock; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/GroupTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/map/GroupTypeEnum.java new file mode 100644 index 0000000..1319a57 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/GroupTypeEnum.java @@ -0,0 +1,44 @@ +package com.dji.sdk.cloudapi.map; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/15 + */ +@Schema(description = "

0: custom element group

1: default element group

2: APP shared element group " + + "(type=2 is an APP element group, PILOT will add map elements to this element group by default, " + + "and there must be an APP shared element group. " + + "It is recommended that in the same workspace, there are And there is only one APP shared element group)

", + enumAsRef = true, type = "int", allowableValues = {"0", "1", "2"}) +public enum GroupTypeEnum { + + NORMAL(0), + + DEFAULT(1), + + SHARED(2); + + private final int type; + + GroupTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static GroupTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(GroupTypeEnum.class, type)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/MapElementCreateWsResponse.java b/src/main/java/com/dji/sdk/cloudapi/map/MapElementCreateWsResponse.java new file mode 100644 index 0000000..74933f5 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/MapElementCreateWsResponse.java @@ -0,0 +1,120 @@ +package com.dji.sdk.cloudapi.map; + +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/19 + */ +@Schema(description = "BizCode: map_element_create.

Websocket response data when element is created.

") +public class MapElementCreateWsResponse extends BaseModel { + + @JsonProperty("group_id") + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "group id", format = "uuid") + private String groupId; + + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "element id", format = "uuid") + private String id; + + @NotNull + @Schema(description = "element name", example = "PILOT 1") + private String name; + + @NotNull + @Schema(description = "element create time", example = "123456789012") + @JsonProperty(value = "create_time") + @Min(123456789012L) + private Long createTime; + + @NotNull + @Schema(description = "element update time", example = "123456789012") + @JsonProperty(value = "update_time") + @Min(123456789012L) + private Long updateTime; + + @NotNull + @Valid + private ElementResource resource; + + public MapElementCreateWsResponse() { + } + + @Override + public String toString() { + return "MapElementCreateWsResponse{" + + "groupId='" + groupId + '\'' + + ", id='" + id + '\'' + + ", name='" + name + '\'' + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + ", resource=" + resource + + '}'; + } + + public String getId() { + return id; + } + + public MapElementCreateWsResponse setId(String id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public MapElementCreateWsResponse setName(String name) { + this.name = name; + return this; + } + + public Long getCreateTime() { + return createTime; + } + + public MapElementCreateWsResponse setCreateTime(Long createTime) { + this.createTime = createTime; + return this; + } + + public Long getUpdateTime() { + return updateTime; + } + + public MapElementCreateWsResponse setUpdateTime(Long updateTime) { + this.updateTime = updateTime; + return this; + } + + public ElementResource getResource() { + return resource; + } + + public MapElementCreateWsResponse setResource(ElementResource resource) { + this.resource = resource; + return this; + } + + public String getGroupId() { + return groupId; + } + + public MapElementCreateWsResponse setGroupId(String groupId) { + this.groupId = groupId; + return this; + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/MapElementDeleteWsResponse.java b/src/main/java/com/dji/sdk/cloudapi/map/MapElementDeleteWsResponse.java new file mode 100644 index 0000000..fdf48ae --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/MapElementDeleteWsResponse.java @@ -0,0 +1,57 @@ +package com.dji.sdk.cloudapi.map; + +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/19 + */ +@Schema(description = "BizCode: map_element_delete.

Websocket response data when element is deleted.

") +public class MapElementDeleteWsResponse extends BaseModel { + + @JsonProperty("group_id") + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "group id", format = "uuid") + private String groupId; + + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "element id", format = "uuid") + private String id; + + public MapElementDeleteWsResponse() { + } + + @Override + public String toString() { + return "MapElementDeleteWsResponse{" + + "groupId='" + groupId + '\'' + + ", id='" + id + '\'' + + '}'; + } + + public String getGroupId() { + return groupId; + } + + public MapElementDeleteWsResponse setGroupId(String groupId) { + this.groupId = groupId; + return this; + } + + public String getId() { + return id; + } + + public MapElementDeleteWsResponse setId(String id) { + this.id = id; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/MapElementUpdateWsResponse.java b/src/main/java/com/dji/sdk/cloudapi/map/MapElementUpdateWsResponse.java new file mode 100644 index 0000000..2ace077 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/MapElementUpdateWsResponse.java @@ -0,0 +1,120 @@ +package com.dji.sdk.cloudapi.map; + +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/19 + */ +@Schema(description = "BizCode: map_element_update.

Websocket response data when the element is updated.

") +public class MapElementUpdateWsResponse extends BaseModel { + + @JsonProperty("group_id") + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "group id", format = "uuid") + private String groupId; + + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "element id", format = "uuid") + private String id; + + @NotNull + @Schema(description = "element name", example = "PILOT 1") + private String name; + + @NotNull + @Schema(description = "element create time", example = "123456789012") + @JsonProperty(value = "create_time") + @Min(123456789012L) + private Long createTime; + + @NotNull + @Schema(description = "element update time", example = "123456789012") + @JsonProperty(value = "update_time") + @Min(123456789012L) + private Long updateTime; + + @NotNull + @Valid + private ElementResource resource; + + public MapElementUpdateWsResponse() { + } + + @Override + public String toString() { + return "MapElementUpdateWsResponse{" + + "groupId='" + groupId + '\'' + + ", id='" + id + '\'' + + ", name='" + name + '\'' + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + ", resource=" + resource + + '}'; + } + + public String getId() { + return id; + } + + public MapElementUpdateWsResponse setId(String id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public MapElementUpdateWsResponse setName(String name) { + this.name = name; + return this; + } + + public Long getCreateTime() { + return createTime; + } + + public MapElementUpdateWsResponse setCreateTime(Long createTime) { + this.createTime = createTime; + return this; + } + + public Long getUpdateTime() { + return updateTime; + } + + public MapElementUpdateWsResponse setUpdateTime(Long updateTime) { + this.updateTime = updateTime; + return this; + } + + public ElementResource getResource() { + return resource; + } + + public MapElementUpdateWsResponse setResource(ElementResource resource) { + this.resource = resource; + return this; + } + + public String getGroupId() { + return groupId; + } + + public MapElementUpdateWsResponse setGroupId(String groupId) { + this.groupId = groupId; + return this; + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/MapGroupElement.java b/src/main/java/com/dji/sdk/cloudapi/map/MapGroupElement.java new file mode 100644 index 0000000..f360571 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/MapGroupElement.java @@ -0,0 +1,102 @@ +package com.dji.sdk.cloudapi.map; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Schema(description = "element data") +public class MapGroupElement { + + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "element id", format = "uuid") + private String id; + + @NotNull + @Schema(description = "element name", example = "PILOT 1") + private String name; + + @NotNull + @Schema(description = "element create time", example = "123456789012") + @JsonProperty(value = "create_time") + @Min(123456789012L) + private Long createTime; + + @NotNull + @Schema(description = "element update time", example = "123456789012") + @JsonProperty(value = "update_time") + @Min(123456789012L) + private Long updateTime; + + @NotNull + @Valid + private ElementResource resource; + + public MapGroupElement() { + } + + @Override + public String toString() { + return "MapGroupElement{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + ", resource=" + resource + + '}'; + } + + public String getId() { + return id; + } + + public MapGroupElement setId(String id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public MapGroupElement setName(String name) { + this.name = name; + return this; + } + + public Long getCreateTime() { + return createTime; + } + + public MapGroupElement setCreateTime(Long createTime) { + this.createTime = createTime; + return this; + } + + public Long getUpdateTime() { + return updateTime; + } + + public MapGroupElement setUpdateTime(Long updateTime) { + this.updateTime = updateTime; + return this; + } + + public ElementResource getResource() { + return resource; + } + + public MapGroupElement setResource(ElementResource resource) { + this.resource = resource; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/MapGroupRefreshWsResponse.java b/src/main/java/com/dji/sdk/cloudapi/map/MapGroupRefreshWsResponse.java new file mode 100644 index 0000000..b30c2ea --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/MapGroupRefreshWsResponse.java @@ -0,0 +1,45 @@ +package com.dji.sdk.cloudapi.map; + +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/19 + */ +@Schema(description = "BizCode: map_group_refresh.

When several elements have changed on the server end, such as drag an element on web end, the user end can be notified through WebSocket. " + + "The downward parameter has the layer group_id. The user end can call \"*Obtain Map Element List*\" to refresh the element list through http after receiving the ID.

") +public class MapGroupRefreshWsResponse extends BaseModel { + + @JsonProperty("ids") + @NotNull + @Size(min = 1) + @Schema(description = "group id collection", format = "uuid") + private List<@Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") String> ids; + + public MapGroupRefreshWsResponse() { + } + + @Override + public String toString() { + return "MapGroupRefreshWsResponse{" + + "ids=" + ids + + '}'; + } + + public List getIds() { + return ids; + } + + public MapGroupRefreshWsResponse setIds(List ids) { + this.ids = ids; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/UpdateMapElementRequest.java b/src/main/java/com/dji/sdk/cloudapi/map/UpdateMapElementRequest.java new file mode 100644 index 0000000..1c712be --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/UpdateMapElementRequest.java @@ -0,0 +1,52 @@ +package com.dji.sdk.cloudapi.map; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/1 + */ +@Schema(description = "Update element request data") +public class UpdateMapElementRequest { + + @Schema(description = "element name", example = "PILOT 1") + @NotNull + private String name; + + @NotNull + @Valid + private ElementContent content; + + public UpdateMapElementRequest() { + } + + @Override + public String toString() { + return "UpdateMapElementRequest{" + + "name='" + name + '\'' + + ", content=" + content + + '}'; + } + + public String getName() { + return name; + } + + public UpdateMapElementRequest setName(String name) { + this.name = name; + return this; + } + + public ElementContent getContent() { + return content; + } + + public UpdateMapElementRequest setContent(ElementContent content) { + this.content = content; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/map/api/IHttpMapService.java b/src/main/java/com/dji/sdk/cloudapi/map/api/IHttpMapService.java new file mode 100644 index 0000000..be0530b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/map/api/IHttpMapService.java @@ -0,0 +1,124 @@ +package com.dji.sdk.cloudapi.map.api; + +import com.dji.sdk.cloudapi.map.CreateMapElementRequest; +import com.dji.sdk.cloudapi.map.CreateMapElementResponse; +import com.dji.sdk.cloudapi.map.GetMapElementsResponse; +import com.dji.sdk.cloudapi.map.UpdateMapElementRequest; +import com.dji.sdk.common.HttpResultResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Tag(name = "map interface") +public interface IHttpMapService { + + String PREFIX = "map/api/v1"; + + /** + * In the first connection, pilot will send out this http request to get the group element list. + * Also, if pilot receives a group refresh instruction from WebSocket, + * it needs the same interface to request the group element list. + * @param workspaceId + * @param groupId + * @param isDistributed + * @param req + * @param rsp + * @return + */ + @Operation(summary = "get map elements", description = "In the first connection, pilot will send out this http " + + "request to get the group element list. Also, if pilot receives a group refresh instruction from " + + "WebSocket, it needs the same interface to request the group element list.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + @Parameter(name = "group_id", description = "element group id. The same element group can contain " + + "multiple map elements, which is equivalent to grouping map elements. " + + "When initiating the request, if the group id parameter is not included, " + + "the server needs to return all map elements. If the group id is specified, " + + "it only needs to return the set of elements in the specified element group", schema = @Schema(format = "uuid")), + @Parameter(name = "is_distributed", description = "Whether the element group is distributed.") + }) + @GetMapping(PREFIX + "/workspaces/{workspace_id}/element-groups") + HttpResultResponse> getMapElements( + @PathVariable(name = "workspace_id") String workspaceId, + @RequestParam(name = "group_id", required = false) String groupId, + @RequestParam(name = "is_distributed", required = false) Boolean isDistributed, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * When user draws a point, line or polygon on the PILOT/Web side. + * @param workspaceId + * @param groupId + * @param elementCreate + * @param req + * @param rsp + * @return + */ + @Operation(summary = "create map element", description = "When user draws a point, line or polygon on the PILOT/Web side.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + @Parameter(name = "group_id", description = "element group id. The same element group can contain " + + "multiple map elements, which is equivalent to grouping map elements. " + + "When initiating the request, if the group id parameter is not included, " + + "the server needs to return all map elements. If the group id is specified, " + + "it only needs to return the set of elements in the specified element group", schema = @Schema(format = "uuid")) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/element-groups/{group_id}/elements") + HttpResultResponse createMapElement( + @PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "group_id") String groupId, + @Valid @RequestBody CreateMapElementRequest elementCreate, + HttpServletRequest req, HttpServletResponse rsp); + + + /** + * When user edits a point, line or polygon on the PILOT/Web side. + * @param workspaceId + * @param elementId + * @param elementUpdate + * @param req + * @param rsp + * @return + */ + @Operation(summary = "update map element", description = "When user edits a point, line or polygon on the PILOT/Web side.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + @Parameter(name = "element_id", description = "element id", schema = @Schema(format = "uuid")) + }) + @PutMapping(PREFIX + "/workspaces/{workspace_id}/elements/{element_id}") + HttpResultResponse updateMapElement( + @PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "element_id") String elementId, + @Valid @RequestBody UpdateMapElementRequest elementUpdate, + HttpServletRequest req, HttpServletResponse rsp); + + + /** + * When user delete a point, line or polygon on the PILOT/Web side. + * @param workspaceId + * @param elementId + * @return + */ + @Operation(summary = "delete map element", description = "When user delete a point, line or polygon on the PILOT/Web side.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + @Parameter(name = "element_id", description = "element id", schema = @Schema(format = "uuid")) + }) + @DeleteMapping(PREFIX + "/workspaces/{workspace_id}/elements/{element_id}") + HttpResultResponse deleteMapElement( + @PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "element_id") String elementId, + HttpServletRequest req, HttpServletResponse rsp); + +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/media/FastUploadExtension.java b/src/main/java/com/dji/sdk/cloudapi/media/FastUploadExtension.java new file mode 100644 index 0000000..5426ceb --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/FastUploadExtension.java @@ -0,0 +1,99 @@ +package com.dji.sdk.cloudapi.media; + +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media file fast upload extension data") +public class FastUploadExtension { + + @NotNull + @JsonProperty("drone_model_key") + @Schema(description = "drone device product enum") + private DeviceEnum droneModelKey; + + @JsonProperty("is_original") + @NotNull + @Schema(description = "Whether the image is the original image.") + private Boolean original; + + @NotNull + @JsonProperty("payload_model_key") + @Schema(description = "payload device product enum", example = "1-42-0") + private DeviceEnum payloadModelKey; + + @NotNull + @JsonProperty("tinny_fingerprint") + @Schema(description = "tiny fingerprint of the file.", example = "297f490b0252690d3f93841818567cc6_2022_8_31_15_16_16") + private String tinnyFingerprint; + + @NotNull + @Schema(description = "drone sn", example = "1AD3CA2VL3LAD6") + private String sn; + + public FastUploadExtension() { + } + + @Override + public String toString() { + return "FastUploadExtension{" + + "droneModelKey=" + droneModelKey + + ", original=" + original + + ", payloadModelKey=" + payloadModelKey + + ", tinnyFingerprint='" + tinnyFingerprint + '\'' + + ", sn='" + sn + '\'' + + '}'; + } + + public DeviceEnum getDroneModelKey() { + return droneModelKey; + } + + public FastUploadExtension setDroneModelKey(DeviceEnum droneModelKey) { + this.droneModelKey = droneModelKey; + return this; + } + + public Boolean getOriginal() { + return original; + } + + public FastUploadExtension setOriginal(Boolean original) { + this.original = original; + return this; + } + + public DeviceEnum getPayloadModelKey() { + return payloadModelKey; + } + + public FastUploadExtension setPayloadModelKey(DeviceEnum payloadModelKey) { + this.payloadModelKey = payloadModelKey; + return this; + } + + public String getTinnyFingerprint() { + return tinnyFingerprint; + } + + public FastUploadExtension setTinnyFingerprint(String tinnyFingerprint) { + this.tinnyFingerprint = tinnyFingerprint; + return this; + } + + public String getSn() { + return sn; + } + + public FastUploadExtension setSn(String sn) { + this.sn = sn; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/FileUploadCallback.java b/src/main/java/com/dji/sdk/cloudapi/media/FileUploadCallback.java new file mode 100644 index 0000000..826c468 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/FileUploadCallback.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.media; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +public class FileUploadCallback { + + private Integer result; + + private Integer progress; + + private FileUploadCallbackFile file; + + public FileUploadCallback() { + } + + @Override + public String toString() { + return "FileUploadCallback{" + + "result=" + result + + ", progress=" + progress + + ", file=" + file + + '}'; + } + + public Integer getResult() { + return result; + } + + public FileUploadCallback setResult(Integer result) { + this.result = result; + return this; + } + + public Integer getProgress() { + return progress; + } + + public FileUploadCallback setProgress(Integer progress) { + this.progress = progress; + return this; + } + + public FileUploadCallbackFile getFile() { + return file; + } + + public FileUploadCallback setFile(FileUploadCallbackFile file) { + this.file = file; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/FileUploadCallbackFile.java b/src/main/java/com/dji/sdk/cloudapi/media/FileUploadCallbackFile.java new file mode 100644 index 0000000..65168d1 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/FileUploadCallbackFile.java @@ -0,0 +1,78 @@ +package com.dji.sdk.cloudapi.media; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +public class FileUploadCallbackFile { + + private UploadCallbackFileExtension ext; + + private String name; + + private String path; + + private String objectKey; + + private UploadCallbackFileMetadata metadata; + + public FileUploadCallbackFile() { + } + + @Override + public String toString() { + return "FileUploadCallbackFile{" + + "ext=" + ext + + ", name='" + name + '\'' + + ", path='" + path + '\'' + + ", objectKey='" + objectKey + '\'' + + ", metadata=" + metadata + + '}'; + } + + public UploadCallbackFileExtension getExt() { + return ext; + } + + public FileUploadCallbackFile setExt(UploadCallbackFileExtension ext) { + this.ext = ext; + return this; + } + + public String getName() { + return name; + } + + public FileUploadCallbackFile setName(String name) { + this.name = name; + return this; + } + + public String getPath() { + return path; + } + + public FileUploadCallbackFile setPath(String path) { + this.path = path; + return this; + } + + public String getObjectKey() { + return objectKey; + } + + public FileUploadCallbackFile setObjectKey(String objectKey) { + this.objectKey = objectKey; + return this; + } + + public UploadCallbackFileMetadata getMetadata() { + return metadata; + } + + public FileUploadCallbackFile setMetadata(UploadCallbackFileMetadata metadata) { + this.metadata = metadata; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/FolderUploadCallbackRequest.java b/src/main/java/com/dji/sdk/cloudapi/media/FolderUploadCallbackRequest.java new file mode 100644 index 0000000..78abab4 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/FolderUploadCallbackRequest.java @@ -0,0 +1,69 @@ +package com.dji.sdk.cloudapi.media; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/19 + */ +@Schema(description = "folder upload callback request data") +public class FolderUploadCallbackRequest { + + @NotNull + @JsonProperty("file_group_id") + @Schema(description = "file group id", format = "uuid") + private String fileGroupId; + + @NotNull + @JsonProperty("file_count") + @Schema(description = "total amount of media in the file group") + private Integer fileCount; + + @NotNull + @JsonProperty("file_uploaded_count") + @Schema(description = "the number of uploaded media in the file group") + private Integer fileUploadedCount; + + public FolderUploadCallbackRequest() { + } + + @Override + public String toString() { + return "FolderUploadCallbackRequest{" + + "fileGroupId='" + fileGroupId + '\'' + + ", fileCount=" + fileCount + + ", fileUploadedCount=" + fileUploadedCount + + '}'; + } + + public String getFileGroupId() { + return fileGroupId; + } + + public FolderUploadCallbackRequest setFileGroupId(String fileGroupId) { + this.fileGroupId = fileGroupId; + return this; + } + + public Integer getFileCount() { + return fileCount; + } + + public FolderUploadCallbackRequest setFileCount(Integer fileCount) { + this.fileCount = fileCount; + return this; + } + + public Integer getFileUploadedCount() { + return fileUploadedCount; + } + + public FolderUploadCallbackRequest setFileUploadedCount(Integer fileUploadedCount) { + this.fileUploadedCount = fileUploadedCount; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/GetFileFingerprintRequest.java b/src/main/java/com/dji/sdk/cloudapi/media/GetFileFingerprintRequest.java new file mode 100644 index 0000000..7fe08bb --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/GetFileFingerprintRequest.java @@ -0,0 +1,41 @@ +package com.dji.sdk.cloudapi.media; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/16 + */ +@Schema(description = "get request data for tiny fingerprints of existing files") +public class GetFileFingerprintRequest { + + @NotNull + @Schema(description = "tiny fingerprints collection", example = "[\"297f490b0252690d3f93841818567cc6_2022_8_31_15_16_16\"]") + @JsonProperty("tiny_fingerprints") + private List tinyFingerprints; + + public GetFileFingerprintRequest() { + } + + @Override + public String toString() { + return "GetFileFingerprintRequest{" + + "tinyFingerprints=" + tinyFingerprints + + '}'; + } + + public List getTinyFingerprints() { + return tinyFingerprints; + } + + public GetFileFingerprintRequest setTinyFingerprints(List tinyFingerprints) { + this.tinyFingerprints = tinyFingerprints; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/GetFileFingerprintResponse.java b/src/main/java/com/dji/sdk/cloudapi/media/GetFileFingerprintResponse.java new file mode 100644 index 0000000..d0ab21a --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/GetFileFingerprintResponse.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.media; + + +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/16 + */ +@Schema(description = "response data for tiny fingerprints of existing files") +public class GetFileFingerprintResponse extends BaseModel { + + @NotNull + @Schema(description = "tiny fingerprints collection", example = "[\"297f490b0252690d3f93841818567cc6_2022_8_31_15_16_16\"]") + @JsonProperty("tiny_fingerprints") + private List tinyFingerprints; + + public GetFileFingerprintResponse() { + } + + @Override + public String toString() { + return "GetFileFingerprintResponse{" + + "tinyFingerprints=" + tinyFingerprints + + '}'; + } + + public List getTinyFingerprints() { + return tinyFingerprints; + } + + public GetFileFingerprintResponse setTinyFingerprints(List tinyFingerprints) { + this.tinyFingerprints = tinyFingerprints; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/HighestPriorityUploadFlightTaskMedia.java b/src/main/java/com/dji/sdk/cloudapi/media/HighestPriorityUploadFlightTaskMedia.java new file mode 100644 index 0000000..8eadb0d --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/HighestPriorityUploadFlightTaskMedia.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.media; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public class HighestPriorityUploadFlightTaskMedia { + + private String flightId; + + public HighestPriorityUploadFlightTaskMedia() { + } + + @Override + public String toString() { + return "HighestPriorityUploadFlightTaskMedia{" + + "flightId='" + flightId + '\'' + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public HighestPriorityUploadFlightTaskMedia setFlightId(String flightId) { + this.flightId = flightId; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/MediaFastUploadRequest.java b/src/main/java/com/dji/sdk/cloudapi/media/MediaFastUploadRequest.java new file mode 100644 index 0000000..78c22b3 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/MediaFastUploadRequest.java @@ -0,0 +1,79 @@ +package com.dji.sdk.cloudapi.media; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media fast upload request data") +public class MediaFastUploadRequest { + + @NotNull + @Valid + private FastUploadExtension ext; + + @NotNull + @Schema(description = "media file fingerprint", example = "7F78C9F1999425CB61F10E1FE206009E") + private String fingerprint; + + @NotNull + @Schema(description = "media file name", example = "DJI_20220831151616_0004_W_Waypoint4.JPG") + private String name; + + @Schema(description = "media file path. This value is empty if the photo was not taken in the wayline.", example = "DJI_202208311455_008_Waypoint1") + private String path; + + public MediaFastUploadRequest() { + } + + @Override + public String toString() { + return "MediaFastUploadRequest{" + + "ext=" + ext + + ", fingerprint='" + fingerprint + '\'' + + ", name='" + name + '\'' + + ", path='" + path + '\'' + + '}'; + } + + public FastUploadExtension getExt() { + return ext; + } + + public MediaFastUploadRequest setExt(FastUploadExtension ext) { + this.ext = ext; + return this; + } + + public String getFingerprint() { + return fingerprint; + } + + public MediaFastUploadRequest setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + return this; + } + + public String getName() { + return name; + } + + public MediaFastUploadRequest setName(String name) { + this.name = name; + return this; + } + + public String getPath() { + return path; + } + + public MediaFastUploadRequest setPath(String path) { + this.path = path; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/MediaFileExtension.java b/src/main/java/com/dji/sdk/cloudapi/media/MediaFileExtension.java new file mode 100644 index 0000000..8e2f7c9 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/MediaFileExtension.java @@ -0,0 +1,114 @@ +package com.dji.sdk.cloudapi.media; + +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media file upload callback extension data") +public class MediaFileExtension { + + @NotNull + @JsonProperty("drone_model_key") + @Schema(description = "drone device product enum") + private DeviceEnum droneModelKey; + + @NotNull + @JsonProperty("file_group_id") + @Schema(description = "If the media file was shot during the wayline, this value will not be null.", format = "uuid") + private String fileGroupId; + + @JsonProperty("is_original") + @NotNull + @Schema(description = "Whether the image is the original image.") + private Boolean original; + + @NotNull + @JsonProperty("payload_model_key") + @Schema(description = "payload device product enum", example = "1-42-0") + private DeviceEnum payloadModelKey; + + @NotNull + @JsonProperty("tinny_fingerprint") + @Schema(description = "tiny fingerprint of the file.", example = "297f490b0252690d3f93841818567cc6_2022_8_31_15_16_16") + private String tinnyFingerprint; + + @NotNull + @Schema(description = "drone sn", example = "1AD3CA2VL3LAD6") + private String sn; + + public MediaFileExtension() { + } + + @Override + public String toString() { + return "MediaFileExtension{" + + "droneModelKey=" + droneModelKey + + ", fileGroupId='" + fileGroupId + '\'' + + ", original=" + original + + ", payloadModelKey=" + payloadModelKey + + ", tinnyFingerprint='" + tinnyFingerprint + '\'' + + ", sn='" + sn + '\'' + + '}'; + } + + public DeviceEnum getDroneModelKey() { + return droneModelKey; + } + + public MediaFileExtension setDroneModelKey(DeviceEnum droneModelKey) { + this.droneModelKey = droneModelKey; + return this; + } + + public Boolean getOriginal() { + return original; + } + + public MediaFileExtension setOriginal(Boolean original) { + this.original = original; + return this; + } + + public DeviceEnum getPayloadModelKey() { + return payloadModelKey; + } + + public MediaFileExtension setPayloadModelKey(DeviceEnum payloadModelKey) { + this.payloadModelKey = payloadModelKey; + return this; + } + + public String getTinnyFingerprint() { + return tinnyFingerprint; + } + + public MediaFileExtension setTinnyFingerprint(String tinnyFingerprint) { + this.tinnyFingerprint = tinnyFingerprint; + return this; + } + + public String getSn() { + return sn; + } + + public MediaFileExtension setSn(String sn) { + this.sn = sn; + return this; + } + + public String getFileGroupId() { + return fileGroupId; + } + + public MediaFileExtension setFileGroupId(String fileGroupId) { + this.fileGroupId = fileGroupId; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/MediaFileMetadata.java b/src/main/java/com/dji/sdk/cloudapi/media/MediaFileMetadata.java new file mode 100644 index 0000000..5a5a17b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/MediaFileMetadata.java @@ -0,0 +1,104 @@ +package com.dji.sdk.cloudapi.media; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media file metadata") +public class MediaFileMetadata { + + @JsonProperty("absolute_altitude") + @NotNull + @Schema(description = "absolute height", example = "-36.889") + private Double absoluteAltitude; + + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssVV") + @NotNull + @Schema(description = "media create time", example = "2023-01-01T20:00:00+08:00") + @JsonProperty("created_time") + private LocalDateTime createdTime; + + @NotNull + @JsonProperty("gimbal_yaw_degree") + @Schema(description = "gimbal yaw degree", example = "-4.3") + private Double gimbalYawDegree; + + @NotNull + @JsonProperty("shoot_position") + @Valid + @Schema(description = "The latitude and longitude of the drone when the photo was taken") + private Position shootPosition; + + @NotNull + @JsonProperty("relative_altitude") + @Schema(description = "relative altitude", example = "100.001") + private Double relativeAltitude; + + public MediaFileMetadata() { + } + + @Override + public String toString() { + return "MediaFileMetadata{" + + "absoluteAltitude=" + absoluteAltitude + + ", createdTime=" + createdTime + + ", gimbalYawDegree=" + gimbalYawDegree + + ", shootPosition=" + shootPosition + + ", relativeAltitude=" + relativeAltitude + + '}'; + } + + public Double getAbsoluteAltitude() { + return absoluteAltitude; + } + + public MediaFileMetadata setAbsoluteAltitude(Double absoluteAltitude) { + this.absoluteAltitude = absoluteAltitude; + return this; + } + + public LocalDateTime getCreatedTime() { + return createdTime; + } + + public MediaFileMetadata setCreatedTime(LocalDateTime createdTime) { + this.createdTime = createdTime; + return this; + } + + public Double getGimbalYawDegree() { + return gimbalYawDegree; + } + + public MediaFileMetadata setGimbalYawDegree(Double gimbalYawDegree) { + this.gimbalYawDegree = gimbalYawDegree; + return this; + } + + public Position getShootPosition() { + return shootPosition; + } + + public MediaFileMetadata setShootPosition(Position shootPosition) { + this.shootPosition = shootPosition; + return this; + } + + public Double getRelativeAltitude() { + return relativeAltitude; + } + + public MediaFileMetadata setRelativeAltitude(Double relativeAltitude) { + this.relativeAltitude = relativeAltitude; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/MediaMethodEnum.java b/src/main/java/com/dji/sdk/cloudapi/media/MediaMethodEnum.java new file mode 100644 index 0000000..9f6f354 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/MediaMethodEnum.java @@ -0,0 +1,24 @@ +package com.dji.sdk.cloudapi.media; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum MediaMethodEnum { + + UPLOAD_FLIGHTTASK_MEDIA_PRIORITIZE("upload_flighttask_media_prioritize"); + + private final String method; + + MediaMethodEnum(String method) { + this.method = method; + } + + @JsonValue + public String getMethod() { + return method; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/MediaSubFileTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/media/MediaSubFileTypeEnum.java new file mode 100644 index 0000000..724bd36 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/MediaSubFileTypeEnum.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.media; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/16 + */ +@Schema(description = "The type of image file.

0: normal picture;

1: panorama.

") +public enum MediaSubFileTypeEnum { + + NORMAL(0), + + PANORAMA(1); + + private final int type; + + MediaSubFileTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static MediaSubFileTypeEnum find(int type) { + return Arrays.stream(values()).filter(subFile -> subFile.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(MediaSubFileTypeEnum.class, type)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/MediaUploadCallbackRequest.java b/src/main/java/com/dji/sdk/cloudapi/media/MediaUploadCallbackRequest.java new file mode 100644 index 0000000..6567ea3 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/MediaUploadCallbackRequest.java @@ -0,0 +1,124 @@ +package com.dji.sdk.cloudapi.media; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media fast upload request data") +public class MediaUploadCallbackRequest { + + @NotNull + @Valid + private MediaFileExtension ext; + + @NotNull + @Schema(description = "media file fingerprint", example = "7F78C9F1999425CB61F10E1FE206009E") + private String fingerprint; + + @NotNull + @Schema(description = "media file name", example = "DJI_20220831151616_0004_W_Waypoint4.JPG") + private String name; + + @Schema(description = "media file path. This value is empty if the photo was not taken in the wayline.", example = "DJI_202208311455_008_Waypoint1") + private String path; + + @JsonProperty("object_key") + @NotNull + @Schema(description = "The key of the object in the bucket", example = "media/DJI_20220831151616_0004_W_Waypoint4.JPG") + private String objectKey; + + @Schema(type = "int") + @JsonProperty("sub_file_type") + @NotNull + private MediaSubFileTypeEnum subFileType; + + @Valid + @NotNull + private MediaFileMetadata metadata; + + public MediaUploadCallbackRequest() { + } + + @Override + public String toString() { + return "MediaUploadCallbackRequest{" + + "ext=" + ext + + ", fingerprint='" + fingerprint + '\'' + + ", name='" + name + '\'' + + ", path='" + path + '\'' + + ", objectKey='" + objectKey + '\'' + + ", subFileType=" + subFileType + + ", metadata=" + metadata + + '}'; + } + + public MediaFileExtension getExt() { + return ext; + } + + public MediaUploadCallbackRequest setExt(MediaFileExtension ext) { + this.ext = ext; + return this; + } + + public String getFingerprint() { + return fingerprint; + } + + public MediaUploadCallbackRequest setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + return this; + } + + public String getName() { + return name; + } + + public MediaUploadCallbackRequest setName(String name) { + this.name = name; + return this; + } + + public String getPath() { + return path; + } + + public MediaUploadCallbackRequest setPath(String path) { + this.path = path; + return this; + } + + public String getObjectKey() { + return objectKey; + } + + public MediaUploadCallbackRequest setObjectKey(String objectKey) { + this.objectKey = objectKey; + return this; + } + + public MediaSubFileTypeEnum getSubFileType() { + return subFileType; + } + + public MediaUploadCallbackRequest setSubFileType(MediaSubFileTypeEnum subFileType) { + this.subFileType = subFileType; + return this; + } + + public MediaFileMetadata getMetadata() { + return metadata; + } + + public MediaUploadCallbackRequest setMetadata(MediaFileMetadata metadata) { + this.metadata = metadata; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/Position.java b/src/main/java/com/dji/sdk/cloudapi/media/Position.java new file mode 100644 index 0000000..f192f6e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/Position.java @@ -0,0 +1,50 @@ +package com.dji.sdk.cloudapi.media; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +public class Position { + + @Schema(description = "latitude", example = "22.577666000000001") + @NotNull + private Double lat; + + @Schema(description = "longitude", example = "113.9431940000000") + @NotNull + private Double lng; + + public Position() { + } + + @Override + public String toString() { + return "Position{" + + "lat=" + lat + + ", lng=" + lng + + '}'; + } + + public Double getLat() { + return lat; + } + + public Position setLat(Double lat) { + this.lat = lat; + return this; + } + + public Double getLng() { + return lng; + } + + public Position setLng(Double lng) { + this.lng = lng; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/StorageConfigGet.java b/src/main/java/com/dji/sdk/cloudapi/media/StorageConfigGet.java new file mode 100644 index 0000000..d8f964f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/StorageConfigGet.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.media; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public class StorageConfigGet { + + private StorageConfigGetModuleEnum module; + + public StorageConfigGet() { + } + + @Override + public String toString() { + return "StorageConfigGet{" + + "module=" + module + + '}'; + } + + public StorageConfigGetModuleEnum getModule() { + return module; + } + + public StorageConfigGet setModule(StorageConfigGetModuleEnum module) { + this.module = module; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/StorageConfigGetModuleEnum.java b/src/main/java/com/dji/sdk/cloudapi/media/StorageConfigGetModuleEnum.java new file mode 100644 index 0000000..b61fe8a --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/StorageConfigGetModuleEnum.java @@ -0,0 +1,34 @@ +package com.dji.sdk.cloudapi.media; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public enum StorageConfigGetModuleEnum { + + MEDIA(0); + + private final int module; + + StorageConfigGetModuleEnum(int module) { + this.module = module; + } + + @JsonValue + public int getModule() { + return module; + } + + @JsonCreator + public StorageConfigGetModuleEnum find(int module) { + return Arrays.stream(values()).filter(moduleEnum -> moduleEnum.module == module).findAny() + .orElseThrow(() -> new CloudSDKException(StorageConfigGetModuleEnum.class, module)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/UploadCallbackFileExtension.java b/src/main/java/com/dji/sdk/cloudapi/media/UploadCallbackFileExtension.java new file mode 100644 index 0000000..d5ead91 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/UploadCallbackFileExtension.java @@ -0,0 +1,70 @@ +package com.dji.sdk.cloudapi.media; + +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +public class UploadCallbackFileExtension { + + private DeviceEnum droneModelKey; + + @JsonProperty("is_original") + private Boolean original; + + private DeviceEnum payloadModelKey; + + private String flightId; + + public UploadCallbackFileExtension() { + } + + @Override + public String toString() { + return "UploadCallbackFileExtension{" + + "droneModelKey=" + droneModelKey + + ", original=" + original + + ", payloadModelKey=" + payloadModelKey + + ", flightId='" + flightId + '\'' + + '}'; + } + + public DeviceEnum getDroneModelKey() { + return droneModelKey; + } + + public UploadCallbackFileExtension setDroneModelKey(DeviceEnum droneModelKey) { + this.droneModelKey = droneModelKey; + return this; + } + + public Boolean getOriginal() { + return original; + } + + public UploadCallbackFileExtension setOriginal(Boolean original) { + this.original = original; + return this; + } + + public DeviceEnum getPayloadModelKey() { + return payloadModelKey; + } + + public UploadCallbackFileExtension setPayloadModelKey(DeviceEnum payloadModelKey) { + this.payloadModelKey = payloadModelKey; + return this; + } + + public String getFlightId() { + return flightId; + } + + public UploadCallbackFileExtension setFlightId(String flightId) { + this.flightId = flightId; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/UploadCallbackFileMetadata.java b/src/main/java/com/dji/sdk/cloudapi/media/UploadCallbackFileMetadata.java new file mode 100644 index 0000000..e2ea7a8 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/UploadCallbackFileMetadata.java @@ -0,0 +1,85 @@ +package com.dji.sdk.cloudapi.media; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.time.LocalDateTime; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media file metadata") +public class UploadCallbackFileMetadata { + + private Double absoluteAltitude; + + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssVV") + private LocalDateTime createdTime; + + private Double gimbalYawDegree; + + private Position shootPosition; + + private Double relativeAltitude; + + public UploadCallbackFileMetadata() { + } + + @Override + public String toString() { + return "MediaFileMetadata{" + + "absoluteAltitude=" + absoluteAltitude + + ", createdTime=" + createdTime + + ", gimbalYawDegree=" + gimbalYawDegree + + ", shootPosition=" + shootPosition + + ", relativeAltitude=" + relativeAltitude + + '}'; + } + + public Double getAbsoluteAltitude() { + return absoluteAltitude; + } + + public UploadCallbackFileMetadata setAbsoluteAltitude(Double absoluteAltitude) { + this.absoluteAltitude = absoluteAltitude; + return this; + } + + public LocalDateTime getCreatedTime() { + return createdTime; + } + + public UploadCallbackFileMetadata setCreatedTime(LocalDateTime createdTime) { + this.createdTime = createdTime; + return this; + } + + public Double getGimbalYawDegree() { + return gimbalYawDegree; + } + + public UploadCallbackFileMetadata setGimbalYawDegree(Double gimbalYawDegree) { + this.gimbalYawDegree = gimbalYawDegree; + return this; + } + + public Position getShootPosition() { + return shootPosition; + } + + public UploadCallbackFileMetadata setShootPosition(Position shootPosition) { + this.shootPosition = shootPosition; + return this; + } + + public Double getRelativeAltitude() { + return relativeAltitude; + } + + public UploadCallbackFileMetadata setRelativeAltitude(Double relativeAltitude) { + this.relativeAltitude = relativeAltitude; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/UploadFlighttaskMediaPrioritize.java b/src/main/java/com/dji/sdk/cloudapi/media/UploadFlighttaskMediaPrioritize.java new file mode 100644 index 0000000..59c197f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/UploadFlighttaskMediaPrioritize.java @@ -0,0 +1,37 @@ +package com.dji.sdk.cloudapi.media; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public class UploadFlighttaskMediaPrioritize extends BaseModel { + + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + private String flightId; + + public UploadFlighttaskMediaPrioritize() { + } + + @Override + public String toString() { + return "UploadFlighttaskMediaPrioritize{" + + "flightId='" + flightId + '\'' + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public UploadFlighttaskMediaPrioritize setFlightId(String flightId) { + this.flightId = flightId; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/api/AbstractMediaService.java b/src/main/java/com/dji/sdk/cloudapi/media/api/AbstractMediaService.java new file mode 100644 index 0000000..1aa0afa --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/api/AbstractMediaService.java @@ -0,0 +1,78 @@ +package com.dji.sdk.cloudapi.media.api; + +import com.dji.sdk.annotations.CloudSDKVersion; +import com.dji.sdk.cloudapi.media.*; +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.common.GatewayTypeEnum; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import com.dji.sdk.mqtt.services.ServicesPublish; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.MessageHeaders; + +import javax.annotation.Resource; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public abstract class AbstractMediaService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Result reporting of media file uploading + * @param request + * @param headers + * @return + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FILE_UPLOAD_CALLBACK, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse fileUploadCallback(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("fileUploadCallback not implemented"); + } + + /** + * Priority report of the media file uploading + * @param request + * @param headers + * @return + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse highestPriorityUploadFlightTaskMedia(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("highestPriorityUploadFlightTaskMedia not implemented"); + } + + /** + * Set the uploading file to highest priority + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse uploadFlighttaskMediaPrioritize(GatewayManager gateway, UploadFlighttaskMediaPrioritize request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + MediaMethodEnum.UPLOAD_FLIGHTTASK_MEDIA_PRIORITIZE.getMethod(), + request); + } + + /** + * Obtain upload temporary credentials + * @param request + * @param headers + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_STORAGE_CONFIG_GET, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse> storageConfigGet(TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("storageConfigGet not implemented"); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/media/api/IHttpMediaService.java b/src/main/java/com/dji/sdk/cloudapi/media/api/IHttpMediaService.java new file mode 100644 index 0000000..81a23e0 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/media/api/IHttpMediaService.java @@ -0,0 +1,115 @@ +package com.dji.sdk.cloudapi.media.api; + +import com.dji.sdk.cloudapi.media.*; +import com.dji.sdk.common.HttpResultResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +@Tag(name = "media interface") +public interface IHttpMediaService { + + String PREFIX = "media/api/v1"; + + /** + * Check if the file has been uploaded by the fingerprint. + * @param workspaceId + * @param request + * @param req + * @param rsp + * @return + */ + @Operation(summary = "media fast upload", description = "Check if the file has been uploaded by the fingerprint.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/fast-upload") + HttpResultResponse mediaFastUpload( + @PathVariable(name = "workspace_id") String workspaceId, + @Valid @RequestBody MediaFastUploadRequest request, + HttpServletRequest req, HttpServletResponse rsp); + + + /** + * When the file is uploaded to the storage server by pilot, + * the basic information of the file is reported through this interface. + * @param workspaceId + * @param request + * @param req + * @param rsp + * @return + */ + @Operation(summary = "app reports file upload result", description = "When the file is uploaded to the storage server by pilot, " + + "the basic information of the file is reported through this interface.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }, responses = @ApiResponse(responseCode = "200", description = "OK", + content = @Content(mediaType = "application/json", + examples = {@ExampleObject(name = "responseObjectKey", + summary = "response object key", + description = "response object key", + value = "{\"code\": 0, \"message\":\"success\", \"data\": \"media/DJI_20220831151616_0004_W_Waypoint4.JPG\"}" + )}))) + + @PostMapping(PREFIX + "/workspaces/{workspace_id}/upload-callback") + HttpResultResponse mediaUploadCallback( + @PathVariable(name = "workspace_id") String workspaceId, + @Valid @RequestBody MediaUploadCallbackRequest request, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Query the files that already exist in this workspace based on the workspace id and the collection of tiny fingerprints. + * @param workspaceId + * @param request There is only one tiny_fingerprint parameter in the body. + * @param req + * @param rsp + * @return + */ + @Operation(summary = "checks whether the file fingerprint exists", description = "Query the files that already exist in this " + + "workspace based on the workspace id and the collection of tiny fingerprints.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/files/tiny-fingerprints") + HttpResultResponse getExistFileTinyFingerprint( + @PathVariable(name = "workspace_id") String workspaceId, + @Valid @RequestBody GetFileFingerprintRequest request, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Report the upload status of the media files in the file group in real time. + * @param workspaceId + * @param request + * @param req + * @param rsp + * @return + */ + @Operation(summary = "callback after the file group upload complete", description = "Report the upload status of " + + "the media files in the file group in real time.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/group-upload-callback") + HttpResultResponse folderUploadCallback( + @PathVariable(name = "workspace_id") String workspaceId, + @Valid @RequestBody FolderUploadCallbackRequest request, + HttpServletRequest req, HttpServletResponse rsp); + + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/organization/AirportBindStatusRequest.java b/src/main/java/com/dji/sdk/cloudapi/organization/AirportBindStatusRequest.java new file mode 100644 index 0000000..6697990 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/organization/AirportBindStatusRequest.java @@ -0,0 +1,32 @@ +package com.dji.sdk.cloudapi.organization; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AirportBindStatusRequest { + + private List devices; + + public AirportBindStatusRequest() { + } + + @Override + public String toString() { + return "AirportBindStatusRequest{" + + "devices=" + devices + + '}'; + } + + public List getDevices() { + return devices; + } + + public AirportBindStatusRequest setDevices(List devices) { + this.devices = devices; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/organization/AirportBindStatusResponse.java b/src/main/java/com/dji/sdk/cloudapi/organization/AirportBindStatusResponse.java new file mode 100644 index 0000000..9928c5c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/organization/AirportBindStatusResponse.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.organization; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AirportBindStatusResponse extends BaseModel { + + @NotNull + @Valid + @Size(min = 1, max = 2) + private List bindStatus; + + public AirportBindStatusResponse() { + } + + @Override + public String toString() { + return "AirportBindStatusResponse{" + + "bindStatus=" + bindStatus + + '}'; + } + + public List getBindStatus() { + return bindStatus; + } + + public AirportBindStatusResponse setBindStatus(List bindStatus) { + this.bindStatus = bindStatus; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationBindRequest.java b/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationBindRequest.java new file mode 100644 index 0000000..0facdd0 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationBindRequest.java @@ -0,0 +1,32 @@ +package com.dji.sdk.cloudapi.organization; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AirportOrganizationBindRequest { + + private List bindDevices; + + public AirportOrganizationBindRequest() { + } + + @Override + public String toString() { + return "AirportOrganizationBindRequest{" + + "bindDevices=" + bindDevices + + '}'; + } + + public List getBindDevices() { + return bindDevices; + } + + public AirportOrganizationBindRequest setBindDevices(List bindDevices) { + this.bindDevices = bindDevices; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationBindResponse.java b/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationBindResponse.java new file mode 100644 index 0000000..8155091 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationBindResponse.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.organization; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AirportOrganizationBindResponse extends BaseModel { + + @NotNull + @Valid + @Size(min = 1, max = 2) + private List errInfos; + + public AirportOrganizationBindResponse() { + } + + @Override + public String toString() { + return "AirportOrganizationBindResponse{" + + "errInfos=" + errInfos + + '}'; + } + + public List getErrInfos() { + return errInfos; + } + + public AirportOrganizationBindResponse setErrInfos(List errInfos) { + this.errInfos = errInfos; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationGetRequest.java b/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationGetRequest.java new file mode 100644 index 0000000..e3b4f4d --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationGetRequest.java @@ -0,0 +1,42 @@ +package com.dji.sdk.cloudapi.organization; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/13 + */ +public class AirportOrganizationGetRequest { + + private String deviceBindingCode; + + private String organizationId; + + public AirportOrganizationGetRequest() { + } + + @Override + public String toString() { + return "AirportOrganizationGetRequest{" + + "deviceBindingCode='" + deviceBindingCode + '\'' + + ", organizationId='" + organizationId + '\'' + + '}'; + } + + public String getDeviceBindingCode() { + return deviceBindingCode; + } + + public AirportOrganizationGetRequest setDeviceBindingCode(String deviceBindingCode) { + this.deviceBindingCode = deviceBindingCode; + return this; + } + + public String getOrganizationId() { + return organizationId; + } + + public AirportOrganizationGetRequest setOrganizationId(String organizationId) { + this.organizationId = organizationId; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationGetResponse.java b/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationGetResponse.java new file mode 100644 index 0000000..cb10abf --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/organization/AirportOrganizationGetResponse.java @@ -0,0 +1,35 @@ +package com.dji.sdk.cloudapi.organization; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/13 + */ +public class AirportOrganizationGetResponse extends BaseModel { + + @NotNull + private String organizationName; + + public AirportOrganizationGetResponse() { + } + + @Override + public String toString() { + return "AirportOrganizationGetResponse{" + + "organizationName='" + organizationName + '\'' + + '}'; + } + + public String getOrganizationName() { + return organizationName; + } + + public AirportOrganizationGetResponse setOrganizationName(String organizationName) { + this.organizationName = organizationName; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/organization/BindStatusRequestDevice.java b/src/main/java/com/dji/sdk/cloudapi/organization/BindStatusRequestDevice.java new file mode 100644 index 0000000..68a263e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/organization/BindStatusRequestDevice.java @@ -0,0 +1,88 @@ +package com.dji.sdk.cloudapi.organization; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/14 + */ +public class BindStatusRequestDevice { + + @NotNull + private String sn; + + @NotNull + @JsonProperty("is_device_bind_organization") + private Boolean deviceBindOrganization; + + @NotNull + private String organizationId; + + @NotNull + private String organizationName; + + @NotNull + private String deviceCallsign; + + public BindStatusRequestDevice() { + } + + @Override + public String toString() { + return "BindStatusRequestDevice{" + + "sn='" + sn + '\'' + + ", deviceBindOrganization=" + deviceBindOrganization + + ", organizationId='" + organizationId + '\'' + + ", organizationName='" + organizationName + '\'' + + ", deviceCallsign='" + deviceCallsign + '\'' + + '}'; + } + + public String getSn() { + return sn; + } + + public BindStatusRequestDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public Boolean getDeviceBindOrganization() { + return deviceBindOrganization; + } + + public BindStatusRequestDevice setDeviceBindOrganization(Boolean deviceBindOrganization) { + this.deviceBindOrganization = deviceBindOrganization; + return this; + } + + public String getOrganizationId() { + return organizationId; + } + + public BindStatusRequestDevice setOrganizationId(String organizationId) { + this.organizationId = organizationId; + return this; + } + + public String getOrganizationName() { + return organizationName; + } + + public BindStatusRequestDevice setOrganizationName(String organizationName) { + this.organizationName = organizationName; + return this; + } + + public String getDeviceCallsign() { + return deviceCallsign; + } + + public BindStatusRequestDevice setDeviceCallsign(String deviceCallsign) { + this.deviceCallsign = deviceCallsign; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/organization/BindStatusResponseDevice.java b/src/main/java/com/dji/sdk/cloudapi/organization/BindStatusResponseDevice.java new file mode 100644 index 0000000..9fb647f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/organization/BindStatusResponseDevice.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.organization; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class BindStatusResponseDevice { + + private String sn; + + public BindStatusResponseDevice() { + } + + @Override + public String toString() { + return "BindStatusResponseDevice{" + + "sn='" + sn + '\'' + + '}'; + } + + public String getSn() { + return sn; + } + + public BindStatusResponseDevice setSn(String sn) { + this.sn = sn; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/organization/OrganizationBindDevice.java b/src/main/java/com/dji/sdk/cloudapi/organization/OrganizationBindDevice.java new file mode 100644 index 0000000..6b896d8 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/organization/OrganizationBindDevice.java @@ -0,0 +1,80 @@ +package com.dji.sdk.cloudapi.organization; + +import com.dji.sdk.cloudapi.device.DeviceEnum; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/13 + */ +public class OrganizationBindDevice { + + private String deviceBindingCode; + + private String organizationId; + + private String deviceCallsign; + + private String sn; + + private DeviceEnum deviceModelKey; + + public OrganizationBindDevice() { + } + + @Override + public String toString() { + return "OrganizationBindDevice{" + + "deviceBindingCode='" + deviceBindingCode + '\'' + + ", organizationId='" + organizationId + '\'' + + ", deviceCallsign='" + deviceCallsign + '\'' + + ", sn='" + sn + '\'' + + ", deviceModelKey=" + deviceModelKey + + '}'; + } + + public String getDeviceBindingCode() { + return deviceBindingCode; + } + + public OrganizationBindDevice setDeviceBindingCode(String deviceBindingCode) { + this.deviceBindingCode = deviceBindingCode; + return this; + } + + public String getOrganizationId() { + return organizationId; + } + + public OrganizationBindDevice setOrganizationId(String organizationId) { + this.organizationId = organizationId; + return this; + } + + public String getDeviceCallsign() { + return deviceCallsign; + } + + public OrganizationBindDevice setDeviceCallsign(String deviceCallsign) { + this.deviceCallsign = deviceCallsign; + return this; + } + + public String getSn() { + return sn; + } + + public OrganizationBindDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public DeviceEnum getDeviceModelKey() { + return deviceModelKey; + } + + public OrganizationBindDevice setDeviceModelKey(DeviceEnum deviceModelKey) { + this.deviceModelKey = deviceModelKey; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/organization/OrganizationBindInfo.java b/src/main/java/com/dji/sdk/cloudapi/organization/OrganizationBindInfo.java new file mode 100644 index 0000000..128c44b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/organization/OrganizationBindInfo.java @@ -0,0 +1,57 @@ +package com.dji.sdk.cloudapi.organization; + +import com.dji.sdk.mqtt.MqttReply; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/14 + */ +public class OrganizationBindInfo { + + @NotNull + private String sn; + + @NotNull + private Integer errCode; + + public OrganizationBindInfo() { + } + + public OrganizationBindInfo(String sn, Integer errCode) { + this.sn = sn; + this.errCode = errCode; + } + + public static OrganizationBindInfo success(String sn) { + return new OrganizationBindInfo(sn, MqttReply.CODE_SUCCESS); + } + + @Override + public String toString() { + return "OrganizationBindInfo{" + + "sn='" + sn + '\'' + + ", errCode=" + errCode + + '}'; + } + + public String getSn() { + return sn; + } + + public OrganizationBindInfo setSn(String sn) { + this.sn = sn; + return this; + } + + public Integer getErrCode() { + return errCode; + } + + public OrganizationBindInfo setErrCode(Integer errCode) { + this.errCode = errCode; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/organization/api/AbstractOrganizationService.java b/src/main/java/com/dji/sdk/cloudapi/organization/api/AbstractOrganizationService.java new file mode 100644 index 0000000..369cc00 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/organization/api/AbstractOrganizationService.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.organization.api; + +import com.dji.sdk.cloudapi.organization.*; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public abstract class AbstractOrganizationService { + + /** + * Obtain organization binding information + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_AIRPORT_BIND_STATUS, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse> airportBindStatus( + TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("airportBindStatus not implemented"); + } + + /** + * Search for the organization information that device bound to + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse> airportOrganizationGet( + TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("airportOrganizationGet not implemented"); + } + + /** + * Device bind to organization + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_BIND, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse> airportOrganizationBind( + TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("airportOrganizationBind not implemented"); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/DistanceLimitStatusData.java b/src/main/java/com/dji/sdk/cloudapi/property/DistanceLimitStatusData.java new file mode 100644 index 0000000..cf03f33 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/DistanceLimitStatusData.java @@ -0,0 +1,52 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.cloudapi.device.SwitchActionEnum; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; + +/** + * The state of the drone's limited distance + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class DistanceLimitStatusData { + + private SwitchActionEnum state; + + @Min(15) + @Max(8000) + @JsonProperty("distance_limit") + private Integer distanceLimit; + + public DistanceLimitStatusData() { + } + + @Override + public String toString() { + return "DistanceLimitStatusData{" + + "state=" + state + + ", distanceLimit=" + distanceLimit + + '}'; + } + + public SwitchActionEnum getState() { + return state; + } + + public DistanceLimitStatusData setState(SwitchActionEnum state) { + this.state = state; + return this; + } + + public Integer getDistanceLimit() { + return distanceLimit; + } + + public DistanceLimitStatusData setDistanceLimit(Integer distanceLimit) { + this.distanceLimit = distanceLimit; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/DistanceLimitStatusSet.java b/src/main/java/com/dji/sdk/cloudapi/property/DistanceLimitStatusSet.java new file mode 100644 index 0000000..ddca848 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/DistanceLimitStatusSet.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * The state of the drone's limited distance + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class DistanceLimitStatusSet extends BaseModel { + + @Valid + @NotNull + private DistanceLimitStatusData distanceLimitStatus; + + public DistanceLimitStatusSet() { + } + + @Override + public String toString() { + return "DistanceLimitStatusSet{" + + "distanceLimitStatus=" + distanceLimitStatus + + '}'; + } + + public DistanceLimitStatusData getDistanceLimitStatus() { + return distanceLimitStatus; + } + + public DistanceLimitStatusSet setDistanceLimitStatus(DistanceLimitStatusData distanceLimitStatus) { + this.distanceLimitStatus = distanceLimitStatus; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/ExitWaylineWhenRcLostSet.java b/src/main/java/com/dji/sdk/cloudapi/property/ExitWaylineWhenRcLostSet.java new file mode 100644 index 0000000..d9053fa --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/ExitWaylineWhenRcLostSet.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum; +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public class ExitWaylineWhenRcLostSet extends BaseModel { + + @NotNull + @JsonProperty("exit_wayline_when_rc_lost") + private ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost; + + public ExitWaylineWhenRcLostSet() { + } + + @Override + public String toString() { + return "ExitWaylineWhenRcLostSet{" + + "exitWaylineWhenRcLost=" + exitWaylineWhenRcLost + + '}'; + } + + public ExitWaylineWhenRcLostEnum getExitWaylineWhenRcLost() { + return exitWaylineWhenRcLost; + } + + public ExitWaylineWhenRcLostSet setExitWaylineWhenRcLost(ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost) { + this.exitWaylineWhenRcLost = exitWaylineWhenRcLost; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/HeightLimitSet.java b/src/main/java/com/dji/sdk/cloudapi/property/HeightLimitSet.java new file mode 100644 index 0000000..0fc3180 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/HeightLimitSet.java @@ -0,0 +1,41 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/28 + */ +public class HeightLimitSet extends BaseModel { + + @NotNull + @Max(1500) + @Min(20) + @JsonProperty("height_limit") + private Integer heightLimit; + + public HeightLimitSet() { + } + + @Override + public String toString() { + return "HeightLimitSet{" + + "heightLimit=" + heightLimit + + '}'; + } + + public Integer getHeightLimit() { + return heightLimit; + } + + public HeightLimitSet setHeightLimit(Integer heightLimit) { + this.heightLimit = heightLimit; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/NightLightsStateSet.java b/src/main/java/com/dji/sdk/cloudapi/property/NightLightsStateSet.java new file mode 100644 index 0000000..feb5fea --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/NightLightsStateSet.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.cloudapi.device.SwitchActionEnum; +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class NightLightsStateSet extends BaseModel { + + @NotNull + @JsonProperty("night_lights_state") + private SwitchActionEnum nightLightsState; + + public NightLightsStateSet() { + } + + @Override + public String toString() { + return "NightLightsStateSet{" + + "nightLightsState=" + nightLightsState + + '}'; + } + + public SwitchActionEnum getNightLightsState() { + return nightLightsState; + } + + public NightLightsStateSet setNightLightsState(SwitchActionEnum nightLightsState) { + this.nightLightsState = nightLightsState; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/ObstacleAvoidanceSet.java b/src/main/java/com/dji/sdk/cloudapi/property/ObstacleAvoidanceSet.java new file mode 100644 index 0000000..f84ec4c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/ObstacleAvoidanceSet.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.cloudapi.device.ObstacleAvoidance; +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class ObstacleAvoidanceSet extends BaseModel { + + @Valid + @NotNull + private ObstacleAvoidance obstacleAvoidance; + + public ObstacleAvoidanceSet() { + } + + @Override + public String toString() { + return "ObstacleAvoidanceSet{" + + "obstacleAvoidance=" + obstacleAvoidance + + '}'; + } + + public ObstacleAvoidance getObstacleAvoidance() { + return obstacleAvoidance; + } + + public ObstacleAvoidanceSet setObstacleAvoidance(ObstacleAvoidance obstacleAvoidance) { + this.obstacleAvoidance = obstacleAvoidance; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/PropertySetEnum.java b/src/main/java/com/dji/sdk/cloudapi/property/PropertySetEnum.java new file mode 100644 index 0000000..549c6fd --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/PropertySetEnum.java @@ -0,0 +1,62 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.common.BaseModel; +import com.dji.sdk.exception.CloudSDKException; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public enum PropertySetEnum { + + NIGHT_LIGHTS_STATE("night_lights_state", NightLightsStateSet.class), + + HEIGHT_LIMIT("height_limit", HeightLimitSet.class), + + DISTANCE_LIMIT_STATUS("distance_limit_status", DistanceLimitStatusSet.class), + + OBSTACLE_AVOIDANCE("obstacle_avoidance", ObstacleAvoidanceSet.class), + + RTH_ALTITUDE("rth_altitude", RthAltitudeSet.class), + + OUT_OF_CONTROL_ACTION("rc_lost_action", RcLostActionSet.class), + + EXIT_WAYLINE_WHEN_RC_LOST("exit_wayline_when_rc_lost", ExitWaylineWhenRcLostSet.class), + + THERMAL_CURRENT_PALETTE_STYLE("thermal_current_palette_style", ThermalCurrentPaletteStyleSet.class), + + THERMAL_GAIN_MODE("thermal_gain_mode", ThermalGainModeSet.class), + + THERMAL_ISOTHERM_STATE("thermal_isotherm_state", ThermalIsothermStateSet.class), + + THERMAL_ISOTHERM_UPPER_LIMIT("thermal_isotherm_upper_limit", ThermalIsothermUpperLimitSet.class), + + THERMAL_ISOTHERM_LOWER_LIMIT("thermal_isotherm_lower_limit", ThermalIsothermLowerLimitSet.class), + + ; + + private final String property; + + private final Class clazz; + + PropertySetEnum(String property, Class clazz) { + this.property = property; + this.clazz = clazz; + } + + public String getProperty() { + return property; + } + + public Class getClazz() { + return clazz; + } + + public static PropertySetEnum find(String property) { + return Arrays.stream(values()).filter(propertyEnum -> propertyEnum.property.equals(property)).findAny() + .orElseThrow(() -> new CloudSDKException(PropertySetEnum.class, property)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/RcLostActionSet.java b/src/main/java/com/dji/sdk/cloudapi/property/RcLostActionSet.java new file mode 100644 index 0000000..6866478 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/RcLostActionSet.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.cloudapi.device.RcLostActionEnum; +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public class RcLostActionSet extends BaseModel { + + @NotNull + @JsonProperty("rc_lost_action") + private RcLostActionEnum rcLostAction; + + public RcLostActionSet() { + } + + @Override + public String toString() { + return "RcLostActionSet{" + + "rcLostAction=" + rcLostAction + + '}'; + } + + public RcLostActionEnum getRcLostAction() { + return rcLostAction; + } + + public RcLostActionSet setRcLostAction(RcLostActionEnum rcLostAction) { + this.rcLostAction = rcLostAction; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/RthAltitudeSet.java b/src/main/java/com/dji/sdk/cloudapi/property/RthAltitudeSet.java new file mode 100644 index 0000000..94e3094 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/RthAltitudeSet.java @@ -0,0 +1,41 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public class RthAltitudeSet extends BaseModel { + + @NotNull + @Min(20) + @Max(50) + @JsonProperty("rth_altitude") + private Integer rthAltitude; + + public RthAltitudeSet() { + } + + @Override + public String toString() { + return "RthAltitudeSet{" + + "rthAltitude=" + rthAltitude + + '}'; + } + + public Integer getRthAltitude() { + return rthAltitude; + } + + public RthAltitudeSet setRthAltitude(Integer rthAltitude) { + this.rthAltitude = rthAltitude; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/ThermalCurrentPaletteStyleSet.java b/src/main/java/com/dji/sdk/cloudapi/property/ThermalCurrentPaletteStyleSet.java new file mode 100644 index 0000000..6b5e847 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/ThermalCurrentPaletteStyleSet.java @@ -0,0 +1,59 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.cloudapi.device.ThermalPaletteStyleEnum; +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonValue; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.Map; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class ThermalCurrentPaletteStyleSet extends BaseModel { + + @NotNull + @Valid + private PayloadIndex payloadIndex; + + @NotNull + private ThermalPaletteStyleEnum thermalCurrentPaletteStyle; + + public ThermalCurrentPaletteStyleSet() { + } + + @Override + public String toString() { + return "ThermalCurrentPaletteStyleSet{" + + "payloadIndex=" + payloadIndex + + ", thermalCurrentPaletteStyle=" + thermalCurrentPaletteStyle + + '}'; + } + + @JsonValue + public Map toMap() { + return Map.of(payloadIndex.toString(), Map.of("thermal_current_palette_style", thermalCurrentPaletteStyle.getStyle())); + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public ThermalCurrentPaletteStyleSet setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ThermalPaletteStyleEnum getThermalCurrentPaletteStyle() { + return thermalCurrentPaletteStyle; + } + + public ThermalCurrentPaletteStyleSet setThermalCurrentPaletteStyle(ThermalPaletteStyleEnum thermalCurrentPaletteStyle) { + this.thermalCurrentPaletteStyle = thermalCurrentPaletteStyle; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/ThermalGainModeSet.java b/src/main/java/com/dji/sdk/cloudapi/property/ThermalGainModeSet.java new file mode 100644 index 0000000..f49bea4 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/ThermalGainModeSet.java @@ -0,0 +1,59 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.cloudapi.device.ThermalGainModeEnum; +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonValue; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.Map; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class ThermalGainModeSet extends BaseModel { + + @NotNull + @Valid + private PayloadIndex payloadIndex; + + @NotNull + private ThermalGainModeEnum thermalGainMode; + + public ThermalGainModeSet() { + } + + @Override + public String toString() { + return "ThermalGainModeSet{" + + "payloadIndex=" + payloadIndex + + ", thermalGainMode=" + thermalGainMode + + '}'; + } + + @JsonValue + public Map toMap() { + return Map.of(payloadIndex.toString(), Map.of("thermal_gain_mode", thermalGainMode.getMode())); + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public ThermalGainModeSet setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ThermalGainModeEnum getThermalGainMode() { + return thermalGainMode; + } + + public ThermalGainModeSet setThermalGainMode(ThermalGainModeEnum thermalGainMode) { + this.thermalGainMode = thermalGainMode; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/ThermalIsothermLowerLimitSet.java b/src/main/java/com/dji/sdk/cloudapi/property/ThermalIsothermLowerLimitSet.java new file mode 100644 index 0000000..66ff5b4 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/ThermalIsothermLowerLimitSet.java @@ -0,0 +1,58 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonValue; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.Map; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class ThermalIsothermLowerLimitSet extends BaseModel { + + @NotNull + @Valid + private PayloadIndex payloadIndex; + + @NotNull + private Integer thermalIsothermLowerLimit; + + public ThermalIsothermLowerLimitSet() { + } + + @Override + public String toString() { + return "ThermalIsothermLowerLimitSet{" + + "payloadIndex=" + payloadIndex + + ", thermalIsothermLowerLimit=" + thermalIsothermLowerLimit + + '}'; + } + + @JsonValue + public Map toMap() { + return Map.of(payloadIndex.toString(), Map.of("thermal_isotherm_upper_limit", thermalIsothermLowerLimit)); + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public ThermalIsothermLowerLimitSet setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public Integer getThermalIsothermLowerLimit() { + return thermalIsothermLowerLimit; + } + + public ThermalIsothermLowerLimitSet setThermalIsothermLowerLimit(Integer thermalIsothermLowerLimit) { + this.thermalIsothermLowerLimit = thermalIsothermLowerLimit; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/ThermalIsothermStateSet.java b/src/main/java/com/dji/sdk/cloudapi/property/ThermalIsothermStateSet.java new file mode 100644 index 0000000..df25b38 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/ThermalIsothermStateSet.java @@ -0,0 +1,59 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.cloudapi.device.SwitchActionEnum; +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonValue; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.Map; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class ThermalIsothermStateSet extends BaseModel { + + @NotNull + @Valid + private PayloadIndex payloadIndex; + + @NotNull + private SwitchActionEnum thermalIsothermState; + + public ThermalIsothermStateSet() { + } + + @Override + public String toString() { + return "ThermalGainModeSet{" + + "payloadIndex=" + payloadIndex + + ", thermalIsothermState=" + thermalIsothermState + + '}'; + } + + @JsonValue + public Map toMap() { + return Map.of(payloadIndex.toString(), Map.of("thermal_isotherm_state", thermalIsothermState.getAction())); + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public ThermalIsothermStateSet setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public SwitchActionEnum getThermalIsothermState() { + return thermalIsothermState; + } + + public ThermalIsothermStateSet setThermalIsothermState(SwitchActionEnum thermalIsothermState) { + this.thermalIsothermState = thermalIsothermState; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/ThermalIsothermUpperLimitSet.java b/src/main/java/com/dji/sdk/cloudapi/property/ThermalIsothermUpperLimitSet.java new file mode 100644 index 0000000..3d5df2b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/ThermalIsothermUpperLimitSet.java @@ -0,0 +1,58 @@ +package com.dji.sdk.cloudapi.property; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonValue; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.Map; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class ThermalIsothermUpperLimitSet extends BaseModel { + + @NotNull + @Valid + private PayloadIndex payloadIndex; + + @NotNull + private Integer thermalIsothermUpperLimit; + + public ThermalIsothermUpperLimitSet() { + } + + @Override + public String toString() { + return "ThermalIsothermUpperLimitSet{" + + "payloadIndex=" + payloadIndex + + ", thermalIsothermUpperLimit=" + thermalIsothermUpperLimit + + '}'; + } + + @JsonValue + public Map toMap() { + return Map.of(payloadIndex.toString(), Map.of("thermal_isotherm_upper_limit", thermalIsothermUpperLimit)); + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public ThermalIsothermUpperLimitSet setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public Integer getThermalIsothermUpperLimit() { + return thermalIsothermUpperLimit; + } + + public ThermalIsothermUpperLimitSet setThermalIsothermUpperLimit(Integer thermalIsothermUpperLimit) { + this.thermalIsothermUpperLimit = thermalIsothermUpperLimit; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/property/api/AbstractPropertyService.java b/src/main/java/com/dji/sdk/cloudapi/property/api/AbstractPropertyService.java new file mode 100644 index 0000000..eec89bc --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/property/api/AbstractPropertyService.java @@ -0,0 +1,78 @@ +package com.dji.sdk.cloudapi.property.api; + +import com.dji.sdk.annotations.CloudSDKVersion; +import com.dji.sdk.cloudapi.property.PropertySetEnum; +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.exception.CloudSDKException; +import com.dji.sdk.mqtt.property.PropertySetPublish; +import com.dji.sdk.mqtt.property.PropertySetReplyResultEnum; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public abstract class AbstractPropertyService { + + @Resource + private PropertySetPublish propertySetPublish; + + /** + * Device property set + * @param gateway + * @param propertyEnum + * @param request + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public PropertySetReplyResultEnum propertySet(GatewayManager gateway, PropertySetEnum propertyEnum, BaseModel request) { + if (Objects.isNull(request) || propertyEnum.getClazz() != request.getClass()) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + Common.validateModel(request); + Field[] fields = request.getClass().getDeclaredFields(); + if (fields.length > 1 || null == fields[0].getDeclaredAnnotation(Valid.class)) { + return propertySetPublish.publish(gateway.getGatewaySn(), request); + } + + try { + Map map = new HashMap<>(); + fields[0].setAccessible(true); + Object child = fields[0].get(request); + for (Field field : ((Class) fields[0].getGenericType()).getDeclaredFields()) { + field.setAccessible(true); + Object value = field.get(child); + if (Objects.isNull(value)) { + continue; + } + map.put(Optional.ofNullable(field.getDeclaredAnnotation(JsonProperty.class)) + .map(JsonProperty::value).orElse(field.getName()), value); + field.setAccessible(false); + PropertySetReplyResultEnum result = propertySetPublish.publish( + gateway.getGatewaySn(), Map.of(propertyEnum.getProperty(), map)); + if (PropertySetReplyResultEnum.SUCCESS != result) { + return result; + } + map.clear(); + } + fields[0].setAccessible(false); + + } catch (IllegalAccessException e) { + throw new CloudSDKException(e); + } + return PropertySetReplyResultEnum.SUCCESS; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/storage/CredentialsToken.java b/src/main/java/com/dji/sdk/cloudapi/storage/CredentialsToken.java new file mode 100644 index 0000000..93317b4 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/storage/CredentialsToken.java @@ -0,0 +1,111 @@ +package com.dji.sdk.cloudapi.storage; + +import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.minio.credentials.Credentials; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "The token data of the temporary credential") +public class CredentialsToken { + + private static final int DELAY = 300; + + @NotNull + @Schema(description = "access key id", example = "3POX6W77L1EF4C86L2RE") + @JsonProperty("access_key_id") + private String accessKeyId; + + @NotNull + @Schema(description = "access key secret", example = "9NG2P2yJaUrck576CkdRoRbchKssJiZygi5D93CBsduY") + @JsonProperty("access_key_secret") + private String accessKeySecret; + + @NotNull + @Min(1) + @Schema(description = "The valid time of the token, in seconds.", example = "3600") + private Long expire; + + @NotNull + @JsonProperty("security_token") + @Schema(description = "security token", example = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiIzUE9YNlc3N0wxRUY0Qzg2TDJSRSIsImV4cCI6MTY4NjgxOTgyOSwicGFyZW50IjoibWluaW8ifQ.cWJXI90UidrBOTD0gWxKt8PT5Qp_6dEK5wNfJuE6lR9dH6Us7jtSB8vcttRDwPhpCNrAGsv91ydw6NLMyjqAOw") + private String securityToken; + + public CredentialsToken(Credentials credentials, long expire) { + this.accessKeyId = credentials.accessKey(); + this.accessKeySecret = credentials.secretKey(); + this.securityToken = credentials.sessionToken(); + this.expire = expire - DELAY; + } + + public CredentialsToken(AssumeRoleResponse.Credentials credentials, long expire) { + this.accessKeyId = credentials.getAccessKeyId(); + this.accessKeySecret = credentials.getAccessKeySecret(); + this.securityToken = credentials.getSecurityToken(); + this.expire = expire - DELAY; + } + + public CredentialsToken(com.amazonaws.services.securitytoken.model.Credentials credentials) { + this.accessKeyId = credentials.getAccessKeyId(); + this.accessKeySecret = credentials.getSecretAccessKey(); + this.securityToken = credentials.getSessionToken(); + this.expire = (credentials.getExpiration().getTime() - System.currentTimeMillis()) / 1000 - DELAY; + } + + public CredentialsToken() { + } + + @Override + public String toString() { + return "CredentialsToken{" + + "accessKeyId='" + accessKeyId + '\'' + + ", accessKeySecret='" + accessKeySecret + '\'' + + ", expire=" + expire + + ", securityToken='" + securityToken + '\'' + + '}'; + } + + public String getAccessKeyId() { + return accessKeyId; + } + + public CredentialsToken setAccessKeyId(String accessKeyId) { + this.accessKeyId = accessKeyId; + return this; + } + + public String getAccessKeySecret() { + return accessKeySecret; + } + + public CredentialsToken setAccessKeySecret(String accessKeySecret) { + this.accessKeySecret = accessKeySecret; + return this; + } + + public Long getExpire() { + return expire; + } + + public CredentialsToken setExpire(Long expire) { + this.expire = expire; + return this; + } + + public String getSecurityToken() { + return securityToken; + } + + public CredentialsToken setSecurityToken(String securityToken) { + this.securityToken = securityToken; + return this; + } +} diff --git a/src/main/java/com/dji/sample/component/oss/model/enums/OssTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/storage/OssTypeEnum.java similarity index 56% rename from src/main/java/com/dji/sample/component/oss/model/enums/OssTypeEnum.java rename to src/main/java/com/dji/sdk/cloudapi/storage/OssTypeEnum.java index a5dafe0..16401af 100644 --- a/src/main/java/com/dji/sample/component/oss/model/enums/OssTypeEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/storage/OssTypeEnum.java @@ -1,10 +1,14 @@ -package com.dji.sample.component.oss.model.enums; +package com.dji.sdk.cloudapi.storage; + +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; /** * @author sean * @version 1.0 * @date 2022/5/30 */ +@Schema(description = "oss type", example = "minio", enumAsRef = true) public enum OssTypeEnum { ALIYUN("ali"), @@ -19,6 +23,7 @@ public enum OssTypeEnum { this.type = type; } + @JsonValue public String getType() { return type; } diff --git a/src/main/java/com/dji/sdk/cloudapi/storage/StsCredentialsResponse.java b/src/main/java/com/dji/sdk/cloudapi/storage/StsCredentialsResponse.java new file mode 100644 index 0000000..0821274 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/storage/StsCredentialsResponse.java @@ -0,0 +1,113 @@ +package com.dji.sdk.cloudapi.storage; + +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "Temporary credential data") +public class StsCredentialsResponse extends BaseModel { + + @Schema(description = "bucket name", example = "bucket-api") + @NotNull + private String bucket; + + @NotNull + @Valid + @Schema(description = "The token data of the temporary credential") + private CredentialsToken credentials; + + @NotNull + @Schema(description = "access domain name for external services", example = "https://oss-cn-hangzhou.aliyuncs.com") + @Pattern(regexp = "^http[s]?://.*$") + private String endpoint; + + @NotNull + @JsonProperty("object_key_prefix") + @Schema(description = "The folder path where the object needs to be stored.", example = "files/wayline") + private String objectKeyPrefix; + + @NotNull + private OssTypeEnum provider; + + @NotNull + @Schema(description = "The region where the bucket is located.", example = "us-east-1") + private String region; + + public StsCredentialsResponse() { + } + + @Override + public String toString() { + return "StsCredentialsResponse{" + + "bucket='" + bucket + '\'' + + ", credentials=" + credentials + + ", endpoint='" + endpoint + '\'' + + ", objectKeyPrefix='" + objectKeyPrefix + '\'' + + ", provider='" + provider + '\'' + + ", region='" + region + '\'' + + '}'; + } + + public String getBucket() { + return bucket; + } + + public StsCredentialsResponse setBucket(String bucket) { + this.bucket = bucket; + return this; + } + + public CredentialsToken getCredentials() { + return credentials; + } + + public StsCredentialsResponse setCredentials(CredentialsToken credentials) { + this.credentials = credentials; + return this; + } + + public String getEndpoint() { + return endpoint; + } + + public StsCredentialsResponse setEndpoint(String endpoint) { + this.endpoint = endpoint; + return this; + } + + public String getObjectKeyPrefix() { + return objectKeyPrefix; + } + + public StsCredentialsResponse setObjectKeyPrefix(String objectKeyPrefix) { + this.objectKeyPrefix = objectKeyPrefix; + return this; + } + + public OssTypeEnum getProvider() { + return provider; + } + + public StsCredentialsResponse setProvider(OssTypeEnum provider) { + this.provider = provider; + return this; + } + + public String getRegion() { + return region; + } + + public StsCredentialsResponse setRegion(String region) { + this.region = region; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/storage/api/IHttpStorageService.java b/src/main/java/com/dji/sdk/cloudapi/storage/api/IHttpStorageService.java new file mode 100644 index 0000000..602a8d2 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/storage/api/IHttpStorageService.java @@ -0,0 +1,39 @@ +package com.dji.sdk.cloudapi.storage.api; + +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; +import com.dji.sdk.common.HttpResultResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/29 + */ +public interface IHttpStorageService { + + String PREFIX = "storage/api/v1"; + + /** + * Get temporary credentials for uploading the media and wayline in DJI Pilot. + * @param workspaceId workspace id + * @param req + * @param rsp + * @return + */ + @Operation(summary = "Get STS Token", description = "Get temporary credentials for uploading the media and wayline in DJI Pilot.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/sts") + HttpResultResponse getTemporaryCredential( + @PathVariable(name = "workspace_id") String workspaceId, + HttpServletRequest req, HttpServletResponse rsp); + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/tsa/DeviceIconUrl.java b/src/main/java/com/dji/sdk/cloudapi/tsa/DeviceIconUrl.java new file mode 100644 index 0000000..937cb4a --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/tsa/DeviceIconUrl.java @@ -0,0 +1,56 @@ +package com.dji.sdk.cloudapi.tsa; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.3 + * @date 2022/1/5 + */ +@Schema(description = "device icon url.
You can use icons from the web, and the App internally downloads and caches these icons and" + + " loads them at a fixed size (28dp) to display on the map. Example: http://r56978dr7.hn-bkt.clouddn.com/tsa_equipment_normal.png", + anyOf = IconUrlEnum.class) +public class DeviceIconUrl { + + @JsonProperty("normal_icon_url") + @NotNull + @Schema(description = "icon displayed in normal state", example = "resource://pilot/drawable/tsa_car_normal") + private String normalIconUrl; + + @JsonProperty("selected_icon_url") + @NotNull + @Schema(description = "icon displayed in selected state", example = "resource://pilot/drawable/tsa_car_select") + private String selectIconUrl; + + public DeviceIconUrl() { + } + + @Override + public String toString() { + return "DeviceIconUrl{" + + "normalIconUrl='" + normalIconUrl + '\'' + + ", selectIconUrl='" + selectIconUrl + '\'' + + '}'; + } + + public String getNormalIconUrl() { + return normalIconUrl; + } + + public DeviceIconUrl setNormalIconUrl(String normalIconUrl) { + this.normalIconUrl = normalIconUrl; + return this; + } + + public String getSelectIconUrl() { + return selectIconUrl; + } + + public DeviceIconUrl setSelectIconUrl(String selectIconUrl) { + this.selectIconUrl = selectIconUrl; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/tsa/DeviceTopology.java b/src/main/java/com/dji/sdk/cloudapi/tsa/DeviceTopology.java new file mode 100644 index 0000000..437783d --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/tsa/DeviceTopology.java @@ -0,0 +1,128 @@ +package com.dji.sdk.cloudapi.tsa; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Schema(description = "device topology data") +public class DeviceTopology { + + @NotNull + @Schema(description = "device sn", example = "1AEC32CK4AD23R") + private String sn; + + @NotNull + @JsonProperty("device_callsign") + @Schema(description = "device nickname", example = "my M350") + private String deviceCallsign; + + @NotNull + @JsonProperty("device_model") + @Valid + private TopologyDeviceModel deviceModel; + + @NotNull + @Schema(description = "online status") + @JsonProperty("online_status") + private Boolean onlineStatus; + + @Schema(description = "the id of the person using the device", format = "uuid") + @JsonProperty("user_id") + private String userId; + + @NotNull + @Schema(description = "the nickname of the person using the device", example = "admin") + @JsonProperty("user_callsign") + private String userCallsign; + + @NotNull + @JsonProperty("icon_urls") + @Valid + private DeviceIconUrl iconUrls; + + public DeviceTopology() { + } + + @Override + public String toString() { + return "DeviceTopology{" + + "sn='" + sn + '\'' + + ", deviceCallsign='" + deviceCallsign + '\'' + + ", deviceModel=" + deviceModel + + ", onlineStatus=" + onlineStatus + + ", userId='" + userId + '\'' + + ", userCallsign='" + userCallsign + '\'' + + ", iconUrls=" + iconUrls + + '}'; + } + + public String getSn() { + return sn; + } + + public DeviceTopology setSn(String sn) { + this.sn = sn; + return this; + } + + public String getDeviceCallsign() { + return deviceCallsign; + } + + public DeviceTopology setDeviceCallsign(String deviceCallsign) { + this.deviceCallsign = deviceCallsign; + return this; + } + + public TopologyDeviceModel getDeviceModel() { + return deviceModel; + } + + public DeviceTopology setDeviceModel(TopologyDeviceModel deviceModel) { + this.deviceModel = deviceModel; + return this; + } + + public Boolean getOnlineStatus() { + return onlineStatus; + } + + public DeviceTopology setOnlineStatus(Boolean onlineStatus) { + this.onlineStatus = onlineStatus; + return this; + } + + public String getUserId() { + return userId; + } + + public DeviceTopology setUserId(String userId) { + this.userId = userId; + return this; + } + + public String getUserCallsign() { + return userCallsign; + } + + public DeviceTopology setUserCallsign(String userCallsign) { + this.userCallsign = userCallsign; + return this; + } + + public DeviceIconUrl getIconUrls() { + return iconUrls; + } + + public DeviceTopology setIconUrls(DeviceIconUrl iconUrls) { + this.iconUrls = iconUrls; + return this; + } +} diff --git a/src/main/java/com/dji/sample/manage/model/enums/IconUrlEnum.java b/src/main/java/com/dji/sdk/cloudapi/tsa/IconUrlEnum.java similarity index 66% rename from src/main/java/com/dji/sample/manage/model/enums/IconUrlEnum.java rename to src/main/java/com/dji/sdk/cloudapi/tsa/IconUrlEnum.java index 3803d2f..8c91ea2 100644 --- a/src/main/java/com/dji/sample/manage/model/enums/IconUrlEnum.java +++ b/src/main/java/com/dji/sdk/cloudapi/tsa/IconUrlEnum.java @@ -1,4 +1,7 @@ -package com.dji.sample.manage.model.enums; +package com.dji.sdk.cloudapi.tsa; + +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; /** * The system icon that comes with the pilot. @@ -6,6 +9,7 @@ package com.dji.sample.manage.model.enums; * @version 0.3 * @date 2022/1/5 */ +@Schema(enumAsRef = true) public enum IconUrlEnum { SELECT_CAR("resource://pilot/drawable/tsa_car_select"), @@ -20,17 +24,13 @@ public enum IconUrlEnum { NORMAL_EQUIPMENT("resource://pilot/drawable/tsa_equipment_normal"); - /** - * You can use icons from the web, and the App internally downloads and caches these icons and - * loads them at a fixed size (28dp) to display on the map. - * Example: http://r56978dr7.hn-bkt.clouddn.com/tsa_equipment_normal.png - */ - private String url; + private final String url; IconUrlEnum(String url) { this.url = url; } + @JsonValue public String getUrl() { return url; } diff --git a/src/main/java/com/dji/sdk/cloudapi/tsa/TopologyDeviceModel.java b/src/main/java/com/dji/sdk/cloudapi/tsa/TopologyDeviceModel.java new file mode 100644 index 0000000..770c28b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/tsa/TopologyDeviceModel.java @@ -0,0 +1,82 @@ +package com.dji.sdk.cloudapi.tsa; + +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.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Schema(description = "topology device model") +public class TopologyDeviceModel { + + @NotNull + @JsonProperty("device_model_key") + private DeviceEnum deviceModelKey; + + @NotNull + private DeviceDomainEnum domain; + + @NotNull + private DeviceTypeEnum type; + + @NotNull + @JsonProperty("sub_type") + private DeviceSubTypeEnum subType; + + public TopologyDeviceModel() { + } + + @Override + public String toString() { + return "TopologyDeviceModel{" + + "deviceModelKey=" + deviceModelKey + + ", domain=" + domain + + ", type=" + type + + ", subType=" + subType + + '}'; + } + + public DeviceEnum getDeviceModelKey() { + return deviceModelKey; + } + + public TopologyDeviceModel setDeviceModelKey(DeviceEnum deviceModelKey) { + this.deviceModelKey = deviceModelKey; + return this; + } + + public DeviceDomainEnum getDomain() { + return domain; + } + + public TopologyDeviceModel setDomain(DeviceDomainEnum domain) { + this.domain = domain; + return this; + } + + public DeviceTypeEnum getType() { + return type; + } + + public TopologyDeviceModel setType(DeviceTypeEnum type) { + this.type = type; + return this; + } + + public DeviceSubTypeEnum getSubType() { + return subType; + } + + public TopologyDeviceModel setSubType(DeviceSubTypeEnum subType) { + this.subType = subType; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/tsa/TopologyList.java b/src/main/java/com/dji/sdk/cloudapi/tsa/TopologyList.java new file mode 100644 index 0000000..4f41c57 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/tsa/TopologyList.java @@ -0,0 +1,55 @@ +package com.dji.sdk.cloudapi.tsa; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Schema(description = "device topology list") +public class TopologyList { + + @Valid + @Schema(description = "drone device topology collection") + @NotNull + private List hosts; + + @Valid + @Schema(description = "gateway device topology collection") + @NotNull + private List parents; + + public TopologyList() { + } + + @Override + public String toString() { + return "TopologyList{" + + "hosts=" + hosts + + ", parents=" + parents + + '}'; + } + + public List getHosts() { + return hosts; + } + + public TopologyList setHosts(List hosts) { + this.hosts = hosts; + return this; + } + + public List getParents() { + return parents; + } + + public TopologyList setParents(List parents) { + this.parents = parents; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/tsa/TopologyResponse.java b/src/main/java/com/dji/sdk/cloudapi/tsa/TopologyResponse.java new file mode 100644 index 0000000..b3a2216 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/tsa/TopologyResponse.java @@ -0,0 +1,40 @@ +package com.dji.sdk.cloudapi.tsa; + +import com.dji.sdk.common.BaseModel; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/16 + */ +@Schema(description = "topology response data") +public class TopologyResponse extends BaseModel { + + @Valid + @NotNull + private List list; + + public TopologyResponse() { + } + + @Override + public String toString() { + return "TopologyResponse{" + + "list=" + list + + '}'; + } + + public List getList() { + return list; + } + + public TopologyResponse setList(List list) { + this.list = list; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/tsa/api/IHttpTsaService.java b/src/main/java/com/dji/sdk/cloudapi/tsa/api/IHttpTsaService.java new file mode 100644 index 0000000..6e9a2d8 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/tsa/api/IHttpTsaService.java @@ -0,0 +1,44 @@ +package com.dji.sdk.cloudapi.tsa.api; + +import com.dji.sdk.cloudapi.tsa.TopologyResponse; +import com.dji.sdk.common.HttpResultResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Tag(name = "tsa interface") +public interface IHttpTsaService { + + String PREFIX = "manage/api/v1"; + + /** + * Get the topology list of all devices in the current user workspace for pilot display. + * @param workspaceId + * @param req + * @param rsp + * @return + */ + @Operation(summary = "obtain device topology list", description = "Get the topology list of all devices in the current user workspace for pilot display." + + "In the first connection, DJI Pilot 2 will call this interface to obtain the list topology of all devices." + + "Also, when Pilot receives a websocket command to notify the device of online, offline, and update, " + + "it will also call this interface to request the device topology list to be updated.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + }) + @GetMapping(PREFIX + "/workspaces/{workspace_id}/devices/topologies") + HttpResultResponse obtainDeviceTopologyList( + @PathVariable(name = "workspace_id") String workspaceId, + HttpServletRequest req, HttpServletResponse rsp); + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/BreakpointStateEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/BreakpointStateEnum.java new file mode 100644 index 0000000..ec958ee --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/BreakpointStateEnum.java @@ -0,0 +1,43 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum BreakpointStateEnum { + + WAYLINE_SEGMENT(0, "On the wayline segment"), + + WAYPOINT(1, "On the waypoint"); + + private final int state; + + private final String msg; + + BreakpointStateEnum(int state, String msg) { + this.state = state; + this.msg = msg; + } + + public int getState() { + return state; + } + + @JsonValue + public String getMsg() { + return msg; + } + + @JsonCreator + public static BreakpointStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(BreakpointStateEnum.class, state)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/DeviceExitHomingNotify.java b/src/main/java/com/dji/sdk/cloudapi/wayline/DeviceExitHomingNotify.java new file mode 100644 index 0000000..0225663 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/DeviceExitHomingNotify.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.wayline; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class DeviceExitHomingNotify { + + private ExitingRTHActionEnum action; + + private String sn; + + private ExitingRTHReasonEnum reason; + + public DeviceExitHomingNotify() { + } + + @Override + public String toString() { + return "DeviceExitHomingNotify{" + + "action=" + action + + ", sn='" + sn + '\'' + + ", reason=" + reason + + '}'; + } + + public ExitingRTHActionEnum getAction() { + return action; + } + + public DeviceExitHomingNotify setAction(ExitingRTHActionEnum action) { + this.action = action; + return this; + } + + public String getSn() { + return sn; + } + + public DeviceExitHomingNotify setSn(String sn) { + this.sn = sn; + return this; + } + + public ExitingRTHReasonEnum getReason() { + return reason; + } + + public DeviceExitHomingNotify setReason(ExitingRTHReasonEnum reason) { + this.reason = reason; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/ExecutableConditions.java b/src/main/java/com/dji/sdk/cloudapi/wayline/ExecutableConditions.java new file mode 100755 index 0000000..768b301 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/ExecutableConditions.java @@ -0,0 +1,39 @@ +package com.dji.sdk.cloudapi.wayline; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class ExecutableConditions { + + /** + * Storage capacity + * The minimum storage capacity of DJI dock or aircraft that can execute a task. Unit: MB. + * If the storage capacity doesn't satisfy the `storage_capacity`, task execution will fail. + */ + @NotNull + @Min(0) + private Integer storageCapacity; + + public ExecutableConditions() {} + + @Override + public String toString() { + return "ExecutableConditions{" + + "storageCapacity=" + storageCapacity + + '}'; + } + + public Integer getStorageCapacity() { + return storageCapacity; + } + + public ExecutableConditions setStorageCapacity(Integer storageCapacity) { + this.storageCapacity = storageCapacity; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/ExecutionStepEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/ExecutionStepEnum.java new file mode 100644 index 0000000..f142ce6 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/ExecutionStepEnum.java @@ -0,0 +1,66 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum ExecutionStepEnum { + + STARTING(0, 4, "MissionCenter starting, checking and resuming"), + + WAITING_STATE(5, 18, "Waiting state"), + + EXECUTING(19, 20, "Task executing"), + + RTH(21, 29, "Returning to home"), + + PULLING_LOGS(30, 39, "Pulling logs"), + + COMPLETE(40, 65534, "Interaction completed"), + + UNKNOWN(65535, 65535, "Unknown"); + + private final int min; + + private final int max; + + private final String msg; + + ExecutionStepEnum(int min, int max, String msg) { + this.min = min; + this.max = max; + this.msg = msg; + } + + @JsonValue + public int getMin() { + return min; + } + + public int getMax() { + return max; + } + + public String getMsg() { + return msg; + } + + @JsonCreator + public static ExecutionStepEnum find(int step) { + return Arrays.stream(values()).filter(stepEnum -> stepEnum.min <= step && stepEnum.max >= step).findAny() + .orElseThrow(() -> new CloudSDKException(ExecutionStepEnum.class, step)); + } + + @JsonCreator + public static ExecutionStepEnum find(String msg) { + return Arrays.stream(values()).filter(stepEnum -> stepEnum.msg.equals(msg)).findAny() + .orElseThrow(() -> new CloudSDKException(ExecutionStepEnum.class, msg)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/ExitingRTHActionEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/ExitingRTHActionEnum.java new file mode 100644 index 0000000..402cfa1 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/ExitingRTHActionEnum.java @@ -0,0 +1,44 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum; +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum ExitingRTHActionEnum { + + EXIT(0, "Exit exiting RTH state"), + + Enter(1, "Enter exiting RTH state"); + + private final int action; + + private final String msg; + + ExitingRTHActionEnum(int action, String msg) { + this.action = action; + this.msg = msg; + } + + public int getAction() { + return action; + } + + @JsonValue + public String getMsg() { + return msg; + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static ExitingRTHActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(ExitWaylineWhenRcLostEnum.class, action)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/ExitingRTHReasonEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/ExitingRTHReasonEnum.java new file mode 100644 index 0000000..63b407d --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/ExitingRTHReasonEnum.java @@ -0,0 +1,61 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum ExitingRTHReasonEnum { + + ADD_JOYSTICK_THROTTLE(0, "Add joystick throttle"), + + ADD_JOYSTICK_PITCH(1, "Add joystick pitch"), + + INITIALIZATION_FAILED(2, "The initialization of behavior tree is failed"), + + SURROUNDED_BY_OBSTACLES(3, "Surrounded by obstacles"), + + FLIGHT_RESTRICTION(4, "Flight restriction is triggered"), + + OBSTACLE_IS_TOO_CLOSED(5, "Obstacle is too closed"), + + NO_GPS(6, "No GPS signal"), + + GPS_AND_VIO_ARE_FALSE(7, "The output flag of GPS and VIO location is false"), + + ERROR_OF_GPS_AND_VIO(8, "The error of GPS and VIO fusion position is too large"), + + SHORT_DISTANCE_BACKTRACKING(9, "Backtrack in a short distance"), + + TRIGGER_RTH(10, "Trigger the RTH in a short distanc"); + + private final int reason; + + private final String msg; + + ExitingRTHReasonEnum(int reason, String msg) { + this.reason = reason; + this.msg = msg; + } + + public int getReason() { + return reason; + } + + @JsonValue + public String getMsg() { + return msg; + } + + @JsonCreator + public static ExitingRTHReasonEnum find(int reason) { + return Arrays.stream(values()).filter(reasonEnum -> reasonEnum.reason == reason).findAny() + .orElseThrow(() -> new CloudSDKException(ExitingRTHReasonEnum.class, reason)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java new file mode 100755 index 0000000..6d0c232 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakPoint.java @@ -0,0 +1,163 @@ +package com.dji.sdk.cloudapi.wayline; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskBreakPoint { + + /** + * Breakpoint index + */ + @NotNull + @Min(0) + private Integer index; + + /** + * Breakpoint state + */ + @NotNull + private BreakpointStateEnum state; + + /** + * Current wayline segment process + */ + @NotNull + @Min(0) + @Max(1) + private Float progress; + + /** + * Wayline ID + */ + private Integer waylineID; + + /** + * Break reason + */ + private FlighttaskBreakReasonEnum breakReason; + + /** + * Breakpoint latitude + */ + private Float latitude; + + /** + * Breakpoint longitude + */ + private Float longitude; + + /** + * Breakpoint altitude relative to the Earth's ellipsoid surface + * + */ + private Float height; + + /** + * Yaw angle relative to true north (meridian), with positive values from 0 to 6 o'clock direction and negative values from 6 to 12 o'clock direction + */ + private Integer attitudeHead; + + public FlighttaskBreakPoint() {} + + @Override + public String toString() { + return "FlighttaskBreakPoint{" + + "index=" + index + + ", state=" + state + + ", progress=" + progress + + ", waylineID=" + waylineID + + ", breakReason=" + breakReason + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + ", attitudeHead=" + attitudeHead + + '}'; + } + + public Integer getIndex() { + return index; + } + + public FlighttaskBreakPoint setIndex(Integer index) { + this.index = index; + return this; + } + + public BreakpointStateEnum getState() { + return state; + } + + public FlighttaskBreakPoint setState(BreakpointStateEnum state) { + this.state = state; + return this; + } + + public Float getProgress() { + return progress; + } + + public FlighttaskBreakPoint setProgress(Float progress) { + this.progress = progress; + return this; + } + + public Integer getWaylineID() { + return waylineID; + } + + public FlighttaskBreakPoint setWaylineID(Integer waylineID) { + this.waylineID = waylineID; + return this; + } + + public FlighttaskBreakReasonEnum getBreakReason() { + return breakReason; + } + + public FlighttaskBreakPoint setBreakReason(FlighttaskBreakReasonEnum breakReason) { + this.breakReason = breakReason; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public FlighttaskBreakPoint setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public FlighttaskBreakPoint setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public FlighttaskBreakPoint setHeight(Float height) { + this.height = height; + return this; + } + + public Integer getAttitudeHead() { + return attitudeHead; + } + + public FlighttaskBreakPoint setAttitudeHead(Integer attitudeHead) { + this.attitudeHead = attitudeHead; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakReasonEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakReasonEnum.java new file mode 100644 index 0000000..8926a49 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskBreakReasonEnum.java @@ -0,0 +1,11 @@ +package com.dji.sdk.cloudapi.wayline; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum FlighttaskBreakReasonEnum { + + // TODO 增加枚举值 +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskCreateFile.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskCreateFile.java new file mode 100755 index 0000000..271d2d4 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskCreateFile.java @@ -0,0 +1,51 @@ +package com.dji.sdk.cloudapi.wayline; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskCreateFile { + + /** + * File URL + */ + @NotNull + private String url; + + /** + * MD5 signature + */ + @NotNull + private String sign; + + public FlighttaskCreateFile() {} + + @Override + public String toString() { + return "FlighttaskCreateFile{" + + "url='" + url + '\'' + + ", sign='" + sign + '\'' + + '}'; + } + + public String getUrl() { + return url; + } + + public FlighttaskCreateFile setUrl(String url) { + this.url = url; + return this; + } + + public String getSign() { + return sign; + } + + public FlighttaskCreateFile setSign(String sign) { + this.sign = sign; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskCreateRequest.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskCreateRequest.java new file mode 100755 index 0000000..c614c96 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskCreateRequest.java @@ -0,0 +1,73 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class FlighttaskCreateRequest extends BaseModel { + + /** + * Task ID + */ + @NotNull + private String flightId; + + /** + * Task type + */ + @NotNull + @Pattern(regexp = "^wayline$") + private String type = "wayline"; + + /** + * Wayline flighttaskFile object + */ + @NotNull + @Valid + private FlighttaskCreateFile file; + + public FlighttaskCreateRequest() {} + + @Override + public String toString() { + return "FlighttaskCreateRequest{" + + "flightId='" + flightId + '\'' + + ", type='" + type + '\'' + + ", file=" + file + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public FlighttaskCreateRequest setFlightId(String flightId) { + this.flightId = flightId; + return this; + } + + public String getType() { + return type; + } + + public FlighttaskCreateRequest setType(String type) { + this.type = type; + return this; + } + + public FlighttaskCreateFile getFile() { + return file; + } + + public FlighttaskCreateRequest setFile(FlighttaskCreateFile file) { + this.file = file; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskExecuteRequest.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskExecuteRequest.java new file mode 100644 index 0000000..451b784 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskExecuteRequest.java @@ -0,0 +1,37 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +public class FlighttaskExecuteRequest extends BaseModel { + + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + private String flightId; + + public FlighttaskExecuteRequest() { + } + + @Override + public String toString() { + return "FlighttaskExecuteRequest{" + + "flightId='" + flightId + '\'' + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public FlighttaskExecuteRequest setFlightId(String flightId) { + this.flightId = flightId; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskFile.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskFile.java new file mode 100644 index 0000000..70837fc --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskFile.java @@ -0,0 +1,52 @@ +package com.dji.sdk.cloudapi.wayline; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskFile { + + /** + * File URL + */ + @NotNull + private String url; + + /** + * File signature + */ + @NotNull + private String fingerprint; + + public FlighttaskFile() { + } + + @Override + public String toString() { + return "FlighttaskFile{" + + "url='" + url + '\'' + + ", fingerprint='" + fingerprint + '\'' + + '}'; + } + + public String getUrl() { + return url; + } + + public FlighttaskFile setUrl(String url) { + this.url = url; + return this; + } + + public String getFingerprint() { + return fingerprint; + } + + public FlighttaskFile setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskPrepareRequest.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskPrepareRequest.java new file mode 100755 index 0000000..41a7934 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskPrepareRequest.java @@ -0,0 +1,242 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.annotations.CloudSDKVersion; +import com.dji.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum; +import com.dji.sdk.common.BaseModel; +import com.dji.sdk.common.CloudSDKVersionEnum; + +import javax.validation.Valid; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskPrepareRequest extends BaseModel { + + /** + * Task ID + */ + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + private String flightId; + + /** + * Time to execute + * Millisecond timestamp of task execution time. Optional field. + * When the `task_type` is 0 or 1, it is required. When the `task_type` is 2, it is not required. + */ + @Min(123456789012L) + private Long executeTime; + + /** + * Task type + * The execution time of immediate task and timed task are defined by `execute_time`. + * The conditional task supports the task readiness condition defined by `ready_conditions`. + * The task can be executed if conditions are satisfied within a specified period. + * Immediate task has the highest priority. Timed task and conditional task have the same priority. + */ + @NotNull + private TaskTypeEnum taskType; + + /** + * Wayline type + */ + @NotNull + private WaylineTypeEnum waylineType; + + /** + * Wayline file object + */ + @NotNull + @Valid + private FlighttaskFile file; + + /** + * Task readiness condition + */ + private ReadyConditions readyConditions; + + /** + * Task executable condition + */ + private ExecutableConditions executableConditions; + + /** + * Wayline breakpoint information + */ + private FlighttaskBreakPoint breakPoint; + + /** + * Height for RTH + */ + @NotNull + @Min(20) + @Max(1500) + private Integer rthAltitude; + + /** + * Remote controller out of control action + * Out of control action: the current fixed transmitted value is 0, meaning Return-to-Home (RTH). + * Note that this enumeration value definition is inconsistent with the flight control and dock definitions, + * and a conversion exists at the dock end. + */ + @NotNull + private OutOfControlActionEnum outOfControlAction; + + /** + * wayline out of control action + * consistent with the KMZ file + */ + @NotNull + private ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private RthModeEnum rthMode = RthModeEnum.SETTING_HEIGHT; + + @Valid + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private SimulateMission simulateMission; + + public FlighttaskPrepareRequest() {} + + @Override + public String toString() { + return "FlighttaskPrepareRequest{" + + "flightId='" + flightId + '\'' + + ", executeTime=" + executeTime + + ", taskType=" + taskType + + ", waylineType=" + waylineType + + ", file=" + file + + ", readyConditions=" + readyConditions + + ", executableConditions=" + executableConditions + + ", breakPoint=" + breakPoint + + ", rthAltitude=" + rthAltitude + + ", outOfControlAction=" + outOfControlAction + + ", exitWaylineWhenRcLost=" + exitWaylineWhenRcLost + + ", rthMode=" + rthMode + + ", simulateMission=" + simulateMission + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public FlighttaskPrepareRequest setFlightId(String flightId) { + this.flightId = flightId; + return this; + } + + public Long getExecuteTime() { + return executeTime; + } + + public FlighttaskPrepareRequest setExecuteTime(Long executeTime) { + this.executeTime = executeTime; + return this; + } + + public TaskTypeEnum getTaskType() { + return taskType; + } + + public FlighttaskPrepareRequest setTaskType(TaskTypeEnum taskType) { + this.taskType = taskType; + return this; + } + + public WaylineTypeEnum getWaylineType() { + return waylineType; + } + + public FlighttaskPrepareRequest setWaylineType(WaylineTypeEnum waylineType) { + this.waylineType = waylineType; + return this; + } + + public FlighttaskFile getFile() { + return file; + } + + public FlighttaskPrepareRequest setFile(FlighttaskFile file) { + this.file = file; + return this; + } + + public ReadyConditions getReadyConditions() { + return readyConditions; + } + + public FlighttaskPrepareRequest setReadyConditions(ReadyConditions readyConditions) { + this.readyConditions = readyConditions; + return this; + } + + public ExecutableConditions getExecutableConditions() { + return executableConditions; + } + + public FlighttaskPrepareRequest setExecutableConditions(ExecutableConditions executableConditions) { + this.executableConditions = executableConditions; + return this; + } + + public FlighttaskBreakPoint getBreakPoint() { + return breakPoint; + } + + public FlighttaskPrepareRequest setBreakPoint(FlighttaskBreakPoint breakPoint) { + this.breakPoint = breakPoint; + return this; + } + + public Integer getRthAltitude() { + return rthAltitude; + } + + public FlighttaskPrepareRequest setRthAltitude(Integer rthAltitude) { + this.rthAltitude = rthAltitude; + return this; + } + + public OutOfControlActionEnum getOutOfControlAction() { + return outOfControlAction; + } + + public FlighttaskPrepareRequest setOutOfControlAction(OutOfControlActionEnum outOfControlAction) { + this.outOfControlAction = outOfControlAction; + return this; + } + + public ExitWaylineWhenRcLostEnum getExitWaylineWhenRcLost() { + return exitWaylineWhenRcLost; + } + + public FlighttaskPrepareRequest setExitWaylineWhenRcLost(ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost) { + this.exitWaylineWhenRcLost = exitWaylineWhenRcLost; + return this; + } + + public RthModeEnum getRthMode() { + return rthMode; + } + + public FlighttaskPrepareRequest setRthMode(RthModeEnum rthMode) { + this.rthMode = rthMode; + return this; + } + + public SimulateMission getSimulateMission() { + return simulateMission; + } + + public FlighttaskPrepareRequest setSimulateMission(SimulateMission simulateMission) { + this.simulateMission = simulateMission; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskProgress.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskProgress.java new file mode 100644 index 0000000..d71bcca --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskProgress.java @@ -0,0 +1,54 @@ +package com.dji.sdk.cloudapi.wayline; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +public class FlighttaskProgress { + + private FlighttaskProgressExt ext; + + private FlighttaskProgressData progress; + + private FlighttaskStatusEnum status; + + public FlighttaskProgress() { + } + + @Override + public String toString() { + return "FlighttaskProgress{" + + "ext=" + ext + + ", progress=" + progress + + ", status=" + status + + '}'; + } + + public FlighttaskProgressExt getExt() { + return ext; + } + + public FlighttaskProgress setExt(FlighttaskProgressExt ext) { + this.ext = ext; + return this; + } + + public FlighttaskProgressData getProgress() { + return progress; + } + + public FlighttaskProgress setProgress(FlighttaskProgressData progress) { + this.progress = progress; + return this; + } + + public FlighttaskStatusEnum getStatus() { + return status; + } + + public FlighttaskProgress setStatus(FlighttaskStatusEnum status) { + this.status = status; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskProgressData.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskProgressData.java new file mode 100644 index 0000000..25693e2 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskProgressData.java @@ -0,0 +1,48 @@ +package com.dji.sdk.cloudapi.wayline; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +public class FlighttaskProgressData { + + /** + * Execution step + */ + private ExecutionStepEnum currentStep; + + /** + * Progress value + */ + private Integer percent; + + public FlighttaskProgressData() { + } + + @Override + public String toString() { + return "FlighttaskProgressData{" + + "currentStep=" + currentStep + + ", percent=" + percent + + '}'; + } + + public ExecutionStepEnum getCurrentStep() { + return currentStep; + } + + public FlighttaskProgressData setCurrentStep(ExecutionStepEnum currentStep) { + this.currentStep = currentStep; + return this; + } + + public Integer getPercent() { + return percent; + } + + public FlighttaskProgressData setPercent(Integer percent) { + this.percent = percent; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskProgressExt.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskProgressExt.java new file mode 100644 index 0000000..a924773 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskProgressExt.java @@ -0,0 +1,80 @@ +package com.dji.sdk.cloudapi.wayline; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +public class FlighttaskProgressExt { + + private Integer currentWaypointIndex; + + private Integer mediaCount; + + private String flightId; + + private String trackId; + + private FlighttaskBreakPoint breakPoint; + + public FlighttaskProgressExt() { + } + + @Override + public String toString() { + return "FlighttaskProgressExt{" + + "currentWaypointIndex=" + currentWaypointIndex + + ", mediaCount=" + mediaCount + + ", flightId='" + flightId + '\'' + + ", trackId='" + trackId + '\'' + + ", breakPoint=" + breakPoint + + '}'; + } + + public Integer getCurrentWaypointIndex() { + return currentWaypointIndex; + } + + public FlighttaskProgressExt setCurrentWaypointIndex(Integer currentWaypointIndex) { + this.currentWaypointIndex = currentWaypointIndex; + return this; + } + + public Integer getMediaCount() { + return mediaCount; + } + + public FlighttaskProgressExt setMediaCount(Integer mediaCount) { + this.mediaCount = mediaCount; + return this; + } + + public String getFlightId() { + return flightId; + } + + public FlighttaskProgressExt setFlightId(String flightId) { + this.flightId = flightId; + return this; + } + + public String getTrackId() { + return trackId; + } + + public FlighttaskProgressExt setTrackId(String trackId) { + this.trackId = trackId; + return this; + } + + public FlighttaskBreakPoint getBreakPoint() { + return breakPoint; + } + + public FlighttaskProgressExt setBreakPoint(FlighttaskBreakPoint breakPoint) { + this.breakPoint = breakPoint; + return this; + } +} + + diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskReady.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskReady.java new file mode 100644 index 0000000..471321f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskReady.java @@ -0,0 +1,35 @@ +package com.dji.sdk.cloudapi.wayline; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskReady { + + /** + * The task ID set that currently satisfies the task readiness conditions + */ + private List flightIds; + + public FlighttaskReady() { + } + + @Override + public String toString() { + return "FlighttaskReady{" + + "flightIds=" + flightIds + + '}'; + } + + public List getFlightIds() { + return flightIds; + } + + public FlighttaskReady setFlightIds(List flightIds) { + this.flightIds = flightIds; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskResourceGetRequest.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskResourceGetRequest.java new file mode 100644 index 0000000..5da16d6 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskResourceGetRequest.java @@ -0,0 +1,30 @@ +package com.dji.sdk.cloudapi.wayline; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/25 + */ +public class FlighttaskResourceGetRequest { + + private String flightId; + + public FlighttaskResourceGetRequest() { + } + + @Override + public String toString() { + return "FlighttaskResourceGetRequest{" + + "flightId='" + flightId + '\'' + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public FlighttaskResourceGetRequest setFlightId(String flightId) { + this.flightId = flightId; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskResourceGetResponse.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskResourceGetResponse.java new file mode 100755 index 0000000..1a1f275 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskResourceGetResponse.java @@ -0,0 +1,39 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskResourceGetResponse extends BaseModel { + + /** + * Wayline file object + */ + @NotNull + @Valid + private FlighttaskFile file; + + public FlighttaskResourceGetResponse() {} + + @Override + public String toString() { + return "FlighttaskResourceGetResponse{" + + "file=" + file + + '}'; + } + + public FlighttaskFile getFile() { + return file; + } + + public FlighttaskResourceGetResponse setFile(FlighttaskFile file) { + this.file = file; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskStatusEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskStatusEnum.java new file mode 100644 index 0000000..d75d991 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskStatusEnum.java @@ -0,0 +1,59 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/17 + */ +public enum FlighttaskStatusEnum { + + SENT("sent", false), + + IN_PROGRESS("in_progress", false), + + OK("ok", true), + + PAUSED("paused", false), + + REJECTED("rejected", true), + + FAILED("failed", true), + + CANCELED("canceled", true), + + TIMEOUT("timeout", true), + + PARTIALLY_DONE("partially_done", true); + + private final String status; + + private final boolean end; + + FlighttaskStatusEnum(String status, boolean end) { + this.status = status; + this.end = end; + } + + @JsonValue + public String getStatus() { + return status; + } + + public boolean isEnd() { + return end; + } + + @JsonCreator + public static FlighttaskStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(FlighttaskStatusEnum.class, status)); + } +} + + diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskUndoRequest.java b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskUndoRequest.java new file mode 100644 index 0000000..a38af28 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/FlighttaskUndoRequest.java @@ -0,0 +1,39 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/7 + */ +public class FlighttaskUndoRequest extends BaseModel { + + @NotNull + @Size(min = 1) + private List<@Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") String> flightIds; + + public FlighttaskUndoRequest() { + } + + @Override + public String toString() { + return "FlighttaskUndoRequest{" + + "flightIds=" + flightIds + + '}'; + } + + public List getFlightIds() { + return flightIds; + } + + public FlighttaskUndoRequest setFlightIds(List flightIds) { + this.flightIds = flightIds; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/GetWaylineListRequest.java b/src/main/java/com/dji/sdk/cloudapi/wayline/GetWaylineListRequest.java new file mode 100644 index 0000000..8ea9c41 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/GetWaylineListRequest.java @@ -0,0 +1,116 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/8 + */ +@Schema(description = "Query parameter to get list of wayline files") +public class GetWaylineListRequest { + + /** + * Is the wayline file favorited? + */ + @Parameter(name = "favorited", description = "Is the wayline file favorited?") + private Boolean favorited; + + /** + * order(xxx_column desc or xxx_column asc) + * Pilot2 optional value: nameupdate_time desc + */ + @NotNull + @JsonProperty("order_by") + @Parameter(name = "order_by", description = "sort field name", example = "update_time desc", schema = @Schema(allowableValues = {"name", "update_time desc"})) + private String orderBy; + + /** + * current page + */ + @Min(1) + @Parameter(name = "page", description = "current page", schema = @Schema(defaultValue = "1", type = "int")) + private int page = 1; + + /** + * page size + */ + @Min(1) + @JsonProperty("page_size") + @Parameter(name = "page_size", description = "page size", schema = @Schema(defaultValue = "10", type = "int")) + private int pageSize = 10; + + /** + * wayline template type collection + */ + @Size(min = 1) + @JsonProperty("template_type") + @Parameter(name = "template_type", description = "wayline template type collection", example = "[0]") + private List templateType; + + public GetWaylineListRequest() { + } + + @Override + public String toString() { + return "GetWaylineListRequest{" + + "favorited=" + favorited + + ", orderBy='" + orderBy + '\'' + + ", page=" + page + + ", pageSize=" + pageSize + + ", templateType=" + templateType + + '}'; + } + + public Boolean getFavorited() { + return favorited; + } + + public GetWaylineListRequest setFavorited(Boolean favorited) { + this.favorited = favorited; + return this; + } + + public String getOrderBy() { + return orderBy; + } + + public GetWaylineListRequest setOrderBy(String orderBy) { + this.orderBy = orderBy; + return this; + } + + public int getPage() { + return page; + } + + public GetWaylineListRequest setPage(int page) { + this.page = page; + return this; + } + + public int getPageSize() { + return pageSize; + } + + public GetWaylineListRequest setPageSize(int pageSize) { + this.pageSize = pageSize; + return this; + } + + public List getTemplateType() { + return templateType; + } + + public GetWaylineListRequest setTemplateType(List templateType) { + this.templateType = templateType; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/GetWaylineListResponse.java b/src/main/java/com/dji/sdk/cloudapi/wayline/GetWaylineListResponse.java new file mode 100644 index 0000000..8e856da --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/GetWaylineListResponse.java @@ -0,0 +1,203 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.dji.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Schema(description = "The data of the wayline file.") +public class GetWaylineListResponse extends BaseModel { + + /** + * wayline file name + */ + @NotNull + @Schema(description = "wayline file name", example = "waylineFile") + // TODO 排除特殊字符 + private String name; + + /** + * wayline file id + */ + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "wayline file id", format = "uuid") + private String id; + + /** + * drone device product enum + */ + @NotNull + @JsonProperty("drone_model_key") + @Schema(description = "drone device product enum", example = "0-67-0") + private DeviceEnum droneModelKey; + + private String sign; + + /** + * payload device product enum + */ + @NotNull + @Size(min = 1) + @JsonProperty("payload_model_keys") + @Schema(description = "payload device product enum", example = "[\"1-53-0\"]") + private List payloadModelKeys; + + /** + * Is the wayline file favorited? + */ + @NotNull + @Schema(description = "Is the wayline file favorited?") + private Boolean favorited; + + /** + * wayline template collection + */ + @NotNull + @Size(min = 1) + @Schema(description = "wayline template collection", example = "[0]") + @JsonProperty("template_types") + private List templateTypes; + + @NotNull + @Schema(description = "The key of the object in the bucket", example = "wayline/waylineFile.kmz") + @JsonProperty("object_key") + private String objectKey; + + /** + * uploader + */ + @NotNull + @JsonProperty("user_name") + @Schema(description = "uploader's username", example = "admin") + private String username; + + /** + * update time (millisecond) + */ + @NotNull + @Min(123456789012L) + @Schema(description = "update time (millisecond). The field named `update time` must exist in the table.", example = "123456789012") + @JsonProperty("update_time") + private Long updateTime; + + public GetWaylineListResponse() { + } + + @Override + public String toString() { + return "GetWaylineListResponse{" + + "name='" + name + '\'' + + ", id='" + id + '\'' + + ", droneModelKey=" + droneModelKey + + ", sign='" + sign + '\'' + + ", payloadModelKeys=" + payloadModelKeys + + ", favorited=" + favorited + + ", templateTypes=" + templateTypes + + ", objectKey='" + objectKey + '\'' + + ", username='" + username + '\'' + + ", updateTime=" + updateTime + + '}'; + } + + public String getName() { + return name; + } + + public GetWaylineListResponse setName(String name) { + this.name = name; + return this; + } + + public String getId() { + return id; + } + + public GetWaylineListResponse setId(String id) { + this.id = id; + return this; + } + + public DeviceEnum getDroneModelKey() { + return droneModelKey; + } + + public GetWaylineListResponse setDroneModelKey(DeviceEnum droneModelKey) { + this.droneModelKey = droneModelKey; + return this; + } + + public String getSign() { + return sign; + } + + public GetWaylineListResponse setSign(String sign) { + this.sign = sign; + return this; + } + + public List getPayloadModelKeys() { + return payloadModelKeys; + } + + public GetWaylineListResponse setPayloadModelKeys(List payloadModelKeys) { + this.payloadModelKeys = payloadModelKeys; + return this; + } + + public Boolean getFavorited() { + return favorited; + } + + public GetWaylineListResponse setFavorited(Boolean favorited) { + this.favorited = favorited; + return this; + } + + public List getTemplateTypes() { + return templateTypes; + } + + public GetWaylineListResponse setTemplateTypes(List templateTypes) { + this.templateTypes = templateTypes; + return this; + } + + public String getObjectKey() { + return objectKey; + } + + public GetWaylineListResponse setObjectKey(String objectKey) { + this.objectKey = objectKey; + return this; + } + + public String getUsername() { + return username; + } + + public GetWaylineListResponse setUsername(String username) { + this.username = username; + return this; + } + + public Long getUpdateTime() { + return updateTime; + } + + public GetWaylineListResponse setUpdateTime(Long updateTime) { + this.updateTime = updateTime; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/OutOfControlActionEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/OutOfControlActionEnum.java new file mode 100755 index 0000000..4a7cc17 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/OutOfControlActionEnum.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum OutOfControlActionEnum { + + RETURN_TO_HOME(0), + + HOVERING(1), + + LANDING(2); + + private final int action; + + OutOfControlActionEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static OutOfControlActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(OutOfControlActionEnum.class, action)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/ReadyConditions.java b/src/main/java/com/dji/sdk/cloudapi/wayline/ReadyConditions.java new file mode 100755 index 0000000..6194e8d --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/ReadyConditions.java @@ -0,0 +1,77 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.common.BaseModel; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class ReadyConditions extends BaseModel { + + /** + * Battery capacity + * The aircraft battery percentage threshold of the executable task. + * The aircraft battery must be greater than the `battery_capacity` when the task starts. + */ + @NotNull + @Min(0) + @Max(1) + private Integer batteryCapacity; + + /** + * Start time of the task executable period + * Start millisecond timestamp of the task executable period. The task execution time should be later than the `begin_time`. + */ + @NotNull + private Long beginTime; + + /** + * End time of the task executable period + * End millisecond timestamp of the task executable period. The task execution time should be earlier than the `end_time`. + */ + @NotNull + private Long endTime; + + public ReadyConditions() {} + + @Override + public String toString() { + return "ReadyConditions{" + + "batteryCapacity=" + batteryCapacity + + ", beginTime=" + beginTime + + ", endTime=" + endTime + + '}'; + } + + public Integer getBatteryCapacity() { + return batteryCapacity; + } + + public ReadyConditions setBatteryCapacity(Integer batteryCapacity) { + this.batteryCapacity = batteryCapacity; + return this; + } + + public Long getBeginTime() { + return beginTime; + } + + public ReadyConditions setBeginTime(Long beginTime) { + this.beginTime = beginTime; + return this; + } + + public Long getEndTime() { + return endTime; + } + + public ReadyConditions setEndTime(Long endTime) { + this.endTime = endTime; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/RthModeEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/RthModeEnum.java new file mode 100644 index 0000000..2d4713d --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/RthModeEnum.java @@ -0,0 +1,37 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/8/4 + */ +public enum RthModeEnum { + + SMART_HEIGHT(0), + + SETTING_HEIGHT(1); + + private final int rthMode; + + RthModeEnum(int rthMode) { + this.rthMode = rthMode; + } + + @JsonValue + public int getRthMode() { + return rthMode; + } + + @JsonCreator + public static RthModeEnum find(int rthMode) { + return Arrays.stream(values()).filter(rthModeEnum -> rthModeEnum.rthMode == rthMode).findAny() + .orElseThrow(() -> new CloudSDKException(RthModeEnum.class, rthMode)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/SimulateMission.java b/src/main/java/com/dji/sdk/cloudapi/wayline/SimulateMission.java new file mode 100644 index 0000000..bf3c4bc --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/SimulateMission.java @@ -0,0 +1,65 @@ +package com.dji.sdk.cloudapi.wayline; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/8/4 + */ +public class SimulateMission { + + @NotNull + private SimulateSwitchEnum isEnable; + + @NotNull + @Min(-90) + @Max(90) + private Float latitude; + + @NotNull + @Min(-180) + @Max(180) + private Float longitude; + + public SimulateMission() { + } + + @Override + public String toString() { + return "SimulateMission{" + + "isEnable=" + isEnable + + ", latitude=" + latitude + + ", longitude=" + longitude + + '}'; + } + + public SimulateSwitchEnum getIsEnable() { + return isEnable; + } + + public SimulateMission setIsEnable(SimulateSwitchEnum isEnable) { + this.isEnable = isEnable; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public SimulateMission setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public SimulateMission setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/SimulateSwitchEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/SimulateSwitchEnum.java new file mode 100644 index 0000000..3036a4b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/SimulateSwitchEnum.java @@ -0,0 +1,37 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/8/4 + */ +public enum SimulateSwitchEnum { + + DISABLE(0), + + ENABLE(1); + + private final int state; + + SimulateSwitchEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static SimulateSwitchEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(SimulateSwitchEnum.class, state)); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/TaskTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/TaskTypeEnum.java new file mode 100755 index 0000000..b1179fb --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/TaskTypeEnum.java @@ -0,0 +1,38 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum TaskTypeEnum { + + IMMEDIATE(0), + + TIMED(1), + + CONDITIONAL(2); + + private final int type; + + TaskTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return this.type; + } + + @JsonCreator + public static TaskTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(TaskTypeEnum.class, type)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineErrorCodeEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineErrorCodeEnum.java new file mode 100644 index 0000000..0c1275c --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineErrorCodeEnum.java @@ -0,0 +1,322 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.common.IErrorInfo; +import com.dji.sdk.mqtt.events.IEventsErrorCode; +import com.dji.sdk.mqtt.services.IServicesErrorCode; +import com.fasterxml.jackson.annotation.JsonCreator; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum WaylineErrorCodeEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + SUCCESS(0, "success"), + + WRONG_PARAM(314001, "Failed to distribute task. Try again later"), + + MD5_EMPTY(314002, "The issued wayline task md5 is empty."), + + WRONG_WAYLINE_FILE(314003, "Wayline file format not supported. Check file."), + + DISTRIBUTE_TASK_FAILED_1(314004, "Failed to distribute task."), + + MD5_CHECK_FAILED(314005, "Wayline MD5 check failed."), + + INITIATE_AIRCRAFT_FAILED_1(314006, "Failed to initiate aircraft. Restart dock and try again."), + + TRANSFER_KMZ_FILE_FAILED(314007, "Failed to distribute wayline file from dock to aircraft."), + + PREPARATION_TIMED_OUT(314008, "Aircraft task preparation timed out. Restart dock and try again."), + + INITIATE_AIRCRAFT_FAILED_2(314009, "Failed to initiate aircraft. Restart dock and try again."), + + PERFORM_TASK_FAILED(314010, "Unable to perform task."), + + QUERY_TIMEOUT(314011, "Wayline execution result query timed out."), + + PREPARATION_FAILED_1(314012, "Aircraft task preparation failed. Unable to perform task. Restart dock and try again."), + + WRONG_KMZ_URL(314013, "Get KMZ download address failed."), + + DOCK_SYSTEM_ERROR_1(314014, "Dock system error. Failed to perform task. Try again later."), + + CLOSE_FOURTH_GENERATION_FAILED(314015, "Failed to distribute AI-Spot Check wayline from dock to aircraft. Unable to perform task. Try again later or restart dock and try again."), + + PROCESS_KMZ_FILE_FAILED_1(314016, "Failed to process flight route file. Unable to perform task. Check file."), + + MODIFY_KMZ_FILE_FAILED(314017, "Failed to modify the KMZ file of AI Spot-Check."), + + AIRCRAFT_RTK_ERROR(314018, "Aircraft RTK positioning error. Unable to perform task. Try again later or restart dock and try again."), + + CONVERGE_RTK_FAILED_1(314019, "Failed to converge aircraft RTK data. Unable to perform task. Try again later or restart dock and try again."), + + AIRCRAFT_POSITION_ERROR(314020, "Aircraft not in the middle of landing pad or aircraft heading incorrect. Unable to perform task. Check aircraft position and heading."), + + AIRCRAFT_RTK_POSITIONING_ERROR(314021, "Aircraft RTK positioning error. Unable to perform task. Try again later or restart dock and try again."), + + MODIFY_KMZ_BREAKPOINT_FILE_FAILED(314022, "Failed to modify KMZ file of resuming flight from breakpoint"), + + SETTING_BACKUP_LANDING_POINT_FAILED(316001, "Backup landing point setting failed"), + + SETTING_BACKUP_SAFE_HEIGHT_FAILED(316002, "Backup safe height for transfer setting failed"), + + SETTING_TAKEOFF_HEIGHT_FAILED(316003, "Take-off height setting failed. Note: The default safe take-off height of the aircraft is set to 1.8 meters by dock. The aircraft will fly to 1.8 meters after take-off, and cannot be interrupted during the 0-1.8 meters take-off process, and other actions can only be performed after take-off. This altitude is used by the dock by default and does not support modification. The purpose is to prevent personal injury."), + + SETTING_OUT_OF_CONTROL_ACTION_FAILED(316004, "Out of control action setting failed."), + + CONVERGE_RTK_FAILED_2(316005, "Failed to converge aircraft RTK data. Unable to perform task. Restart dock and try again."), + + DOCK_PREPARATION_FAILED(316006, "Aircraft unable to land on dock. Dock cover closed or driving rods pushed into place. Check aircraft status on dock deployment site."), + + INITIATE_AIRCRAFT_FAILED(316007, "Failed to initiate aircraft. Restart dock and try again."), + + OBTAIN_FLIGHT_CONTROL_FAILED(316008, "Dock failed to obtain aircraft flight control. Unable to perform task. Make sure flight control not locked by remote controller."), + + LOW_POWER(316009, "Aircraft battery level low. Unable to perform task. Wait until aircraft is charged up to 50% and try again"), + + AIRCRAFT_NOT_DETECTED(316010, "Aircraft not detected. Unable to perform task. Check if aircraft is inside dock and linked to dock, or restart dock and try again."), + + LANDED_ON_INCORRECT_LOCATION(316011, "Aircraft landed on incorrect location. Check if aircraft should be manually placed on dock deployment site."), + + FOLDER_COLORING_FAILED(316012, "Aircraft task preparation failed. Folder coloring failed."), + + OBTAIN_BATTERY_POWER_FAILED(316013, "Query of battery power failed."), + + FLIGHT_CONTROL_PUSHING_TIMED_OUT(316014, "The receive of flight control pushing timed out."), + + AIRCRAFT_LOCATION_TOO_FAR(316015, "Aircraft location calibrated by RTK device is far from dock. Unable to perform task. Restart dock and try again."), + + LANDING_TIMEOUT(316016, "Aircraft landing on dock timed out. Aircraft and dock may be disconnected. Check livestream view to see if aircraft landed on dock"), + + OBTAIN_MEDIA_TIMEOUT(316017, "Obtaining number of aircraft media files timed out. Aircraft and dock may be disconnected. Check livestream view to see if aircraft landed on dock"), + + TASK_PERFORMANCE_TIMED_OUT(316018, "Task performance timed out. Aircraft and dock may be disconnected. Check livestream view to see if aircraft landed on dock"), + + CAMERA_COLORING_TIMED_OUT(316019, "Camera coloring timed out"), + + RTK_SOURCE_ERROR(316020, "Aircraft RTK signal source error."), + + RTK_SOURCE_TIMEOUT(316021, "Checking aircraft RTK signal source timed out."), + + AIRCRAFT_NOT_CONNECTED(316022, "Aircraft unable to return to home. Check if aircraft is powered on, aircraft and dock are connected, and try again"), + + NO_FLIGHT_CONTROL_1(316023, "Aircraft controlled by Controller B and unable to return to home. Control aircraft from Controller B or power off remote controller and try again."), + + WRONG_COMMAND(316024, "Aircraft failed to return to home. Check if aircraft has taken off and try again."), + + SETTING_AIRCRAFT_PARAMETERS_FAILED(316025, "Failed to configure aircraft parameters. Try again later or restart dock and try again."), + + EMERGENCY_BUTTON_PRESSED_DOWN(316026, "Dock emergency stop button pressed down. Unable to perform task. Release button and try again."), + + SETTING_AIRCRAFT_PARAMETERS_TIMEOUT(316027, "Setting aircraft parameters timed out. Try again later or restart dock and try again."), + + FLYING_TO_BACKUP_POINT_1(316029, "Dock emergency stop button pressed down. Aircraft flying to alternate landing site. Make sure aircraft has safely landed and place aircraft inside dock"), + + REFRESH_HOME_POINT_FAILED(316030, "Refresh of home point failed. Please try again."), + + SETTING_RTH_MODE_FAILED(316031, "Failed to set return home mode. Please try again."), + + LOW_POWER_LANDING_OUTSIDE(316050, "The aircraft has landed outside the dock due to low battery. Please check immediately whether the aircraft has landed safely and return the aircraft to the dock."), + + TASK_ABNORMAL_LANDING_OUTSIDE(316051, "The wayline task is abnormal, the aircraft landed outside the dock, please check immediately whether the aircraft has landed safely and return the aircraft to the dock."), + + FLYING_TO_BACKUP_POINT_2(316052, "The wayline task is abnormal, the aircraft will fly to the backup landing point, please check immediately whether the aircraft has landed safely and return the aircraft to the dock."), + + USER_CONTROL_LANDING(316053, "The user controls the aircraft to land."), + + OBTAIN_MEDIA_FAILED(317001, "Failed to obtain number of aircraft media files."), + + CAMERA_NOT_CONNECTED(317002, "Failed to format aircraft storage. Make sure aircraft is powered on and connected to dock and camera can be detected. Or restart aircraft and try again."), + + FORMAT_AIRCRAFT_STORAGE_FAILED(317003, "Failed to format aircraft storage."), + + FORMAT_MEDIA_FILES_FAILED(317004, "Failed to format media files."), + + STOP_RECORDING_FAILED(317005, "Aircraft video recording terminated unsuccessfully, media files for this flight mission may not be able to be uploaded."), + + NOT_IDLE(319001, "Unable to perform task. Dock is performing task or uploading issue logs. Wait until task is complete or logs uploaded and try again."), + + DOCK_SYSTEM_ERROR_2(319002, "Dock system error. Restart dock and try again."), + + TASK_ID_NOT_EXIST(319003, "Task ID doesn't exist in dock"), + + TASK_EXPIRE(319004, "The task has expired."), + + FLIGHTTASK_EXECUTE_COMMAND_TIMEOUT(319005, "Execution command delivery timed out. Unable to perform task."), + + CANCEL_TASK_FAILED_1(319006, "Failed to cancel task. Task in progress."), + + EDIT_TASK_FAILED(319007, "Failed to edit task. Task in progress."), + + TIME_NOT_SYNCED(319008, "Dock and cloud time not synced. Dock unable to perform task."), + + DISTRIBUTE_TASK_FAILED_2(319009, "Failed to distribute task. Try again later or restart dock and try again."), + + VERSION_TOO_EARLY(319010, "Dock firmware version too early. Unable to perform task. Update dock to latest version and try again."), + + INITIALIZING_DOCK(319015, "Initializing dock. Unable to perform task. Wait until initialization is complete."), + + PERFORMING_OTHER_TASK(319016, "Dock performing other task. Unable to perform current task."), + + PROCESSING_MEDIA_FILE(319017, "Dock processing media files captured in last task. Unable to perform current task. Try again later."), + + EXPORTING_LOGS(319018, "Unable to perform task. Dock uploading issue logs. Try again later."), + + PULLING_LOGS(319019, "Unable to perform task. Dock obtaining issue logs. Try again later."), + + PAUSE_TASK_FAILED(319020, "Failed to pause flight task."), + + DISABLE_FLIGHT_CONTROL_FAILED(319021, "Failed to disable Live Flight Controls."), + + FLYTO_TASK_FAILED(319022, "FlyTo task failed."), + + STOP_FLYTO_TASK_FAILED(319023, "Failed to stop FlyTo task."), + + TAKING_OFF_TASK_FAILED(319024, "One-key taking off failed."), + + TASK_IN_PREPARATION(319025, "Task in preparation. Dock unable to perform task distributed from cloud. Try again later"), + + LOW_POWER_THAN_SET_VALUE(319026, "Aircraft battery level lower than set value. Unable to perform task. Wait until charging completes and try again."), + + INSUFFICIENT_STORAGE(319027, "Insufficient storage on dock or aircraft. Unable to perform task. Wait until media files are uploaded to cloud and try again."), + + NO_FLIGHT_CONTROL_2(319030, "Dock has no flight control authority."), + + NO_PAYLOAD_CONTROL(319031, "Dock has no payload control authority"), + + WRONG_POINT_NUMBER(319032, "Flyto target point, the point number is wrong."), + + SEQ_NUMBER_SMALLER_THAN_LAST(319033, "DRC - flight control failed. Package sequence number is smaller than last one."), + + DELAY_TIME_SMALLER_THAN_SET(319034, "DRC - flight control failed. Package received time out."), + + EMERGENCY_STOP_FAILED(319035, "Emergency stop failed, please try again."), + + REMOTE_DEBUGGING_MODE(319036, "Device in remote debugging mode. "), + + ONSITE_DEBUGGING_MODE(319037, "Device in onsite debugging mode."), + + UPDATING(319038, "Updating device. Try again later."), + + RESUME_TASK_FAILED(319042, "Failed to resume flight."), + + CANCEL_TASK_FAILED_2(319043, "Failed to cancel RTH."), + + NO_BREAKPOINT(319044, "Task completed. Unable to resume."), + + EMERGENCY_STOP_STATUS(319045, "DRC - flight control failed. Aircraft paused."), + + NOT_IN_WAYLINE(319046, "Task completed or paused. Unable to pause."), + + DOCK_SYSTEM_ERROR_3(319999, "Dock system error. Restart dock and try again."), + + TASK_ERROR(321000, "Task error. Try again later or restart dock and try again."), + + PROCESS_KMZ_FILE_FAILED_2(321004, "Failed to process flight route file. Unable to perform task. Check file."), + + MISSING_BREAKPOINT(321005, "Missing breakpoint info in wayline."), + + TASK_IN_PROGRESS(321257, "Task in progress. Failed to start task again."), + + STATUS_NOT_SUPPORTED(321258, "Unable to stop task. Check aircraft status."), + + NOT_STARTED_CANNOT_STOP(321259, "Task not started. Unable to stop task."), + + NOT_STARTED_CANNOT_INTERRUPT(321260, "Task not started. Unable to pause task."), + + HEIGHT_LIMIT(321513, "Unable to perform task. Flight route altitude greater than aircraft max flight altitude."), + + DISTANCE_LIMIT(321514, "Failed to perform task. Flight route start or end point in buffer zone or exceeds distance limit."), + + GEO_ZONE(321515, "Unable to perform task. Aircraft will fly across GEO Zone."), + + HEIGHT_TOO_LOW(321516, "Flight altitude too low. Task stopped."), + + OBSTACLE_SENSED(321517, "Obstacle sensed. Task stopped."), + + APPROACHED_GEO_ZONE(321519, "Aircraft approached GEO Zone or reached max distance and automatically returned to home. Unable to complete task."), + + PROPELLER_CHECK_FAILED(321523, "Aircraft propeller check failed. Propeller may be damaged. Try again later. Contact DJI Support to replace propeller if issue persists."), + + PREPARATION_FAILED_2(321524, "The preparation before takeoff of the aircraft has failed, possibly due to the aircraft's inability to locate or gear error. Please check the status of the aircraft."), + + WEAK_GPS(321769, "Aircraft satellite positioning signal weak. Unable to perform task. Restart dock and try again."), + + WRONG_GEAR_MODE(321770, "Aircraft flight mode error. Unable to perform task. Restart dock and try again."), + + HOME_POINT_NOT_SET(321771, "Aircraft Home Point not set. Unable to perform task. Restart dock and try again."), + + LOW_POWER_PERFORM_TASK(321772, "Aircraft battery level low. Unable to perform task. Wait until aircraft is charged up to 50% and try again."), + + LOW_POWER_RTH(321773, "Aircraft battery level low and returned to home. Unable to complete task."), + + AIRCRAFT_SIGNAL_LOST(321775, "Aircraft signal lost when performing task."), + + RTK_NOT_READY(321776, "Failed to converge aircraft RTK data. Unable to perform task. Restart dock and try again."), + + NOT_HOVERING(321777, "Aircraft not hovering. Unable to start task."), + + B_CONTROL_PROPELLERS(321778, "Unable to perform task. Aircraft controlled by Controller B, and propellers started."), + + USER_CONTROL(322282, "Task stopped. Aircraft control obtained by cloud user or Controller B."), + + USER_SEND_RTH(322283, "RTH command sent by user. Aircraft unable to complete task."), + + WRONG_BREAKPOINT(322539, "Breakpoint info error. Dock unable to perform task"), + + EMPTY_ACTION_LAYER(322594, "The layer of action tree can not be empty."), + + WRONG_TASK(386535, "Task error. Try again later or restart dock and try again."), + + SET_MEDIA_PRIORITY_FAILED(324030, "Setting priority of media upload failed, the task does not exist in the upload queue."), + + MEDIA_PRIORITY_COMMAND_TOO_FAST(324031, "Setting priority of media upload failed, the action of issuing commands is too fast, and the response to the last command has not yet ended."), + + MEDIA_PRIORITY_WRONG_PARAMETER(324032, "Setting priority of media upload failed, incorrect parameter."), + + UNKNOWN(-1, "UNKNOWN"), + + ; + + + private final String msg; + + private final int code; + + WaylineErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + @Override + public String toString() { + return "{" + + "code='" + code + '\'' + + ", message=" + msg + + '}'; + } + + /** + * @param code error code + * @return enumeration object + */ + @JsonCreator + public static WaylineErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineMethodEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineMethodEnum.java new file mode 100755 index 0000000..019be1e --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineMethodEnum.java @@ -0,0 +1,39 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum WaylineMethodEnum { + + FLIGHTTASK_CREATE("flighttask_create"), + + FLIGHTTASK_PREPARE("flighttask_prepare"), + + FLIGHTTASK_EXECUTE("flighttask_execute"), + + FLIGHTTASK_UNDO("flighttask_undo"), + + FLIGHTTASK_PAUSE("flighttask_pause"), + + FLIGHTTASK_RECOVERY("flighttask_recovery"), + + RETURN_HOME("return_home"), + + RETURN_HOME_CANCEL("return_home_cancel"); + + private final String method; + + WaylineMethodEnum(String method) { + this.method = method; + } + + @JsonValue + public String getMethod() { + return this.method; + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineTypeEnum.java b/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineTypeEnum.java new file mode 100644 index 0000000..874963b --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineTypeEnum.java @@ -0,0 +1,51 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/9/26 + */ +@Schema(enumAsRef = true, type = "int", allowableValues = {"0", "1", "2", "3"}, + description = "

0: waypoint

1: mapping2d

2: mapping3d

3: mappingStrip

") +public enum WaylineTypeEnum { + + WAYPOINT(0, "waypoint"), + + MAPPING_2D(1, "mapping2d"), + + MAPPING_3D(2, "mapping3d"), + + MAPPING_STRIP(3, "mappingStrip"); + + private final int value; + + private final String type; + + WaylineTypeEnum(int value, String type) { + this.value = value; + this.type = type; + } + + @JsonValue + public int getValue() { + return value; + } + + @JsonCreator + public static WaylineTypeEnum find(int value) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.value == value).findAny() + .orElseThrow(() -> new CloudSDKException(WaylineTypeEnum.class, value)); + } + + public static WaylineTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(WaylineTypeEnum.class, type)); + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineUploadCallbackMetadata.java b/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineUploadCallbackMetadata.java new file mode 100644 index 0000000..aa97993 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineUploadCallbackMetadata.java @@ -0,0 +1,83 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/12 + */ +@Schema(description = "Wayline file metadata") +public class WaylineUploadCallbackMetadata { + + /** + * drone device product enum + */ + @NotNull + @Schema(description = "drone device product enum", example = "0-67-0") + @JsonProperty("drone_model_key") + private DeviceEnum droneModelKey; + + /** + * payload device product enum + */ + @NotNull + @Size(min = 1) + @JsonProperty("payload_model_keys") + @Schema(description = "payload device product enum", example = "[\"1-53-0\"]") + private List payloadModelKeys; + + /** + * wayline template collection + */ + @NotNull + @Size(min = 1) + @Schema(description = "wayline template collection", example = "[0]") + @JsonProperty("template_types") + private List templateTypes; + + public WaylineUploadCallbackMetadata() { + } + + @Override + public String toString() { + return "WaylineUploadCallbackMetadata{" + + "droneModelKey='" + droneModelKey + '\'' + + ", payloadModelKeys=" + payloadModelKeys + + ", templateTypes=" + templateTypes + + '}'; + } + + public DeviceEnum getDroneModelKey() { + return droneModelKey; + } + + public WaylineUploadCallbackMetadata setDroneModelKey(DeviceEnum droneModelKey) { + this.droneModelKey = droneModelKey; + return this; + } + + public List getPayloadModelKeys() { + return payloadModelKeys; + } + + public WaylineUploadCallbackMetadata setPayloadModelKeys(List payloadModelKeys) { + this.payloadModelKeys = payloadModelKeys; + return this; + } + + public List getTemplateTypes() { + return templateTypes; + } + + public WaylineUploadCallbackMetadata setTemplateTypes(List templateTypes) { + this.templateTypes = templateTypes; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineUploadCallbackRequest.java b/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineUploadCallbackRequest.java new file mode 100644 index 0000000..87f8214 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/WaylineUploadCallbackRequest.java @@ -0,0 +1,69 @@ +package com.dji.sdk.cloudapi.wayline; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/23 + */ +@Schema(description = "The data class of the upload result callback") +public class WaylineUploadCallbackRequest { + + @NotNull + @Schema(description = "The key of the object in the bucket", example = "wayline/waylineFile.kmz") + @JsonProperty("object_key") + private String objectKey; + + @NotNull + @Schema(description = "wayline file name", example = "waylineFile") + private String name; + + @Valid + @NotNull + @Schema(description = "wayline file metadata") + private WaylineUploadCallbackMetadata metadata; + + public WaylineUploadCallbackRequest() { + } + + @Override + public String toString() { + return "WaylineUploadCallbackRequest{" + + "objectKey='" + objectKey + '\'' + + ", name='" + name + '\'' + + ", metadata=" + metadata + + '}'; + } + + public String getObjectKey() { + return objectKey; + } + + public WaylineUploadCallbackRequest setObjectKey(String objectKey) { + this.objectKey = objectKey; + return this; + } + + public String getName() { + return name; + } + + public WaylineUploadCallbackRequest setName(String name) { + this.name = name; + return this; + } + + public WaylineUploadCallbackMetadata getMetadata() { + return metadata; + } + + public WaylineUploadCallbackRequest setMetadata(WaylineUploadCallbackMetadata metadata) { + this.metadata = metadata; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/api/AbstractWaylineService.java b/src/main/java/com/dji/sdk/cloudapi/wayline/api/AbstractWaylineService.java new file mode 100644 index 0000000..b295d0f --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/api/AbstractWaylineService.java @@ -0,0 +1,195 @@ +package com.dji.sdk.cloudapi.wayline.api; + +import com.dji.sdk.annotations.CloudSDKVersion; +import com.dji.sdk.cloudapi.wayline.*; +import com.dji.sdk.common.CloudSDKVersionEnum; +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.exception.CloudSDKException; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import com.dji.sdk.mqtt.services.ServicesPublish; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import javax.annotation.Resource; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public abstract class AbstractWaylineService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Notification of device exits the Return to Home (RTH) state + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_DEVICE_EXIT_HOMING_NOTIFY, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse deviceExitHomingNotify(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("deviceExitHomingNotify not implemented"); + } + + /** + * Report wayline task progress + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHTTASK_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse flighttaskProgress(TopicEventsRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("flighttaskProgress not implemented"); + } + + /** + * Notification of task readiness + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHTTASK_READY, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse flighttaskReady(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("flighttaskReady not implemented"); + } + + /** + * Create wayline task (Deprecated) + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(deprecated = CloudSDKVersionEnum.V0_0_1, exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskCreate(GatewayManager gateway, FlighttaskCreateRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_CREATE.getMethod(), + request); + } + + /** + * Issue wayline task + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskPrepare(GatewayManager gateway, FlighttaskPrepareRequest request) { + validPrepareParam(request); + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_PREPARE.getMethod(), + request, + request.getFlightId()); + } + + /** + * Execute wayline task + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskExecute(GatewayManager gateway, FlighttaskExecuteRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_EXECUTE.getMethod(), + request, + request.getFlightId()); + } + + /** + * Cancel wayline task + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskUndo(GatewayManager gateway, FlighttaskUndoRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_UNDO.getMethod(), + request); + } + + /** + * Pause wayline task + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskPause(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_PAUSE.getMethod()); + } + + /** + * Resume wayline task + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskRecovery(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_RECOVERY.getMethod()); + } + + /** + * Return to Home (RTH) + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse returnHome(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.RETURN_HOME.getMethod()); + } + + /** + * Cancel return to home + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse returnHomeCancel(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.RETURN_HOME_CANCEL.getMethod()); + } + + /** + * Get the wayline task resource + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_FLIGHTTASK_RESOURCE_GET, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse> flighttaskResourceGet(TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("flighttaskResourceGet not implemented"); + } + + + private void validPrepareParam(FlighttaskPrepareRequest request) { + if (null == request.getExecuteTime() + && (TaskTypeEnum.IMMEDIATE == request.getTaskType() || TaskTypeEnum.TIMED == request.getTaskType())) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, "Execute time must not be null."); + } + if (TaskTypeEnum.CONDITIONAL == request.getTaskType()) { + Common.validateModel(request.getReadyConditions()); + } + } + +} diff --git a/src/main/java/com/dji/sdk/cloudapi/wayline/api/IHttpWaylineService.java b/src/main/java/com/dji/sdk/cloudapi/wayline/api/IHttpWaylineService.java new file mode 100644 index 0000000..17fae68 --- /dev/null +++ b/src/main/java/com/dji/sdk/cloudapi/wayline/api/IHttpWaylineService.java @@ -0,0 +1,151 @@ +package com.dji.sdk.cloudapi.wayline.api; + +import com.dji.sdk.cloudapi.wayline.GetWaylineListRequest; +import com.dji.sdk.cloudapi.wayline.GetWaylineListResponse; +import com.dji.sdk.cloudapi.wayline.WaylineUploadCallbackRequest; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springdoc.api.annotations.ParameterObject; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Tag(name = "wayline interface") +public interface IHttpWaylineService { + + String PREFIX = "wayline/api/v1"; + + /** + * Query the basic data of the wayline file according to the query conditions. + * The query condition field in pilot is fixed. + * @param workspaceId workspace id + * @param request get waylines params + * @param req + * @param rsp + * @return wayline list + */ + @Operation(summary = "get wayline list", description = "Query the basic data of the wayline file according to " + + "the query conditions. The query condition field in pilot is fixed.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }) + @GetMapping(PREFIX + "/workspaces/{workspace_id}/waylines") + HttpResultResponse> getWaylineList( + @Valid @ParameterObject GetWaylineListRequest request, + @PathVariable(name = "workspace_id") String workspaceId, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Query the download address of the file according to the wayline file id, + * and redirect to this address directly for download. + * @param workspaceId workspace id + * @param waylineId wayline file id + * @param req + * @param rsp + */ + @Operation(summary = "get wayline file download address", description = "Query the download address of the file " + + "according to the wayline file id, and redirect to this address directly for download.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + @Parameter(name = "wayline_id", description = "wayline id", schema = @Schema(format = "uuid")) + }) + @GetMapping(PREFIX + "/workspaces/{workspace_id}/waylines/{wayline_id}/url") + void getWaylineFileDownloadAddress( + @PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "wayline_id") String waylineId, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Checking whether the name already exists according to the wayline name must ensure the uniqueness of the wayline name. + * This interface will be called when uploading waylines and must be available. + * @param workspaceId workspace id + * @param names wayline file name collection + * @param req + * @param rsp + * @return already existing wayline name + */ + @Operation(summary = "get duplicated wayline name", description = "Checking whether the name already exists " + + "according to the wayline name must ensure the uniqueness of the wayline name. " + + "This interface will be called when uploading waylines and must be available.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", required = true), + @Parameter(name = "name", description = "wayline file name", required = true) + }) + @GetMapping(PREFIX + "/workspaces/{workspace_id}/waylines/duplicate-names") + HttpResultResponse> getDuplicatedWaylineName( + @PathVariable(name = "workspace_id") String workspaceId, + @NotNull @Size(min = 1) @RequestParam(name = "name") List names, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * When the wayline file is uploaded to the storage server by pilot, + * the basic information of the file is reported through this interface. + * @param workspaceId workspace id + * @param request upload callback params + * @param req + * @param rsp + * @return success + */ + @Operation(summary = "file upload result report", description = "When the wayline file is uploaded to the " + + "storage server by pilot, the basic information of the file is reported through this interface.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", required = true) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/upload-callback") + HttpResultResponse fileUploadResultReport( + @PathVariable(name = "workspace_id") String workspaceId, + @Valid @RequestBody WaylineUploadCallbackRequest request, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Favorite the wayline file according to the wayline file id. + * @param workspaceId workspace id + * @param ids wayline file id + * @param req + * @param rsp + * @return success + */ + @Operation(summary = "batch favorites wayline", description = "Favorite the wayline file according to the wayline file id.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", required = true), + @Parameter(name = "id", description = "wayline id", required = true) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/favorites") + HttpResultResponse batchFavoritesWayline( + @PathVariable(name = "workspace_id") String workspaceId, + @NotNull @Size(min = 1) @RequestParam(name = "id") List ids, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Delete the favorites of this wayline file based on the wayline file id. + * @param workspaceId workspace id + * @param ids wayline file id + * @param req + * @param rsp + * @return success + */ + @Operation(summary = "batch unfavorites wayline", description = "Delete the favorites of this wayline file based on the wayline file id.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", required = true), + @Parameter(name = "id", description = "wayline id", required = true) + }) + @DeleteMapping(PREFIX + "/workspaces/{workspace_id}/favorites") + HttpResultResponse batchUnfavoritesWayline( + @PathVariable(name = "workspace_id") String workspaceId, + @NotNull @Size(min = 1) @RequestParam(name = "id") List ids, + HttpServletRequest req, HttpServletResponse rsp); +} diff --git a/src/main/java/com/dji/sdk/common/BaseModel.java b/src/main/java/com/dji/sdk/common/BaseModel.java new file mode 100644 index 0000000..00fde60 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/BaseModel.java @@ -0,0 +1,81 @@ +package com.dji.sdk.common; + +import com.dji.sdk.annotations.CloudSDKVersion; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import org.springframework.util.CollectionUtils; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class BaseModel { + + private final static Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator(); + + public void valid() { + this.valid(null); + } + + public void checkProperty(String fieldName, GatewayManager gateway) { + try { + Field field = this.getClass().getDeclaredField(fieldName); + CloudSDKVersion annotation = field.getDeclaredAnnotation(CloudSDKVersion.class); + if (!gateway.isTypeSupport(annotation) || !gateway.isVersionSupport(annotation)) { + throw new CloudSDKException(CloudSDKErrorEnum.DEVICE_PROPERTY_NOT_SUPPORT, fieldName); + } + } catch (NoSuchFieldException e) { + throw new CloudSDKException(e); + } + } + + public void valid(GatewayManager gateway) { + Set> violations = VALIDATOR.validate(this); + if (null != gateway) { + Set names = new HashSet<>(); + violations = violations.stream().filter(violation -> + filterProperty(gateway, violation.getRootBeanClass(), + violation.getPropertyPath().toString().split("\\."), 0, true, names)) + .collect(Collectors.toSet()); + } + + if (CollectionUtils.isEmpty(violations)) { + return; + } + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, violations.stream() + .map(violation -> violation.getPropertyPath().toString() + violation.getMessage() + + ", Current value is: " + violation.getInvalidValue()) + .collect(Collectors.joining("; "))); + + } + + private boolean filterProperty(GatewayManager gateway, Class clazz, String[] fields, int index, boolean isValid, Set names) { + if (!isValid || index == fields.length) { + return isValid; + } + String name = String.join(".", Arrays.copyOf(fields, index + 1)); + if (names.contains(name)) { + return false; + } + try { + Field field = clazz.getDeclaredField(fields[index]); + isValid = gateway.isPropertyValid(field.getAnnotation(CloudSDKVersion.class)); + if (!isValid) { + names.add(name); + } + return filterProperty(gateway, field.getType(), fields, index + 1, isValid, names); + } catch (NoSuchFieldException e) { + throw new CloudSDKException(e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/common/CloudSDKVersionEnum.java b/src/main/java/com/dji/sdk/common/CloudSDKVersionEnum.java new file mode 100644 index 0000000..7ace3e1 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/CloudSDKVersionEnum.java @@ -0,0 +1,35 @@ +package com.dji.sdk.common; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/22 + */ +public enum CloudSDKVersionEnum { + + V0_0_1("0.0.1"), + + V1_0_0("1.0.0"), + + DEFAULT("1.0.0"), + + V99("99"); + + private final String version; + + CloudSDKVersionEnum(String version) { + this.version = version; + } + + public String getVersion() { + return version; + } + + public boolean isSupported(CloudSDKVersionEnum version) { + return this.version.compareTo(version.getVersion()) >= 0; + } + + public boolean isDeprecated(CloudSDKVersionEnum version) { + return this.version.compareTo(version.getVersion()) >= 0; + } +} diff --git a/src/main/java/com/dji/sdk/common/Common.java b/src/main/java/com/dji/sdk/common/Common.java new file mode 100644 index 0000000..25924fe --- /dev/null +++ b/src/main/java/com/dji/sdk/common/Common.java @@ -0,0 +1,60 @@ +package com.dji.sdk.common; + +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class Common { + + private static final JsonMapper.Builder MAPPER_BUILDER = JsonMapper.builder(); + + static { + JavaTimeModule timeModule = new JavaTimeModule(); + timeModule.addDeserializer(LocalDateTime.class, + new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + timeModule.addSerializer(LocalDateTime.class, + new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + + MAPPER_BUILDER.propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE) + .serializationInclusion(JsonInclude.Include.NON_ABSENT) + .disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS) + .addModule(timeModule) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) + .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true) + .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true) + .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true); + } + + public static void validateModel(BaseModel model) { + if (null == model) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, "Param must not be null."); + } + model.valid(); + } + + public static void validateModel(BaseModel model, GatewayManager gateway) { + if (null == model) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, "Param must not be null."); + } + model.valid(gateway); + } + + public static ObjectMapper getObjectMapper() { + return MAPPER_BUILDER.build(); + } +} diff --git a/src/main/java/com/dji/sdk/common/CommonErrorEnum.java b/src/main/java/com/dji/sdk/common/CommonErrorEnum.java new file mode 100644 index 0000000..dcf71b7 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/CommonErrorEnum.java @@ -0,0 +1,42 @@ + +package com.dji.sdk.common; + +import com.dji.sdk.mqtt.events.IEventsErrorCode; +import com.dji.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum CommonErrorEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + STATUS_NOT_SUPPORTED(314000, "The device is either uploading logs or executing a flight mission. Please try again later."), + + WRONG_PARAMETER(325001, "Cloud command parameter error. Dock unable to execute command."), + + UNKNOWN(-1, "Unknown"); + + private final int code; + + private final String msg; + + CommonErrorEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + public Integer getCode() { + return this.code; + } + + public String getMessage() { + return this.msg; + } + + public static CommonErrorEnum find(int code) { + return Arrays.stream(values()).filter(error -> error.code == code).findAny().orElse(UNKNOWN); + } +} diff --git a/src/main/java/com/dji/sdk/common/DockThingVersionEnum.java b/src/main/java/com/dji/sdk/common/DockThingVersionEnum.java new file mode 100644 index 0000000..3a8d4fb --- /dev/null +++ b/src/main/java/com/dji/sdk/common/DockThingVersionEnum.java @@ -0,0 +1,52 @@ +package com.dji.sdk.common; + +import com.dji.sdk.exception.CloudSDKVersionException; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public enum DockThingVersionEnum { + + V1_0_0("1.0.0", CloudSDKVersionEnum.V0_0_1), + + V1_1_0("1.1.0", CloudSDKVersionEnum.V1_0_0), + + V1_1_2("1.1.2", CloudSDKVersionEnum.V1_0_0), + + V1_2_0("1.2.0", CloudSDKVersionEnum.V1_0_0), + + ; + + private final String thingVersion; + + private final CloudSDKVersionEnum cloudSDKVersion; + + DockThingVersionEnum(String thingVersion, CloudSDKVersionEnum cloudSDKVersion) { + this.thingVersion = thingVersion; + this.cloudSDKVersion = cloudSDKVersion; + } + + @JsonValue + public String getThingVersion() { + return thingVersion; + } + + public CloudSDKVersionEnum getCloudSDKVersion() { + return cloudSDKVersion; + } + + public static DockThingVersionEnum find(String thingVersion) { + Optional opt = Arrays.stream(values()) + .filter(thingVersionEnum -> thingVersionEnum.thingVersion.equals(thingVersion)).findAny(); + if (opt.isPresent()) { + return opt.get(); + } + throw new CloudSDKVersionException(thingVersion); + } +} diff --git a/src/main/java/com/dji/sdk/common/DroneThingVersionEnum.java b/src/main/java/com/dji/sdk/common/DroneThingVersionEnum.java new file mode 100644 index 0000000..04f9701 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/DroneThingVersionEnum.java @@ -0,0 +1,56 @@ +package com.dji.sdk.common; + +import com.dji.sdk.exception.CloudSDKVersionException; +import com.fasterxml.jackson.annotation.JsonValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public enum DroneThingVersionEnum { + + V1_0_0("1.0.0", CloudSDKVersionEnum.V0_0_1), + + V1_1_0("1.1.0", CloudSDKVersionEnum.V1_0_0), + + V1_1_2("1.1.2", CloudSDKVersionEnum.V1_0_0), + + V1_2_0("1.2.0", CloudSDKVersionEnum.V1_0_0), + + ; + + private static final Logger log = LoggerFactory.getLogger(DroneThingVersionEnum.class); + + private final String thingVersion; + + private final CloudSDKVersionEnum cloudSDKVersion; + + DroneThingVersionEnum(String thingVersion, CloudSDKVersionEnum cloudSDKVersion) { + this.thingVersion = thingVersion; + this.cloudSDKVersion = cloudSDKVersion; + } + + @JsonValue + public String getThingVersion() { + return thingVersion; + } + + public CloudSDKVersionEnum getCloudSDKVersion() { + return cloudSDKVersion; + } + + public static DroneThingVersionEnum find(String thingVersion) { + Optional opt = Arrays.stream(values()) + .filter(thingVersionEnum -> thingVersionEnum.thingVersion.equals(thingVersion)).findAny(); + if (opt.isPresent()) { + return opt.get(); + } + throw new CloudSDKVersionException(thingVersion); + } +} diff --git a/src/main/java/com/dji/sdk/common/ErrorCodeSourceEnum.java b/src/main/java/com/dji/sdk/common/ErrorCodeSourceEnum.java new file mode 100644 index 0000000..01c1ef2 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/ErrorCodeSourceEnum.java @@ -0,0 +1,39 @@ + +package com.dji.sdk.common; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum ErrorCodeSourceEnum { + + DEVICE(3), + + DOCK(5), + + PILOT(6); + + private final int source; + + ErrorCodeSourceEnum(int source) { + this.source = source; + } + + @JsonValue + public int getSource() { + return source; + } + + @JsonCreator + public static ErrorCodeSourceEnum find(int source) { + return Arrays.stream(values()).filter(error -> error.source == source).findAny() + .orElseThrow(() -> new CloudSDKException(ErrorCodeSourceEnum.class, source)); + } +} diff --git a/src/main/java/com/dji/sdk/common/GatewayManager.java b/src/main/java/com/dji/sdk/common/GatewayManager.java new file mode 100644 index 0000000..a8e3e6e --- /dev/null +++ b/src/main/java/com/dji/sdk/common/GatewayManager.java @@ -0,0 +1,88 @@ +package com.dji.sdk.common; + +import com.dji.sdk.annotations.CloudSDKVersion; + +import java.util.Arrays; +import java.util.Objects; + +/** + * SDK information corresponding to the gateway device + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public class GatewayManager { + + private String gatewaySn; + private GatewayThingVersion gatewayThingVersion; + private DroneThingVersionEnum droneThingVersion; + private GatewayTypeEnum type; + private CloudSDKVersionEnum sdkVersion; + private String droneSn; + + private GatewayManager(String gatewaySn, String droneSn, GatewayTypeEnum gatewayType) { + this.gatewaySn = gatewaySn; + this.type = gatewayType; + this.droneSn = droneSn; + } + + public GatewayManager(String gatewaySn, String droneSn, GatewayTypeEnum gatewayType, String gatewayThingVersion, String droneThingVersion) { + this(gatewaySn, droneSn, gatewayType); + this.gatewayThingVersion = new GatewayThingVersion(gatewayType, gatewayThingVersion); + if (GatewayTypeEnum.RC == gatewayType) { + this.sdkVersion = CloudSDKVersionEnum.DEFAULT; + return; + } + if (Objects.isNull(this.droneThingVersion)) { + this.sdkVersion = this.gatewayThingVersion.getCloudSDKVersion(); + return; + } + this.droneThingVersion = DroneThingVersionEnum.find(droneThingVersion); + this.sdkVersion = this.gatewayThingVersion.getCloudSDKVersion().isSupported(this.droneThingVersion.getCloudSDKVersion()) ? + this.droneThingVersion.getCloudSDKVersion() : this.gatewayThingVersion.getCloudSDKVersion(); + } + + public String getGatewaySn() { + return gatewaySn; + } + + public GatewayThingVersion getGatewayThingVersion() { + return gatewayThingVersion; + } + + public DroneThingVersionEnum getDroneThingVersion() { + return droneThingVersion; + } + + public GatewayTypeEnum getType() { + return type; + } + + public CloudSDKVersionEnum getSdkVersion() { + return sdkVersion; + } + + public String getDroneSn() { + return droneSn; + } + + public boolean isTypeSupport(CloudSDKVersion version) { + return null != version && Arrays.stream(version.exclude()).noneMatch(typeEnum -> typeEnum == this.getType()) + && (version.include().length == 0 + || Arrays.stream(version.include()).anyMatch(typeEnum -> typeEnum == this.getType())); + } + + public boolean isVersionSupport(CloudSDKVersion version) { + return null != version && this.getSdkVersion().isSupported(version.since()) && !isDeprecated(version); + } + + public boolean isDeprecated(CloudSDKVersion version) { + return null != version && this.getSdkVersion().isDeprecated(version.deprecated()); + } + + public boolean isPropertyValid(CloudSDKVersion version) { + return null == version || + (!this.getSdkVersion().isDeprecated(version.since()) + && this.getSdkVersion().isSupported(version.since())); + } +} diff --git a/src/main/java/com/dji/sdk/common/GatewayThingVersion.java b/src/main/java/com/dji/sdk/common/GatewayThingVersion.java new file mode 100644 index 0000000..b8c39fd --- /dev/null +++ b/src/main/java/com/dji/sdk/common/GatewayThingVersion.java @@ -0,0 +1,48 @@ +package com.dji.sdk.common; + +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public class GatewayThingVersion { + + private DockThingVersionEnum dockThingVersion; + + private RcThingVersionEnum rcThingVersion; + + public GatewayThingVersion(DockThingVersionEnum dockThingVersion) { + this.dockThingVersion = dockThingVersion; + } + + public GatewayThingVersion(RcThingVersionEnum rcThingVersion) { + this.rcThingVersion = rcThingVersion; + } + + public GatewayThingVersion(GatewayTypeEnum type, String thingVersion) { + switch (type) { + case DOCK: + this.dockThingVersion = DockThingVersionEnum.find(thingVersion); + return; + case RC: + this.rcThingVersion = RcThingVersionEnum.find(thingVersion); + return; + } + } + + public String getThingVersion() { + if (Objects.nonNull(dockThingVersion)) { + return dockThingVersion.getThingVersion(); + } + return rcThingVersion.getThingVersion(); + } + + public CloudSDKVersionEnum getCloudSDKVersion() { + if (Objects.nonNull(dockThingVersion)) { + return dockThingVersion.getCloudSDKVersion(); + } + return rcThingVersion.getCloudSDKVersion(); + } +} diff --git a/src/main/java/com/dji/sdk/common/GatewayTypeEnum.java b/src/main/java/com/dji/sdk/common/GatewayTypeEnum.java new file mode 100644 index 0000000..05b4d9b --- /dev/null +++ b/src/main/java/com/dji/sdk/common/GatewayTypeEnum.java @@ -0,0 +1,33 @@ +package com.dji.sdk.common; + +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.dji.sdk.exception.CloudSDKException; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public enum GatewayTypeEnum { + + RC(DeviceEnum.RC, DeviceEnum.RC_PLUS, DeviceEnum.RC_PRO), + + DOCK(DeviceEnum.DOCK); + + private final DeviceEnum[] gateway; + + GatewayTypeEnum(DeviceEnum... gateway) { + this.gateway = gateway; + } + + public DeviceEnum[] getGateway() { + return gateway; + } + + public static GatewayTypeEnum find(DeviceEnum device) { + return Arrays.stream(values()).filter(gateway -> Arrays.stream(gateway.gateway).anyMatch(deviceEnum -> device == deviceEnum)) + .findAny().orElseThrow(() -> new CloudSDKException(GatewayTypeEnum.class, device)); + } +} diff --git a/src/main/java/com/dji/sdk/common/HttpResultResponse.java b/src/main/java/com/dji/sdk/common/HttpResultResponse.java new file mode 100644 index 0000000..9e3efb9 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/HttpResultResponse.java @@ -0,0 +1,95 @@ +package com.dji.sdk.common; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "The data format of the http response.") +public class HttpResultResponse { + + public static final int CODE_SUCCESS = 0; + public static final int CODE_FAILED = -1; + public static final String MESSAGE_SUCCESS = "success"; + public static final String MESSAGE_FAILED = "failed"; + + @Schema(description = "0 means success, non-zero means error.", example = "0") + private int code; + + @Schema(description = "The response message.", example = MESSAGE_SUCCESS) + private String message; + + @Schema(description = "The response data.") + private T data; + + public HttpResultResponse() { + } + + @Override + public String toString() { + return "HttpResultResponse{" + + "code=" + code + + ", message='" + message + '\'' + + ", data=" + data + + '}'; + } + + public int getCode() { + return code; + } + + public HttpResultResponse setCode(int code) { + this.code = code; + return this; + } + + public String getMessage() { + return message; + } + + public HttpResultResponse setMessage(String message) { + this.message = message;; + return this; + } + + public T getData() { + return data; + } + + public HttpResultResponse setData(T data) { + this.data = data; + return this; + } + + public static HttpResultResponse success() { + return new HttpResultResponse() + .setCode(CODE_SUCCESS) + .setMessage(MESSAGE_SUCCESS) + .setData(""); + } + + public static HttpResultResponse success(T data) { + return HttpResultResponse.success().setData(data); + } + + public static HttpResultResponse error() { + return new HttpResultResponse() + .setCode(CODE_FAILED) + .setMessage(MESSAGE_FAILED); + } + + public static HttpResultResponse error(String message) { + return new HttpResultResponse() + .setCode(CODE_FAILED) + .setMessage(message); + } + + public static HttpResultResponse error(int code, String message) { + return new HttpResultResponse() + .setCode(code) + .setMessage(message); + } + + public static HttpResultResponse error(IErrorInfo errorInfo) { + return new HttpResultResponse() + .setCode(errorInfo.getCode()) + .setMessage(errorInfo.getMessage()); + } +} diff --git a/src/main/java/com/dji/sample/common/error/IErrorInfo.java b/src/main/java/com/dji/sdk/common/IErrorInfo.java similarity index 72% rename from src/main/java/com/dji/sample/common/error/IErrorInfo.java rename to src/main/java/com/dji/sdk/common/IErrorInfo.java index 3332dd3..c4965f4 100644 --- a/src/main/java/com/dji/sample/common/error/IErrorInfo.java +++ b/src/main/java/com/dji/sdk/common/IErrorInfo.java @@ -1,4 +1,4 @@ -package com.dji.sample.common.error; +package com.dji.sdk.common; /** * @author sean.zhou @@ -11,12 +11,12 @@ public interface IErrorInfo { * Get error message. * @return error message */ - String getErrorMsg(); + String getMessage(); /** * Get error code. * @return error code */ - Integer getErrorCode(); + Integer getCode(); } diff --git a/src/main/java/com/dji/sdk/common/Pagination.java b/src/main/java/com/dji/sdk/common/Pagination.java new file mode 100644 index 0000000..7a025d3 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/Pagination.java @@ -0,0 +1,80 @@ +package com.dji.sdk.common; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * Used for paging display. These field names cannot be changed. + * Because they need to be the same as the pilot. + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Schema(description = "Used for paging display") +public class Pagination { + + /** + * The current page number. + */ + @Schema(description = "The current page number.", example = "1") + private long page; + + /** + * The amount of data displayed per page. + */ + @Schema(description = "The amount of data displayed per page.", example = "10") + @JsonProperty("page_size") + private long pageSize; + + /** + * The total amount of all data. + */ + @Schema(description = "The total amount of all data.", example = "10") + private long total; + + public Pagination() { + } + + public Pagination(Page page) { + this.page = page.getCurrent(); + this.pageSize = page.getSize(); + this.total = page.getTotal(); + } + + @Override + public String toString() { + return "Pagination{" + + "page=" + page + + ", pageSize=" + pageSize + + ", total=" + total + + '}'; + } + + public long getPage() { + return page; + } + + public Pagination setPage(long page) { + this.page = page; + return this; + } + + public long getPageSize() { + return pageSize; + } + + public Pagination setPageSize(long pageSize) { + this.pageSize = pageSize; + return this; + } + + public long getTotal() { + return total; + } + + public Pagination setTotal(long total) { + this.total = total; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/common/PaginationData.java b/src/main/java/com/dji/sdk/common/PaginationData.java new file mode 100644 index 0000000..c690de9 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/PaginationData.java @@ -0,0 +1,58 @@ +package com.dji.sdk.common; + +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.List; + +/** + * The format of the data response when a paginated display is required. + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Schema(description = "Format of paged data") +public class PaginationData { + + /** + * The collection in which the data list is stored. + */ + @Schema(description = "The collection in which the data list is stored.") + private List list; + + @Schema(description = "Used for paging display. These field names cannot be changed. Because they need to be the same as the pilot.") + private Pagination pagination; + + public PaginationData() { + } + + public PaginationData(List list, Pagination pagination) { + this.list = list; + this.pagination = pagination; + } + + @Override + public String toString() { + return "PaginationData{" + + "list=" + list + + ", pagination=" + pagination + + '}'; + } + + public List getList() { + return list; + } + + public PaginationData setList(List list) { + this.list = list; + return this; + } + + public Pagination getPagination() { + return pagination; + } + + public PaginationData setPagination(Pagination pagination) { + this.pagination = pagination; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/common/RcThingVersionEnum.java b/src/main/java/com/dji/sdk/common/RcThingVersionEnum.java new file mode 100644 index 0000000..1a263d9 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/RcThingVersionEnum.java @@ -0,0 +1,35 @@ +package com.dji.sdk.common; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public enum RcThingVersionEnum { + + V1_0_0("1.0.0", CloudSDKVersionEnum.V0_0_1); + + private final String thingVersion; + + private final CloudSDKVersionEnum cloudSDKVersion; + + RcThingVersionEnum(String thingVersion, CloudSDKVersionEnum cloudSDKVersion) { + this.thingVersion = thingVersion; + this.cloudSDKVersion = cloudSDKVersion; + } + + @JsonValue + public String getThingVersion() { + return thingVersion; + } + + public CloudSDKVersionEnum getCloudSDKVersion() { + return cloudSDKVersion; + } + + public static RcThingVersionEnum find(String thingVersion) { + return V1_0_0; + } +} diff --git a/src/main/java/com/dji/sdk/common/SDKManager.java b/src/main/java/com/dji/sdk/common/SDKManager.java new file mode 100644 index 0000000..ce07689 --- /dev/null +++ b/src/main/java/com/dji/sdk/common/SDKManager.java @@ -0,0 +1,50 @@ +package com.dji.sdk.common; + +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.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; + +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public class SDKManager { + + private SDKManager() { + } + + private static final ConcurrentHashMap SDK_MAP = new ConcurrentHashMap<>(16); + + public static GatewayManager getDeviceSDK(String gatewaySn) { + if (SDK_MAP.containsKey(gatewaySn)) { + return SDK_MAP.get(gatewaySn); + } + throw new CloudSDKException(CloudSDKErrorEnum.NOT_REGISTERED, + "The device has not been registered, please call the 'SDKManager.registerDevice()' method to register the device first."); + } + + public static GatewayManager registerDevice(String gatewaySn, String droneSn, + DeviceDomainEnum domain, DeviceTypeEnum type, DeviceSubTypeEnum subType, String gatewayThingVersion, String droneThingVersion) { + return registerDevice(gatewaySn, droneSn, GatewayTypeEnum.find(DeviceEnum.find(domain, type, subType)), gatewayThingVersion, droneThingVersion); + } + + public static GatewayManager registerDevice(String gatewaySn, String droneSn, GatewayTypeEnum type, String gatewayThingVersion, String droneThingVersion) { + return registerDevice(new GatewayManager(Objects.requireNonNull(gatewaySn), droneSn, type, gatewayThingVersion, droneThingVersion)); + } + + public static GatewayManager registerDevice(GatewayManager gateway) { + SDK_MAP.put(gateway.getGatewaySn(), gateway); + return gateway; + } + + public static void logoutDevice(String gatewaySn) { + SDK_MAP.remove(gatewaySn); + } +} diff --git a/src/main/java/com/dji/sample/common/util/SpringBeanUtils.java b/src/main/java/com/dji/sdk/common/SpringBeanUtils.java similarity index 95% rename from src/main/java/com/dji/sample/common/util/SpringBeanUtils.java rename to src/main/java/com/dji/sdk/common/SpringBeanUtils.java index 23e8966..3aa93fa 100644 --- a/src/main/java/com/dji/sample/common/util/SpringBeanUtils.java +++ b/src/main/java/com/dji/sdk/common/SpringBeanUtils.java @@ -1,4 +1,4 @@ -package com.dji.sample.common.util; +package com.dji.sdk.common; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; diff --git a/src/main/java/com/dji/sdk/config/CloudSDKHandler.java b/src/main/java/com/dji/sdk/config/CloudSDKHandler.java new file mode 100644 index 0000000..b0ef220 --- /dev/null +++ b/src/main/java/com/dji/sdk/config/CloudSDKHandler.java @@ -0,0 +1,107 @@ +package com.dji.sdk.config; + +import com.dji.sdk.annotations.CloudSDKVersion; +import com.dji.sdk.common.*; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; + +import java.lang.reflect.*; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/22 + */ +@Aspect +@Component +public class CloudSDKHandler { + + @Before("execution(public * com.dji.sdk.cloudapi.*.api.*.*(com.dji.sdk.common.GatewayManager, ..))") + public void checkCloudSDK(JoinPoint point) { + GatewayManager deviceSDK = (GatewayManager) point.getArgs()[0]; + CloudSDKVersion since = ((MethodSignature) point.getSignature()).getMethod().getDeclaredAnnotation(CloudSDKVersion.class); + if (Objects.isNull(since)) { + return; + } + if (!deviceSDK.isTypeSupport(since)) { + throw new CloudSDKException(CloudSDKErrorEnum.DEVICE_TYPE_NOT_SUPPORT); + } + if (!deviceSDK.isVersionSupport(since)) { + throw new CloudSDKException(CloudSDKErrorEnum.DEVICE_VERSION_NOT_SUPPORT); + } + } + + @Before("execution(public * com.dji.sdk.cloudapi.*.api.*.*(com.dji.sdk.common.GatewayManager, com.dji.sdk.common.BaseModel+))") + public void checkRequest(JoinPoint point) { + Common.validateModel((BaseModel) point.getArgs()[1], (GatewayManager) point.getArgs()[0]); + } + + @AfterReturning(value = "execution(public com.dji.sdk.common.HttpResultResponse+ com.dji.sdk.cloudapi.*.api.*.*(..))", returning = "response") + public void checkResponse(JoinPoint point, HttpResultResponse response) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { + if (null == response) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, "The return value cannot be null."); + } + Method method = ((MethodSignature) point.getSignature()).getMethod(); + if (method.getGenericReturnType() instanceof Class) { + if (null == response.getData()) { + response.setData(""); + } + return; + } + checkClassType((ParameterizedType) method.getGenericReturnType(), response); + validData(response.getData(), point.getArgs()[0]); + } + + private void checkClassType(ParameterizedType type, HttpResultResponse response) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + Type actualType = type.getActualTypeArguments()[0]; + Class typeClass = actualType instanceof Class ? (Class) actualType : (Class) ((ParameterizedType) actualType).getRawType(); + if (null == response.getData()) { + if (List.class.isAssignableFrom(typeClass)) { + response.setData(Collections.emptyList()); + return; + } + response.setData(typeClass.getDeclaredConstructor().newInstance()); + return; + } + boolean isAssignableFrom = typeClass.isAssignableFrom(response.getData().getClass()); + if (!isAssignableFrom) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + } + + private void validData(Object data, Object arg) { + if (data instanceof BaseModel) { + Common.validateModel((BaseModel) data); + return; + } + if (data instanceof PaginationData) { + List list = ((PaginationData) data).getList(); + if (null == list) { + ((PaginationData) data).setList(Collections.EMPTY_LIST); + try { + Field page = arg.getClass().getDeclaredField("page"); + Field pageSize = arg.getClass().getDeclaredField("pageSize"); + page.setAccessible(true); + pageSize.setAccessible(true); + ((PaginationData) data).setPagination( + new Pagination().setPage((int) page.get(arg)).setPageSize((int) pageSize.get(arg))); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, e.getMessage()); + } + return; + } + for (BaseModel model : list) { + Common.validateModel(model); + } + } + } +} diff --git a/src/main/java/com/dji/sdk/config/CloudSDKMvcConfigurer.java b/src/main/java/com/dji/sdk/config/CloudSDKMvcConfigurer.java new file mode 100644 index 0000000..e5771b2 --- /dev/null +++ b/src/main/java/com/dji/sdk/config/CloudSDKMvcConfigurer.java @@ -0,0 +1,16 @@ +package com.dji.sdk.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +@Configuration +public class CloudSDKMvcConfigurer implements WebMvcConfigurer { + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(new GetSnakeArgumentProcessor(true)); + } +} diff --git a/src/main/java/com/dji/sample/configuration/mvc/GetSnakeArgumentProcessor.java b/src/main/java/com/dji/sdk/config/GetSnakeArgumentProcessor.java similarity index 85% rename from src/main/java/com/dji/sample/configuration/mvc/GetSnakeArgumentProcessor.java rename to src/main/java/com/dji/sdk/config/GetSnakeArgumentProcessor.java index 11d7b48..514b486 100644 --- a/src/main/java/com/dji/sample/configuration/mvc/GetSnakeArgumentProcessor.java +++ b/src/main/java/com/dji/sdk/config/GetSnakeArgumentProcessor.java @@ -1,6 +1,5 @@ -package com.dji.sample.configuration.mvc; +package com.dji.sdk.config; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor; @@ -12,9 +11,6 @@ import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttribu */ public class GetSnakeArgumentProcessor extends ServletModelAttributeMethodProcessor { - @Autowired - private GetSnakeDataBinder snakeDataBinder; - /** * Class constructor. * diff --git a/src/main/java/com/dji/sdk/config/GetSnakeDataBinder.java b/src/main/java/com/dji/sdk/config/GetSnakeDataBinder.java new file mode 100644 index 0000000..b14ab6b --- /dev/null +++ b/src/main/java/com/dji/sdk/config/GetSnakeDataBinder.java @@ -0,0 +1,110 @@ +package com.dji.sdk.config; + +import com.dji.sdk.common.Common; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.PropertyValue; +import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder; + +import javax.servlet.ServletRequest; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +public class GetSnakeDataBinder extends ExtendedServletRequestDataBinder { + + public GetSnakeDataBinder(Object target, String objectName) { + super(target, objectName); + } + + @Override + protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) { + List propertyValueList = mpvs.getPropertyValueList(); + List values = new ArrayList<>(propertyValueList); + Field[] fields = this.getTarget().getClass().getDeclaredFields(); + Map fieldMap = Arrays.stream(fields).collect(Collectors.toMap(Field::getName, field -> field)); + fieldMap.putAll(Arrays.stream(fields).filter(field -> null != field.getAnnotation(JsonProperty.class)) + .collect(Collectors.toMap(field -> field.getAnnotation(JsonProperty.class).value(), field -> field))); + + for (PropertyValue property : values) { + if (!fieldMap.containsKey(property.getName())) { + continue; + } + + Field field = fieldMap.get(property.getName()); + List list = (List) Objects.requireNonNullElse(property.getConvertedValue(), new ArrayList<>()); + list.addAll((List) convertValue(field, this.getTarget(), property.getValue())); + if (!list.isEmpty()) { + property.setConvertedValue(list); + } + + String fieldName = field.getName(); + if (fieldName.equals(property.getName())) { + continue; + } + if (mpvs.contains(fieldName)) { + PropertyValue propertyValue = mpvs.getPropertyValue(fieldName); + if (null != propertyValue.getConvertedValue()) { + ((List) propertyValue.getConvertedValue()).addAll((List) property.getConvertedValue()); + } + } else { + mpvs.addPropertyValue(new PropertyValue(fieldName, Objects.requireNonNullElse(property.getConvertedValue(), property.getValue()))); + } + mpvs.removePropertyValue(property); + } + + super.addBindValues(mpvs, request); + } + + private Object convertValue(Field field, Object object, Object value) { + List convertedValue = new ArrayList(); + if (Enum.class.isAssignableFrom(field.getType())) { + convertedValue.add(getRealEnumValue(field.getType(), object, value)); + } + if (field.getType() == field.getGenericType()) { + return convertedValue; + } + if (List.class.isAssignableFrom(field.getType())) { + if (!value.getClass().isArray()) { + value = String.valueOf(value).split(","); + } + for (String v : (String[]) value) { + if ("".equals(v)) { + continue; + } + convertedValue.add(getRealEnumValue((Class) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0], object, v)); + } + } + + return convertedValue; + } + + private Object getRealEnumValue(Class type, Object object, Object... value) { + if (!type.isEnum()) { + return value; + } + Set methods = Arrays.stream(type.getDeclaredMethods()) + .filter(m -> null != m.getAnnotation(JsonCreator.class)) + .filter(m -> m.getParameterTypes().length == value.length).collect(Collectors.toSet()); + for (Method m : methods) { + try { + Class[] parameterTypes = m.getParameterTypes(); + for (int i = 0; i < value.length; i++) { + value[i] = Common.getObjectMapper().convertValue(value[i], parameterTypes[i]); + } + return m.invoke(object, value); + } catch (IllegalAccessException | InvocationTargetException ignored) { + } + } + return value; + } +} diff --git a/src/main/java/com/dji/sdk/exception/CloudSDKErrorEnum.java b/src/main/java/com/dji/sdk/exception/CloudSDKErrorEnum.java new file mode 100644 index 0000000..acdf986 --- /dev/null +++ b/src/main/java/com/dji/sdk/exception/CloudSDKErrorEnum.java @@ -0,0 +1,49 @@ +package com.dji.sdk.exception; + +import com.dji.sdk.common.IErrorInfo; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public enum CloudSDKErrorEnum implements IErrorInfo { + + NOT_REGISTERED(210001, "Device is not registered."), + + INVALID_PARAMETER(210002, "Invalid parameter."), + + DEVICE_TYPE_NOT_SUPPORT(210003, "The current type of the device does not support this function."), + + DEVICE_VERSION_NOT_SUPPORT(210004, "The current version of the device does not support this function."), + + DEVICE_PROPERTY_NOT_SUPPORT(210005, "The current device does not support this feature."), + + MQTT_PUBLISH_ABNORMAL(211001, "The sending of mqtt message is abnormal."), + + WEBSOCKET_PUBLISH_ABNORMAL(212001, "The sending of webSocket message is abnormal."), + + WRONG_DATA(220001, "Data exceeds limit."), + + UNKNOWN(299999, "sdk unknown"), + ; + + private final int code; + + private final String message; + + CloudSDKErrorEnum(int code, String message) { + this.code = code; + this.message = message; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public Integer getCode() { + return code; + } +} diff --git a/src/main/java/com/dji/sdk/exception/CloudSDKException.java b/src/main/java/com/dji/sdk/exception/CloudSDKException.java new file mode 100644 index 0000000..66f1357 --- /dev/null +++ b/src/main/java/com/dji/sdk/exception/CloudSDKException.java @@ -0,0 +1,48 @@ +package com.dji.sdk.exception; + +import com.dji.sdk.common.IErrorInfo; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public class CloudSDKException extends RuntimeException { + + private IErrorInfo errorInfo; + + public CloudSDKException(String message) { + super(message); + this.errorInfo = CloudSDKErrorEnum.UNKNOWN; + } + + public CloudSDKException(Throwable cause) { + super(cause); + this.errorInfo = CloudSDKErrorEnum.UNKNOWN; + } + + public CloudSDKException() { + this("SDK Exception"); + this.errorInfo = CloudSDKErrorEnum.UNKNOWN; + } + + public CloudSDKException(Class clazz, Object... code) { + this(clazz.getName() + " has unknown data: " + Arrays.toString(code)); + this.errorInfo = CloudSDKErrorEnum.WRONG_DATA; + } + + public CloudSDKException(IErrorInfo err) { + this(err, null); + } + + public CloudSDKException(IErrorInfo err, String msg) { + this(String.format("Error Code: %d, Error Msg: %s. %s", err.getCode(), err.getMessage(), msg)); + this.errorInfo = err; + } + + public IErrorInfo getErrorInfo() { + return errorInfo; + } +} diff --git a/src/main/java/com/dji/sdk/exception/CloudSDKVersionException.java b/src/main/java/com/dji/sdk/exception/CloudSDKVersionException.java new file mode 100644 index 0000000..5edb22d --- /dev/null +++ b/src/main/java/com/dji/sdk/exception/CloudSDKVersionException.java @@ -0,0 +1,17 @@ +package com.dji.sdk.exception; + +import com.dji.sdk.common.CloudSDKVersionEnum; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/7 + */ +public class CloudSDKVersionException extends CloudSDKException { + + public CloudSDKVersionException(String thingVersion) { + super(String.format("The current CloudSDK version(%s) does not support this thing version(%s), " + + "please replace the corresponding CloudSDK version.)", CloudSDKVersionEnum.DEFAULT.getVersion(), thingVersion)); + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/Chan.java b/src/main/java/com/dji/sdk/mqtt/Chan.java new file mode 100644 index 0000000..88f80b7 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/Chan.java @@ -0,0 +1,59 @@ +package com.dji.sdk.mqtt; + +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.LockSupport; + +/** + * The demo is only for functional closure, which is not recommended. + * @author sean.zhou + * @date 2021/11/22 + * @version 0.1 + */ +public class Chan { + + private static final ConcurrentHashMap CHANNEL = new ConcurrentHashMap<>(); + + private static final int UNIT = 1000_000; + + private volatile CommonTopicResponse data; + + private volatile Thread t; + + private Chan () { + + } + + public static Chan getInstance(String tid, boolean isNeedCreate) { + if (!isNeedCreate) { + return CHANNEL.get(tid); + } + Chan chan = new Chan(); + CHANNEL.put(tid, chan); + return chan; + } + + public CommonTopicResponse get(String tid, long timeout) { + Chan chan = CHANNEL.get(tid); + if (Objects.isNull(chan)) { + return null; + } + chan.t = Thread.currentThread(); + LockSupport.parkNanos(chan.t, timeout * UNIT); + chan.t = null; + CHANNEL.remove(tid); + return chan.data; + } + + public void put(CommonTopicResponse response) { + Chan chan = CHANNEL.get(response.getTid()); + if (Objects.isNull(chan)) { + return; + } + chan.data = response; + if (chan.t == null) { + return; + } + LockSupport.unpark(chan.t); + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/ChannelName.java b/src/main/java/com/dji/sdk/mqtt/ChannelName.java new file mode 100644 index 0000000..1fb7c82 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/ChannelName.java @@ -0,0 +1,137 @@ +package com.dji.sdk.mqtt; + +/** + * The name of all channels. + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +public class ChannelName { + + public static final String INBOUND = "inbound"; + public static final String DEFAULT = "default"; + public static final String OUTBOUND = "outbound"; + + // status + public static final String INBOUND_STATUS = "inboundStatus"; + + public static final String OUTBOUND_STATUS = "outboundStatus"; + + public static final String INBOUND_STATUS_ONLINE = "inboundStatusOnline"; + + public static final String INBOUND_STATUS_OFFLINE = "inboundStatusOffline"; + + + // state + public static final String INBOUND_STATE = "inboundState"; + + public static final String INBOUND_STATE_RC_CONTROL_SOURCE = "inboundStateRcControlSource"; + + public static final String INBOUND_STATE_DOCK_CONTROL_SOURCE = "inboundStateDockControlSource"; + + public static final String INBOUND_STATE_RC_LIVESTREAM_ABILITY_UPDATE = "inboundStateRcLiveCapacity"; + + public static final String INBOUND_STATE_DOCK_LIVESTREAM_ABILITY_UPDATE = "inboundStateDockLiveCapacity"; + + public static final String INBOUND_STATE_RC_LIVE_STATUS = "inboundStateRcLiveStatus"; + + public static final String INBOUND_STATE_DOCK_LIVE_STATUS = "inboundStateDockLiveStatus"; + + public static final String INBOUND_STATE_RC_FIRMWARE_VERSION = "inboundStateRcFirmwareVersion"; + + public static final String INBOUND_STATE_DOCK_FIRMWARE_VERSION = "inboundStateDockFirmwareVersion"; + + public static final String INBOUND_STATE_RC_PAYLOAD_FIRMWARE = "inboundStateRcPayloadFirmware"; + + public static final String INBOUND_STATE_DOCK_WPMZ_VERSION = "inboundStateDockWpmzVersion"; + + public static final String INBOUND_STATE_DOCK_PAYLOAD = "inboundStateDockPayload"; + + + // services_reply + public static final String INBOUND_SERVICES_REPLY = "inboundServicesReply"; + + + // osd + public static final String INBOUND_OSD = "inboundOsd"; + + public static final String INBOUND_OSD_RC = "inboundOsdRc"; + + public static final String INBOUND_OSD_DOCK = "inboundOsdDock"; + + public static final String INBOUND_OSD_RC_DRONE = "inboundOsdRcDrone"; + + public static final String INBOUND_OSD_DOCK_DRONE = "inboundOsdDockDrone"; + + + // requests + public static final String INBOUND_REQUESTS = "inboundRequests"; + + public static final String INBOUND_REQUESTS_STORAGE_CONFIG_GET = "inboundRequestsStorageConfigGet"; + + public static final String INBOUND_REQUESTS_AIRPORT_BIND_STATUS = "inboundRequestsAirportBindStatus"; + + public static final String INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET = "inboundRequestsAirportOrganizationGet"; + + public static final String INBOUND_REQUESTS_AIRPORT_ORGANIZATION_BIND = "inboundRequestsAirportOrganizationBind"; + + public static final String INBOUND_REQUESTS_CONFIG = "inboundRequestsConfig"; + + public static final String INBOUND_REQUESTS_FLIGHTTASK_RESOURCE_GET = "inboundEventsFlightTaskResourceGet"; + + public static final String OUTBOUND_REQUESTS = "outboundRequests"; + + + // events + public static final String INBOUND_EVENTS = "inboundEvents"; + + public static final String OUTBOUND_EVENTS = "outboundEvents"; + + public static final String INBOUND_EVENTS_DEVICE_EXIT_HOMING_NOTIFY = "inboundEventsDeviceExitHomingNotify"; + + public static final String INBOUND_EVENTS_FLIGHTTASK_PROGRESS = "inboundEventsFlighttaskProgress"; + + public static final String INBOUND_EVENTS_FLIGHTTASK_READY = "inboundEventsFlighttaskReady"; + + public static final String INBOUND_EVENTS_FILE_UPLOAD_CALLBACK = "inboundEventsFileUploadCallback"; + + public static final String INBOUND_EVENTS_HMS = "inboundEventsHms"; + + public static final String INBOUND_EVENTS_CONTROL_PROGRESS = "inboundEventsControlProgress"; + + public static final String INBOUND_EVENTS_OTA_PROGRESS = "inboundEventsOtaProgress"; + + public static final String INBOUND_EVENTS_FILEUPLOAD_PROGRESS = "inboundEventsFileUploadProgress"; + + public static final String INBOUND_EVENTS_FLY_TO_POINT_PROGRESS = "inboundEventsFlyToPointProgress"; + + public static final String INBOUND_EVENTS_TAKEOFF_TO_POINT_PROGRESS = "inboundEventsTakeoffToPointProgress"; + + public static final String INBOUND_EVENTS_DRC_STATUS_NOTIFY = "inboundEventsDrcStatusNotify"; + + public static final String INBOUND_EVENTS_JOYSTICK_INVALID_NOTIFY = "inboundEventsJoystickInvalidNotify"; + + public static final String INBOUND_EVENTS_HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA = "inboundEventsHighestPriorityUploadFlightTaskMedia"; + + + // property + public static final String INBOUND_PROPERTY_SET_REPLY = "inboundPropertySetReply"; + + + // drc/up + public static final String INBOUND_DRC_UP = "inboundDrcUp"; + + public static final String INBOUND_DRC_UP_DRONE_CONTROL = "inboundDrcUpDroneControl"; + + public static final String INBOUND_DRC_UP_DRONE_EMERGENCY_STOP = "inboundDrcUpDroneEmergencyStop"; + + public static final String INBOUND_DRC_UP_HEART_BEAT = "inboundDrcUpHeartBeat"; + + public static final String INBOUND_DRC_UP_HSI_INFO_PUSH = "inboundDrcUpHsiInfoPush"; + + public static final String INBOUND_DRC_UP_DELAY_INFO_PUSH = "inboundDrcUpDelayInfoPush"; + + public static final String INBOUND_DRC_UP_OSD_INFO_PUSH = "inboundDrcUpOsdInfoPush"; + +} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/DeviceTopicEnum.java b/src/main/java/com/dji/sdk/mqtt/CloudApiTopicEnum.java similarity index 62% rename from src/main/java/com/dji/sample/component/mqtt/model/DeviceTopicEnum.java rename to src/main/java/com/dji/sdk/mqtt/CloudApiTopicEnum.java index 8598905..4ab6f4c 100644 --- a/src/main/java/com/dji/sample/component/mqtt/model/DeviceTopicEnum.java +++ b/src/main/java/com/dji/sdk/mqtt/CloudApiTopicEnum.java @@ -1,25 +1,22 @@ -package com.dji.sample.component.mqtt.model; - -import lombok.Getter; +package com.dji.sdk.mqtt; import java.util.Arrays; import java.util.regex.Pattern; -import static com.dji.sample.component.mqtt.model.TopicConst.*; +import static com.dji.sdk.mqtt.TopicConst.*; /** * @author sean * @version 1.3 * @date 2022/10/28 */ -@Getter -public enum DeviceTopicEnum { +public enum CloudApiTopicEnum { STATUS(Pattern.compile("^" + BASIC_PRE + PRODUCT + REGEX_SN + STATUS_SUF + "$"), ChannelName.INBOUND_STATUS), STATE(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + STATE_SUF + "$"), ChannelName.INBOUND_STATE), - SERVICE_REPLY(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + SERVICES_SUF + _REPLY_SUF + "$"), ChannelName.INBOUND_SERVICE_REPLY), + SERVICE_REPLY(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + SERVICES_SUF + _REPLY_SUF + "$"), ChannelName.INBOUND_SERVICES_REPLY), OSD(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + OSD_SUF + "$"), ChannelName.INBOUND_OSD), @@ -29,18 +26,28 @@ public enum DeviceTopicEnum { PROPERTY_SET_REPLY(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + PROPERTY_SUF + SET_SUF + _REPLY_SUF + "$"), ChannelName.INBOUND_PROPERTY_SET_REPLY), + DRC_UP(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + DRC + UP + "$"), ChannelName.INBOUND_DRC_UP), + UNKNOWN(Pattern.compile("^.*$"), ChannelName.DEFAULT); - Pattern pattern; + private final Pattern pattern; - String beanName; + private final String beanName; - DeviceTopicEnum(Pattern pattern, String beanName) { + CloudApiTopicEnum(Pattern pattern, String beanName) { this.pattern = pattern; this.beanName = beanName; } - public static DeviceTopicEnum find(String topic) { - return Arrays.stream(DeviceTopicEnum.values()).filter(topicEnum -> topicEnum.pattern.matcher(topic).matches()).findAny().orElse(UNKNOWN); + public Pattern getPattern() { + return pattern; + } + + public String getBeanName() { + return beanName; + } + + public static CloudApiTopicEnum find(String topic) { + return Arrays.stream(CloudApiTopicEnum.values()).filter(topicEnum -> topicEnum.pattern.matcher(topic).matches()).findAny().orElse(UNKNOWN); } } diff --git a/src/main/java/com/dji/sdk/mqtt/CommonTopicRequest.java b/src/main/java/com/dji/sdk/mqtt/CommonTopicRequest.java new file mode 100644 index 0000000..049394e --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/CommonTopicRequest.java @@ -0,0 +1,71 @@ +package com.dji.sdk.mqtt; + +/** + * Unified topic request format. + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +public class CommonTopicRequest { + + /** + * The command is sent and the response is matched by the tid and bid fields in the message, + * and the reply should keep the tid and bid the same. + */ + protected String tid; + + protected String bid; + + protected Long timestamp; + + protected T data; + + public CommonTopicRequest() { + } + + @Override + public String toString() { + return "CommonTopicRequest{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getTid() { + return tid; + } + + public CommonTopicRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public CommonTopicRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public CommonTopicRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public CommonTopicRequest setData(T data) { + this.data = data; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/CommonTopicResponse.java b/src/main/java/com/dji/sdk/mqtt/CommonTopicResponse.java new file mode 100644 index 0000000..fcbafa0 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/CommonTopicResponse.java @@ -0,0 +1,71 @@ +package com.dji.sdk.mqtt; + +/** + * Unified Topic response format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class CommonTopicResponse { + + /** + * The command is sent and the response is matched by the tid and bid fields in the message, + * and the reply should keep the tid and bid the same. + */ + protected String tid; + + protected String bid; + + protected T data; + + protected Long timestamp; + + @Override + public String toString() { + return "CommonTopicResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public CommonTopicResponse() { + } + + public String getTid() { + return tid; + } + + public CommonTopicResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public CommonTopicResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public T getData() { + return data; + } + + public CommonTopicResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public CommonTopicResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sample/component/mqtt/service/IMqttMessageGateway.java b/src/main/java/com/dji/sdk/mqtt/IMqttMessageGateway.java similarity index 89% rename from src/main/java/com/dji/sample/component/mqtt/service/IMqttMessageGateway.java rename to src/main/java/com/dji/sdk/mqtt/IMqttMessageGateway.java index cb50b12..fb3dbf2 100644 --- a/src/main/java/com/dji/sample/component/mqtt/service/IMqttMessageGateway.java +++ b/src/main/java/com/dji/sdk/mqtt/IMqttMessageGateway.java @@ -1,6 +1,5 @@ -package com.dji.sample.component.mqtt.service; +package com.dji.sdk.mqtt; -import com.dji.sample.component.mqtt.model.ChannelName; import org.springframework.integration.annotation.MessagingGateway; import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.handler.annotation.Header; diff --git a/src/main/java/com/dji/sample/component/mqtt/service/IMqttTopicService.java b/src/main/java/com/dji/sdk/mqtt/IMqttTopicService.java similarity index 74% rename from src/main/java/com/dji/sample/component/mqtt/service/IMqttTopicService.java rename to src/main/java/com/dji/sdk/mqtt/IMqttTopicService.java index 6983109..d5d6027 100644 --- a/src/main/java/com/dji/sample/component/mqtt/service/IMqttTopicService.java +++ b/src/main/java/com/dji/sdk/mqtt/IMqttTopicService.java @@ -1,4 +1,4 @@ -package com.dji.sample.component.mqtt.service; +package com.dji.sdk.mqtt; import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.handler.annotation.Header; @@ -13,9 +13,9 @@ public interface IMqttTopicService { /** * Subscribe to a specific topic. - * @param topic target + * @param topics target */ - void subscribe(@Header(MqttHeaders.TOPIC) String topic); + void subscribe(@Header(MqttHeaders.TOPIC) String... topics); /** * Subscribe to a specific topic using a specific qos. @@ -26,9 +26,9 @@ public interface IMqttTopicService { /** * Unsubscribe from a specific topic. - * @param topic target + * @param topics target */ - void unsubscribe(@Header(MqttHeaders.TOPIC) String topic); + void unsubscribe(@Header(MqttHeaders.TOPIC) String... topics); /** * Get all the subscribed topics. diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/InboundMessageRouter.java b/src/main/java/com/dji/sdk/mqtt/InboundMessageRouter.java similarity index 75% rename from src/main/java/com/dji/sample/component/mqtt/handler/InboundMessageRouter.java rename to src/main/java/com/dji/sdk/mqtt/InboundMessageRouter.java index 8aa9112..4d2a417 100644 --- a/src/main/java/com/dji/sample/component/mqtt/handler/InboundMessageRouter.java +++ b/src/main/java/com/dji/sdk/mqtt/InboundMessageRouter.java @@ -1,9 +1,8 @@ -package com.dji.sample.component.mqtt.handler; +package com.dji.sdk.mqtt; -import com.dji.sample.common.util.SpringBeanUtils; -import com.dji.sample.component.mqtt.model.ChannelName; -import com.dji.sample.component.mqtt.model.DeviceTopicEnum; -import lombok.extern.slf4j.Slf4j; +import com.dji.sdk.common.SpringBeanUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.integration.annotation.Router; import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.integration.router.AbstractMessageRouter; @@ -22,9 +21,10 @@ import java.util.Collections; * @version 0.1 */ @Component -@Slf4j public class InboundMessageRouter extends AbstractMessageRouter { + private static final Logger log = LoggerFactory.getLogger(InboundMessageRouter.class); + /** * All mqtt broker messages will arrive here before distributing them to different channels. * @param message message from mqtt broker @@ -37,9 +37,9 @@ public class InboundMessageRouter extends AbstractMessageRouter { String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString(); byte[] payload = (byte[])message.getPayload(); - log.debug("received topic :{} \t payload :{}", topic, new String(payload)); + log.debug("received topic: {} \t payload =>{}", topic, new String(payload)); - DeviceTopicEnum topicEnum = DeviceTopicEnum.find(topic); + CloudApiTopicEnum topicEnum = CloudApiTopicEnum.find(topic); MessageChannel bean = (MessageChannel) SpringBeanUtils.getBean(topicEnum.getBeanName()); return Collections.singleton(bean); diff --git a/src/main/java/com/dji/sample/component/mqtt/config/MqttInboundConfiguration.java b/src/main/java/com/dji/sdk/mqtt/MqttConfiguration.java similarity index 58% rename from src/main/java/com/dji/sample/component/mqtt/config/MqttInboundConfiguration.java rename to src/main/java/com/dji/sdk/mqtt/MqttConfiguration.java index 40dada5..5855113 100644 --- a/src/main/java/com/dji/sample/component/mqtt/config/MqttInboundConfiguration.java +++ b/src/main/java/com/dji/sdk/mqtt/MqttConfiguration.java @@ -1,22 +1,22 @@ -package com.dji.sample.component.mqtt.config; +package com.dji.sdk.mqtt; -import com.dji.sample.component.mqtt.model.ChannelName; -import com.dji.sample.component.mqtt.model.MqttClientOptions; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.integration.annotation.IntegrationComponentScan; import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.endpoint.MessageProducerSupport; import org.springframework.integration.mqtt.core.MqttPahoClientFactory; import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter; +import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler; import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter; import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHandler; import javax.annotation.Resource; +import java.util.UUID; /** * Client configuration for inbound messages. @@ -24,12 +24,16 @@ import javax.annotation.Resource; * @date 2021/11/10 * @version 0.1 */ -@Slf4j @Configuration @IntegrationComponentScan -public class MqttInboundConfiguration { +public class MqttConfiguration { - @Autowired + private static final Logger log = LoggerFactory.getLogger(MqttConfiguration.class); + + @Value("${cloud-sdk.mqtt.inbound-topic: }") + private String inboundTopic; + + @Resource private MqttPahoClientFactory mqttClientFactory; @Resource(name = ChannelName.INBOUND) @@ -39,12 +43,10 @@ public class MqttInboundConfiguration { * Clients of inbound message channels. * @return */ - @Bean(name = "adapter") - public MessageProducerSupport mqttInbound() { - MqttClientOptions options = MqttConfiguration.getBasicClientOptions(); + @Bean + public MqttPahoMessageDrivenChannelAdapter mqttInbound() { MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter( - options.getClientId() + "_consumer_" + System.currentTimeMillis(), - mqttClientFactory, options.getInboundTopic().split(",")); + UUID.randomUUID().toString(), mqttClientFactory, inboundTopic.split(",")); DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter(); // use byte types uniformly converter.setPayloadAsBytes(true); @@ -54,6 +56,27 @@ public class MqttInboundConfiguration { return adapter; } + /** + * Clients of outbound message channels. + * @return + */ + @Bean + @ServiceActivator(inputChannel = ChannelName.OUTBOUND) + public MessageHandler mqttOutbound() { + MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler( + UUID.randomUUID().toString(), mqttClientFactory); + DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter(); + // use byte types uniformly + converter.setPayloadAsBytes(true); + + messageHandler.setAsync(true); + messageHandler.setDefaultQos(0); + messageHandler.setConverter(converter); + return messageHandler; + } + + + /** * Define a default channel to handle messages that have no effect. * @return @@ -64,8 +87,7 @@ public class MqttInboundConfiguration { return message -> { log.info("The default channel does not handle messages." + "\nTopic: " + message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC) + - "\nPayload: " + message.getPayload()); + "\nPayload: " + message.getPayload() + "\n"); }; } - } diff --git a/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java new file mode 100644 index 0000000..8d60425 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/MqttGatewayPublish.java @@ -0,0 +1,101 @@ +package com.dji.sdk.mqtt; + +import com.dji.sdk.common.Common; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.TypeMismatchException; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.annotation.Resource; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author sean.zhou + * @date 2021/11/16 + * @version 0.1 + */ +@Component +@Slf4j +public class MqttGatewayPublish { + + private static final int DEFAULT_QOS = 0; + public static final int DEFAULT_RETRY_COUNT = 2; + public static final int DEFAULT_RETRY_TIMEOUT = 3000; + + @Resource + private IMqttMessageGateway messageGateway; + + public void publish(String topic, int qos, CommonTopicRequest request) { + try { + log.debug("send topic: {}, payload: {}", topic, request.toString()); + byte[] payload = Common.getObjectMapper().writeValueAsBytes(request); + messageGateway.publish(topic, payload, qos); + } catch (JsonProcessingException e) { + log.error("Failed to publish the message. {}", request.toString()); + e.printStackTrace(); + } + } + + public void publish(String topic, int qos, CommonTopicResponse response) { + try { + log.debug("send topic: {}, payload: {}", topic, response.toString()); + byte[] payload = Common.getObjectMapper().writeValueAsBytes(response); + messageGateway.publish(topic, payload, qos); + } catch (JsonProcessingException e) { + log.error("Failed to publish the message. {}", response.toString()); + e.printStackTrace(); + } + } + + public void publish(String topic, CommonTopicRequest request, int publishCount) { + AtomicInteger time = new AtomicInteger(0); + while (time.getAndIncrement() < publishCount) { + this.publish(topic, DEFAULT_QOS, request); + } + } + + public void publish(String topic, CommonTopicRequest request) { + this.publish(topic, DEFAULT_QOS, request); + } + + public void publishReply(CommonTopicResponse response, MessageHeaders headers) { + this.publish(headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF, 2, response); + } + + public CommonTopicResponse publishWithReply(Class clazz, String topic, CommonTopicRequest request, int retryCount, long timeout) { + AtomicInteger time = new AtomicInteger(0); + boolean hasBid = StringUtils.hasText(request.getBid()); + request.setBid(hasBid ? request.getBid() : UUID.randomUUID().toString()); + // Retry + while (time.getAndIncrement() <= retryCount) { + this.publish(topic, request); + + // If the message is not received in 3 seconds then resend it again. + CommonTopicResponse receiver = Chan.getInstance(request.getTid(), true).get(request.getTid(), timeout); + // Need to match tid and bid. + if (Objects.nonNull(receiver) + && receiver.getTid().equals(request.getTid()) + && receiver.getBid().equals(request.getBid())) { + if (clazz.isAssignableFrom(receiver.getData().getClass())) { + return receiver; + } + throw new TypeMismatchException(receiver.getData(), clazz); + } + // It must be guaranteed that the tid and bid of each message are different. + if (!hasBid) { + request.setBid(UUID.randomUUID().toString()); + } + request.setTid(UUID.randomUUID().toString()); + } + throw new CloudSDKException(CloudSDKErrorEnum.MQTT_PUBLISH_ABNORMAL, "No message reply received."); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/MqttReply.java b/src/main/java/com/dji/sdk/mqtt/MqttReply.java new file mode 100644 index 0000000..bf97ac1 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/MqttReply.java @@ -0,0 +1,73 @@ +package com.dji.sdk.mqtt; + +import com.dji.sdk.common.IErrorInfo; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/13 + */ +public class MqttReply { + + public static final int CODE_ERROR = -1; + + public static final int CODE_SUCCESS = 0; + + private Integer result; + + private T output; + + private MqttReply() { + } + + @Override + public String toString() { + return "MqttReply{" + + "result=" + result + + ", output=" + output + + '}'; + } + + private MqttReply(T output) { + this.output = output; + } + + private MqttReply(Integer result, T output) { + this.result = result; + this.output = output; + } + + public static MqttReply error(IErrorInfo errorInfo) { + return new MqttReply(errorInfo.getCode(), errorInfo.getMessage()); + } + + public static MqttReply error(String message) { + return new MqttReply(CODE_ERROR, message); + } + + public static MqttReply success(T data) { + return new MqttReply(CODE_SUCCESS, data); + } + + public static MqttReply success() { + return new MqttReply().setResult(CODE_SUCCESS); + } + + public Integer getResult() { + return result; + } + + public MqttReply setResult(Integer result) { + this.result = result; + return this; + } + + public MqttReply setOutput(T output) { + this.output = output; + return this; + } + + public T getOutput() { + return output; + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/MqttReplyHandler.java b/src/main/java/com/dji/sdk/mqtt/MqttReplyHandler.java new file mode 100644 index 0000000..f0e3a27 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/MqttReplyHandler.java @@ -0,0 +1,60 @@ +package com.dji.sdk.mqtt; + +import com.dji.sdk.common.BaseModel; +import com.dji.sdk.common.Common; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/22 + */ +@Aspect +@Component +public class MqttReplyHandler { + + @AfterReturning(value = "execution(public com.dji.sdk.mqtt.CommonTopicResponse+ com.dji.sdk.cloudapi.*.api.*.*(com.dji.sdk.mqtt.CommonTopicRequest+, org.springframework.messaging.MessageHeaders))", returning = "result") + public Object validateReturnValue(JoinPoint point, CommonTopicResponse result) { + if (Objects.isNull(result)) { + return null; + } + CommonTopicRequest request = (CommonTopicRequest) point.getArgs()[0]; + result.setBid(request.getBid()).setTid(request.getTid()).setTimestamp(System.currentTimeMillis()); + if (result instanceof TopicEventsResponse) { + fillEvents((TopicEventsResponse) result, (TopicEventsRequest) request); + } else if (result instanceof TopicRequestsResponse) { + validateRequests((TopicRequestsResponse) result, (TopicRequestsRequest) request); + } + return result; + } + + private void fillEvents(TopicEventsResponse response, TopicEventsRequest request) { + if (!request.isNeedReply()) { + response.setData(null); + return; + } + response.setMethod(request.getMethod()).setData(MqttReply.success()); + } + + private void validateRequests(TopicRequestsResponse response, TopicRequestsRequest request) { + response.setMethod(request.getMethod()); + Object data = response.getData(); + if (data instanceof MqttReply) { + MqttReply mqttData = (MqttReply) data; + if (MqttReply.CODE_SUCCESS != mqttData.getResult()) { + return; + } + data = mqttData.getOutput(); + } + Common.validateModel((BaseModel) data); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/MqttTopicServiceImpl.java b/src/main/java/com/dji/sdk/mqtt/MqttTopicServiceImpl.java new file mode 100644 index 0000000..158fa60 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/MqttTopicServiceImpl.java @@ -0,0 +1,57 @@ +package com.dji.sdk.mqtt; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class MqttTopicServiceImpl implements IMqttTopicService { + + private static final Logger log = LoggerFactory.getLogger(MqttTopicServiceImpl.class); + + @Resource + private MqttPahoMessageDrivenChannelAdapter adapter; + + @Override + public void subscribe(String... topics) { + Set topicSet = new HashSet<>(Arrays.asList(getSubscribedTopic())); + for (String topic : topics) { + if (topicSet.contains(topic)) { + return; + } + subscribe(topic, 1); + } + } + + @Override + public void subscribe(String topic, int qos) { + Set topicSet = new HashSet<>(Arrays.asList(getSubscribedTopic())); + if (topicSet.contains(topic)) { + return; + } + log.debug("subscribe topic: {}", topic); + adapter.addTopic(topic, qos); + } + + @Override + public void unsubscribe(String... topics) { + log.debug("unsubscribe topic: {}", Arrays.toString(topics)); + adapter.removeTopic(topics); + } + + public String[] getSubscribedTopic() { + return adapter.getTopic(); + } +} diff --git a/src/main/java/com/dji/sample/component/mqtt/model/TopicConst.java b/src/main/java/com/dji/sdk/mqtt/TopicConst.java similarity index 95% rename from src/main/java/com/dji/sample/component/mqtt/model/TopicConst.java rename to src/main/java/com/dji/sdk/mqtt/TopicConst.java index 9ee3f9a..8b957de 100644 --- a/src/main/java/com/dji/sample/component/mqtt/model/TopicConst.java +++ b/src/main/java/com/dji/sdk/mqtt/TopicConst.java @@ -1,4 +1,4 @@ -package com.dji.sample.component.mqtt.model; +package com.dji.sdk.mqtt; /** * All the topics that need to be used in the project. diff --git a/src/main/java/com/dji/sdk/mqtt/drc/DrcDownPublish.java b/src/main/java/com/dji/sdk/mqtt/drc/DrcDownPublish.java new file mode 100644 index 0000000..25d643b --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/drc/DrcDownPublish.java @@ -0,0 +1,40 @@ +package com.dji.sdk.mqtt.drc; + +import com.dji.sdk.mqtt.MqttGatewayPublish; +import com.dji.sdk.mqtt.TopicConst; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class DrcDownPublish { + + @Resource + private MqttGatewayPublish gatewayPublish; + + public static final int DEFAULT_PUBLISH_COUNT = 5; + + public void publish(String sn, String method) { + this.publish(sn, method, null); + } + + public void publish(String sn, String method, Object data) { + this.publish(sn, method, data, DEFAULT_PUBLISH_COUNT); + } + + public void publish(String sn, String method, Object data, int publishCount) { + String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(sn) + TopicConst.DRC + TopicConst.DOWN; + gatewayPublish.publish(topic, + new TopicDrcRequest<>() + .setMethod(method) + .setData(Objects.requireNonNullElse(data, "")), + publishCount); + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/drc/DrcUpData.java b/src/main/java/com/dji/sdk/mqtt/drc/DrcUpData.java new file mode 100644 index 0000000..ac64f80 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/drc/DrcUpData.java @@ -0,0 +1,44 @@ +package com.dji.sdk.mqtt.drc; + +import com.dji.sdk.cloudapi.wayline.WaylineErrorCodeEnum; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/22 + */ +public class DrcUpData { + + private WaylineErrorCodeEnum result; + + private T output; + + public DrcUpData() { + } + + @Override + public String toString() { + return "DrcUpData{" + + "result=" + result + + ", output=" + output + + '}'; + } + + public WaylineErrorCodeEnum getResult() { + return result; + } + + public DrcUpData setResult(WaylineErrorCodeEnum result) { + this.result = result; + return this; + } + + public T getOutput() { + return output; + } + + public DrcUpData setOutput(T output) { + this.output = output; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/drc/DrcUpMethodEnum.java b/src/main/java/com/dji/sdk/mqtt/drc/DrcUpMethodEnum.java new file mode 100644 index 0000000..979f600 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/drc/DrcUpMethodEnum.java @@ -0,0 +1,59 @@ +package com.dji.sdk.mqtt.drc; + +import com.dji.sdk.cloudapi.control.*; +import com.dji.sdk.mqtt.ChannelName; +import com.fasterxml.jackson.core.type.TypeReference; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +public enum DrcUpMethodEnum { + + DRONE_CONTROL("drone_control", ChannelName.INBOUND_DRC_UP_DRONE_CONTROL, new TypeReference>() {}), + + DRONE_EMERGENCY_STOP("drone_emergency_stop", ChannelName.INBOUND_DRC_UP_DRONE_EMERGENCY_STOP, new TypeReference() {}), + + HEART_BEAT("heart_beat", ChannelName.INBOUND_DRC_UP_HEART_BEAT, new TypeReference() {}), + + HSI_INFO_PUSH("hsi_info_push", ChannelName.INBOUND_DRC_UP_HSI_INFO_PUSH, new TypeReference() {}), + + DELAY_INFO_PUSH("delay_info_push", ChannelName.INBOUND_DRC_UP_DELAY_INFO_PUSH, new TypeReference() {}), + + OSD_INFO_PUSH("osd_info_push", ChannelName.INBOUND_DRC_UP_OSD_INFO_PUSH, new TypeReference() {}), + + UNKNOWN("", ChannelName.DEFAULT, new TypeReference<>() {}); + + private final String method; + + private final String channelName; + + private final TypeReference classType; + + DrcUpMethodEnum(String method, String channelName, TypeReference classType) { + this.method = method; + this.channelName = channelName; + this.classType = classType; + } + + public String getMethod() { + return method; + } + + public String getChannelName() { + return channelName; + } + + public TypeReference getClassType() { + return classType; + } + + public static DrcUpMethodEnum find(String method) { + return Arrays.stream(DrcUpMethodEnum.values()) + .filter(methodEnum -> methodEnum.method.equals(method)) + .findAny().orElse(UNKNOWN); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/drc/DrcUpRouter.java b/src/main/java/com/dji/sdk/mqtt/drc/DrcUpRouter.java new file mode 100644 index 0000000..8648bf8 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/drc/DrcUpRouter.java @@ -0,0 +1,41 @@ +package com.dji.sdk.mqtt.drc; + +import com.dji.sdk.common.Common; +import com.dji.sdk.exception.CloudSDKException; +import com.dji.sdk.mqtt.ChannelName; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.IntegrationFlows; +import org.springframework.messaging.Message; + +import java.io.IOException; +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Configuration +public class DrcUpRouter { + + @Bean + public IntegrationFlow drcUpRouterFlow() { + return IntegrationFlows + .from(ChannelName.INBOUND_DRC_UP) + .transform(Message.class, source -> { + try { + TopicDrcRequest data = Common.getObjectMapper().readValue((byte[]) source.getPayload(), TopicDrcRequest.class); + return data.setData(Common.getObjectMapper().convertValue(data.getData(), DrcUpMethodEnum.find(data.getMethod()).getClassType())); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }, null) + .route( + response -> DrcUpMethodEnum.find(response.getMethod()), + mapping -> Arrays.stream(DrcUpMethodEnum.values()).forEach( + methodEnum -> mapping.channelMapping(methodEnum, methodEnum.getChannelName()))) + .get(); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/drc/DrcUpSubscribe.java b/src/main/java/com/dji/sdk/mqtt/drc/DrcUpSubscribe.java new file mode 100644 index 0000000..cbb85ba --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/drc/DrcUpSubscribe.java @@ -0,0 +1,26 @@ +package com.dji.sdk.mqtt.drc; + +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.mqtt.IMqttTopicService; +import com.dji.sdk.mqtt.TopicConst; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class DrcUpSubscribe { + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway) { + String drc = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.DRC + TopicConst.UP; + topicService.subscribe(String.format(drc, gateway.getGatewaySn())); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/drc/TopicDrcRequest.java b/src/main/java/com/dji/sdk/mqtt/drc/TopicDrcRequest.java new file mode 100644 index 0000000..f6f092a --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/drc/TopicDrcRequest.java @@ -0,0 +1,73 @@ +package com.dji.sdk.mqtt.drc; + +import com.dji.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicDrcRequest extends CommonTopicRequest { + + private String method; + + public TopicDrcRequest() { + } + + @Override + public String toString() { + return "TopicDrcRequest{" + + "method='" + method + '\'' + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getMethod() { + return method; + } + + public TopicDrcRequest setMethod(String method) { + this.method = method; + return this; + } + + public String getTid() { + return tid; + } + + public TopicDrcRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicDrcRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicDrcRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicDrcRequest setData(T data) { + this.data = data; + return this; + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/drc/TopicDrcResponse.java b/src/main/java/com/dji/sdk/mqtt/drc/TopicDrcResponse.java new file mode 100644 index 0000000..2728890 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/drc/TopicDrcResponse.java @@ -0,0 +1,73 @@ +package com.dji.sdk.mqtt.drc; + +import com.dji.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicDrcResponse extends CommonTopicResponse { + + private String method; + + @Override + public String toString() { + return "TopicDrcResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", method='" + method + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicDrcResponse() { + } + + public String getTid() { + return tid; + } + + public TopicDrcResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicDrcResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public String getMethod() { + return method; + } + + public TopicDrcResponse setMethod(String method) { + this.method = method; + return this; + } + + public T getData() { + return data; + } + + public TopicDrcResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicDrcResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/events/EventsDataRequest.java b/src/main/java/com/dji/sdk/mqtt/events/EventsDataRequest.java new file mode 100644 index 0000000..581270c --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/events/EventsDataRequest.java @@ -0,0 +1,42 @@ +package com.dji.sdk.mqtt.events; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +public class EventsDataRequest { + + private EventsErrorCode result; + + private T output; + + public EventsDataRequest() { + } + + @Override + public String toString() { + return "EventsDataRequest{" + + "result=" + result + + ", output=" + output + + '}'; + } + + public EventsErrorCode getResult() { + return result; + } + + public EventsDataRequest setResult(EventsErrorCode result) { + this.result = result; + return this; + } + + public T getOutput() { + return output; + } + + public EventsDataRequest setOutput(T output) { + this.output = output; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/events/EventsErrorCode.java b/src/main/java/com/dji/sdk/mqtt/events/EventsErrorCode.java new file mode 100644 index 0000000..a969ec0 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/events/EventsErrorCode.java @@ -0,0 +1,88 @@ +package com.dji.sdk.mqtt.events; + +import com.dji.sdk.cloudapi.control.ControlErrorCodeEnum; +import com.dji.sdk.cloudapi.debug.DebugErrorCodeEnum; +import com.dji.sdk.cloudapi.firmware.FirmwareErrorCodeEnum; +import com.dji.sdk.cloudapi.log.LogErrorCodeEnum; +import com.dji.sdk.cloudapi.wayline.WaylineErrorCodeEnum; +import com.dji.sdk.common.CommonErrorEnum; +import com.dji.sdk.common.ErrorCodeSourceEnum; +import com.dji.sdk.common.IErrorInfo; +import com.dji.sdk.mqtt.MqttReply; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/14 + */ +public class EventsErrorCode implements IErrorInfo { + + private static final int MOD = 100_000; + + private ErrorCodeSourceEnum source; + + private IEventsErrorCode errorCode; + + private boolean success; + + private Integer sourceCode; + + @Override + public String toString() { + return "{" + + "errorCode=" + getCode() + + ", errorMsg=" + getMessage() + + '}'; + } + + @JsonCreator + public EventsErrorCode(int code) { + this.sourceCode = code; + if (MqttReply.CODE_SUCCESS == code) { + this.success = true; + return; + } + this.source = ErrorCodeSourceEnum.find(code / MOD); + this.errorCode = DebugErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = ControlErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = LogErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = FirmwareErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = WaylineErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = CommonErrorEnum.find(code); + } + + @Override + public String getMessage() { + return errorCode.getMessage(); + } + + @JsonValue + public Integer getCode() { + return sourceCode; + } + + public boolean isSuccess() { + return success; + } + + public ErrorCodeSourceEnum getSource() { + return source; + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/events/EventsMethodEnum.java b/src/main/java/com/dji/sdk/mqtt/events/EventsMethodEnum.java new file mode 100644 index 0000000..92ca2d8 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/events/EventsMethodEnum.java @@ -0,0 +1,105 @@ +package com.dji.sdk.mqtt.events; + +import com.dji.sdk.cloudapi.control.DrcStatusNotify; +import com.dji.sdk.cloudapi.control.FlyToPointProgress; +import com.dji.sdk.cloudapi.control.JoystickInvalidNotify; +import com.dji.sdk.cloudapi.control.TakeoffToPointProgress; +import com.dji.sdk.cloudapi.debug.RemoteDebugProgress; +import com.dji.sdk.cloudapi.firmware.OtaProgress; +import com.dji.sdk.cloudapi.hms.Hms; +import com.dji.sdk.cloudapi.log.FileUploadProgress; +import com.dji.sdk.cloudapi.media.FileUploadCallback; +import com.dji.sdk.cloudapi.media.HighestPriorityUploadFlightTaskMedia; +import com.dji.sdk.cloudapi.wayline.DeviceExitHomingNotify; +import com.dji.sdk.cloudapi.wayline.FlighttaskProgress; +import com.dji.sdk.cloudapi.wayline.FlighttaskReady; +import com.dji.sdk.mqtt.ChannelName; +import com.fasterxml.jackson.core.type.TypeReference; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +public enum EventsMethodEnum { + + FLIGHTTASK_PROGRESS("flighttask_progress", ChannelName.INBOUND_EVENTS_FLIGHTTASK_PROGRESS, new TypeReference>() {}), + + DEVICE_EXIT_HOMING_NOTIFY("device_exit_homing_notify", ChannelName.INBOUND_EVENTS_DEVICE_EXIT_HOMING_NOTIFY, new TypeReference() {}), + + FILE_UPLOAD_CALLBACK("file_upload_callback", ChannelName.INBOUND_EVENTS_FILE_UPLOAD_CALLBACK, new TypeReference() {}), + + HMS("hms", ChannelName.INBOUND_EVENTS_HMS, new TypeReference() {}), + + DEVICE_REBOOT("device_reboot", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + DRONE_OPEN("drone_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + DRONE_CLOSE("drone_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + DRONE_FORMAT("drone_format", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + DEVICE_FORMAT("device_format", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + COVER_OPEN("cover_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + COVER_CLOSE("cover_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + PUTTER_OPEN("putter_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + PUTTER_CLOSE("putter_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + CHARGE_OPEN("charge_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + CHARGE_CLOSE("charge_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + OTA_PROGRESS("ota_progress", ChannelName.INBOUND_EVENTS_OTA_PROGRESS, new TypeReference>() {}), + + FILE_UPLOAD_PROGRESS("fileupload_progress", ChannelName.INBOUND_EVENTS_FILEUPLOAD_PROGRESS, new TypeReference>() {}), + + HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA("highest_priority_upload_flighttask_media", ChannelName.INBOUND_EVENTS_HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA, new TypeReference() {}), + + FLIGHT_TASK_READY("flighttask_ready", ChannelName.INBOUND_EVENTS_FLIGHTTASK_READY, new TypeReference() {}), + + FLY_TO_POINT_PROGRESS("fly_to_point_progress", ChannelName.INBOUND_EVENTS_FLY_TO_POINT_PROGRESS, new TypeReference() {}), + + TAKE_OFF_TO_POINT_PROGRESS("takeoff_to_point_progress", ChannelName.INBOUND_EVENTS_TAKEOFF_TO_POINT_PROGRESS, new TypeReference() {}), + + DRC_STATUS_NOTIFY("drc_status_notify", ChannelName.INBOUND_EVENTS_DRC_STATUS_NOTIFY, new TypeReference() {}), + + JOYSTICK_INVALID_NOTIFY("joystick_invalid_notify", ChannelName.INBOUND_EVENTS_JOYSTICK_INVALID_NOTIFY, new TypeReference() {}), + + UNKNOWN("", ChannelName.DEFAULT, new TypeReference<>() {}); + + private final String method; + + private final String channelName; + + private final TypeReference classType; + + EventsMethodEnum(String method, String channelName, TypeReference classType) { + this.method = method; + this.channelName = channelName; + this.classType = classType; + } + + public String getMethod() { + return method; + } + + public String getChannelName() { + return channelName; + } + + public TypeReference getClassType() { + return classType; + } + + public static EventsMethodEnum find(String method) { + return Arrays.stream(EventsMethodEnum.values()) + .filter(methodEnum -> methodEnum.method.equals(method)) + .findAny().orElse(UNKNOWN); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/events/EventsRouter.java b/src/main/java/com/dji/sdk/mqtt/events/EventsRouter.java new file mode 100644 index 0000000..0a6d50d --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/events/EventsRouter.java @@ -0,0 +1,71 @@ +package com.dji.sdk.mqtt.events; + +import com.dji.sdk.common.Common; +import com.dji.sdk.exception.CloudSDKException; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.MqttGatewayPublish; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.IntegrationFlows; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import javax.annotation.Resource; +import java.io.IOException; +import java.util.Arrays; +import java.util.Objects; + +import static com.dji.sdk.mqtt.TopicConst.*; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Configuration +public class EventsRouter { + + @Resource + private MqttGatewayPublish gatewayPublish; + + @Bean + public IntegrationFlow eventsMethodRouterFlow() { + return IntegrationFlows + .from(ChannelName.INBOUND_EVENTS) + .transform(Message.class, source -> { + try { + TopicEventsRequest data = Common.getObjectMapper().readValue((byte[]) source.getPayload(), TopicEventsRequest.class); + String topic = String.valueOf(source.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)); + return data.setFrom(topic.substring((THING_MODEL_PRE + PRODUCT).length(), topic.indexOf(EVENTS_SUF))) + .setData(Common.getObjectMapper().convertValue(data.getData(), EventsMethodEnum.find(data.getMethod()).getClassType())); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }, null) + .route( + response -> EventsMethodEnum.find(response.getMethod()), + mapping -> Arrays.stream(EventsMethodEnum.values()).forEach( + methodEnum -> mapping.channelMapping(methodEnum, methodEnum.getChannelName()))) + .get(); + } + + @Bean + public IntegrationFlow replySuccessEvents() { + return IntegrationFlows + .from(ChannelName.OUTBOUND_EVENTS) + .handle(this::publish) + .nullChannel(); + + } + + private TopicEventsResponse publish(TopicEventsResponse request, MessageHeaders headers) { + if (Objects.isNull(request) || Objects.isNull(request.getData())) { + return null; + } + gatewayPublish.publishReply(request, headers); + return request; + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/events/EventsSubscribe.java b/src/main/java/com/dji/sdk/mqtt/events/EventsSubscribe.java new file mode 100644 index 0000000..84cffff --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/events/EventsSubscribe.java @@ -0,0 +1,41 @@ +package com.dji.sdk.mqtt.events; + +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.mqtt.IMqttTopicService; +import com.dji.sdk.mqtt.TopicConst; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class EventsSubscribe { + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.EVENTS_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway, boolean unsubscribeSubDevice) { + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (unsubscribeSubDevice) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + return; + } + if (null != gateway.getDroneSn()) { + topicService.subscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } + + public void unsubscribe(GatewayManager gateway) { + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (null != gateway.getDroneSn()) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/events/IEventsErrorCode.java b/src/main/java/com/dji/sdk/mqtt/events/IEventsErrorCode.java new file mode 100644 index 0000000..9377743 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/events/IEventsErrorCode.java @@ -0,0 +1,22 @@ +package com.dji.sdk.mqtt.events; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public interface IEventsErrorCode { + + /** + * Get error message. + * @return error message + */ + String getMessage(); + + /** + * Get error code. + * @return error code + */ + Integer getCode(); + +} diff --git a/src/main/java/com/dji/sdk/mqtt/events/TopicEventsRequest.java b/src/main/java/com/dji/sdk/mqtt/events/TopicEventsRequest.java new file mode 100644 index 0000000..d519527 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/events/TopicEventsRequest.java @@ -0,0 +1,108 @@ +package com.dji.sdk.mqtt.events; + +import com.dji.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicEventsRequest extends CommonTopicRequest { + + private String method; + + private String gateway; + + private String from; + + private boolean needReply; + + public TopicEventsRequest() { + } + + @Override + public String toString() { + return "TopicRequestsRequest{" + + "method='" + method + '\'' + + ", gateway='" + gateway + '\'' + + ", from='" + from + '\'' + + ", needReply=" + needReply + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getTid() { + return tid; + } + + public TopicEventsRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicEventsRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicEventsRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicEventsRequest setData(T data) { + this.data = data; + return this; + } + + public String getGateway() { + return gateway; + } + + public TopicEventsRequest setGateway(String gateway) { + this.gateway = gateway; + return this; + } + + public String getFrom() { + return from; + } + + public TopicEventsRequest setFrom(String from) { + this.from = from; + return this; + } + + public boolean isNeedReply() { + return needReply; + } + + public TopicEventsRequest setNeedReply(boolean needReply) { + this.needReply = needReply; + return this; + } + + public String getMethod() { + return method; + } + + public TopicEventsRequest setMethod(String method) { + this.method = method; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/events/TopicEventsResponse.java b/src/main/java/com/dji/sdk/mqtt/events/TopicEventsResponse.java new file mode 100644 index 0000000..682d0cf --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/events/TopicEventsResponse.java @@ -0,0 +1,73 @@ +package com.dji.sdk.mqtt.events; + +import com.dji.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicEventsResponse extends CommonTopicResponse { + + private String method; + + @Override + public String toString() { + return "TopicEventsResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", method='" + method + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicEventsResponse() { + } + + public String getTid() { + return tid; + } + + public TopicEventsResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicEventsResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public String getMethod() { + return method; + } + + public TopicEventsResponse setMethod(String method) { + this.method = method; + return this; + } + + public T getData() { + return data; + } + + public TopicEventsResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicEventsResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/osd/OsdDeviceTypeEnum.java b/src/main/java/com/dji/sdk/mqtt/osd/OsdDeviceTypeEnum.java new file mode 100644 index 0000000..bc5c8cc --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/osd/OsdDeviceTypeEnum.java @@ -0,0 +1,68 @@ +package com.dji.sdk.mqtt.osd; + +import com.dji.sdk.cloudapi.device.OsdDock; +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.device.OsdRcDrone; +import com.dji.sdk.cloudapi.device.OsdRemoteControl; +import com.dji.sdk.common.GatewayTypeEnum; +import com.dji.sdk.exception.CloudSDKException; +import com.dji.sdk.mqtt.ChannelName; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/29 + */ +public enum OsdDeviceTypeEnum { + + RC(true, GatewayTypeEnum.RC, OsdRemoteControl.class, ChannelName.INBOUND_OSD_RC), + + DOCK(true, GatewayTypeEnum.DOCK, OsdDock.class, ChannelName.INBOUND_OSD_DOCK), + + RC_DRONE(false, GatewayTypeEnum.RC, OsdRcDrone.class, ChannelName.INBOUND_OSD_RC_DRONE), + + DOCK_DRONE(false, GatewayTypeEnum.DOCK, OsdDockDrone.class, ChannelName.INBOUND_OSD_DOCK_DRONE); + + private final boolean gateway; + + private final GatewayTypeEnum gatewayType; + + private final Class classType; + + private final String channelName; + + OsdDeviceTypeEnum(boolean gateway, GatewayTypeEnum gatewayType, Class classType, String channelName) { + this.gateway = gateway; + this.gatewayType = gatewayType; + this.classType = classType; + this.channelName = channelName; + } + + public GatewayTypeEnum getGatewayType() { + return gatewayType; + } + + public boolean isGateway() { + return gateway; + } + + public Class getClassType() { + return classType; + } + + public String getChannelName() { + return channelName; + } + + public static OsdDeviceTypeEnum find(GatewayTypeEnum gatewayType, boolean isGateway) { + return Arrays.stream(values()).filter(osdEnum -> osdEnum.gatewayType == gatewayType && osdEnum.gateway == isGateway).findAny() + .orElseThrow(() -> new CloudSDKException(OsdDeviceTypeEnum.class, gatewayType, isGateway)); + } + + public static OsdDeviceTypeEnum find(Class classType) { + return Arrays.stream(values()).filter(type -> type.classType == classType).findAny() + .orElseThrow(() -> new CloudSDKException(OsdDeviceTypeEnum.class, classType)); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/osd/OsdRouter.java b/src/main/java/com/dji/sdk/mqtt/osd/OsdRouter.java new file mode 100644 index 0000000..87f5282 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/osd/OsdRouter.java @@ -0,0 +1,64 @@ +package com.dji.sdk.mqtt.osd; + +import com.dji.sdk.cloudapi.device.PayloadModelEnum; +import com.dji.sdk.common.Common; +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.exception.CloudSDKException; +import com.dji.sdk.mqtt.ChannelName; +import com.fasterxml.jackson.core.type.TypeReference; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.IntegrationFlows; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.Message; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static com.dji.sdk.mqtt.TopicConst.*; + +/** + * + * @author sean.zhou + * @date 2021/11/17 + * @version 0.1 + */ +@Configuration +public class OsdRouter { + + @Bean + public IntegrationFlow osdRouterFlow() { + return IntegrationFlows + .from(ChannelName.INBOUND_OSD) + .transform(Message.class, source -> { + try { + TopicOsdRequest response = Common.getObjectMapper().readValue((byte[]) source.getPayload(), new TypeReference() {}); + String topic = String.valueOf(source.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)); + return response.setFrom(topic.substring((THING_MODEL_PRE + PRODUCT).length(), topic.indexOf(OSD_SUF))); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }, null) + .handle((response, headers) -> { + GatewayManager gateway = SDKManager.getDeviceSDK(response.getGateway()); + OsdDeviceTypeEnum typeEnum = OsdDeviceTypeEnum.find(gateway.getType(), response.getFrom().equals(response.getGateway())); + Map data = (Map) response.getData(); + if (!typeEnum.isGateway()) { + List payloadData = (List) data.getOrDefault(PayloadModelEnum.PAYLOAD_KEY, new ArrayList<>()); + PayloadModelEnum.getAllIndexWithPosition().stream().filter(data::containsKey) + .map(data::get).forEach(payloadData::add); + data.put(PayloadModelEnum.PAYLOAD_KEY, payloadData); + } + return response.setData(Common.getObjectMapper().convertValue(data, typeEnum.getClassType())); + }) + .route(response -> OsdDeviceTypeEnum.find(response.getData().getClass()), + mapping -> Arrays.stream(OsdDeviceTypeEnum.values()).forEach(key -> mapping.channelMapping(key, key.getChannelName()))) + .get(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/osd/OsdSubscribe.java b/src/main/java/com/dji/sdk/mqtt/osd/OsdSubscribe.java new file mode 100644 index 0000000..bc359b2 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/osd/OsdSubscribe.java @@ -0,0 +1,44 @@ +package com.dji.sdk.mqtt.osd; + +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.IMqttTopicService; +import com.dji.sdk.mqtt.TopicConst; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class OsdSubscribe { + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.OSD_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway, boolean unsubscribeSubDevice) { + SDKManager.registerDevice(gateway); + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (unsubscribeSubDevice) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + return; + } + if (null != gateway.getDroneSn()) { + topicService.subscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } + + public void unsubscribe(GatewayManager gateway) { + SDKManager.logoutDevice(gateway.getGatewaySn()); + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (null != gateway.getDroneSn()) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/osd/TopicOsdRequest.java b/src/main/java/com/dji/sdk/mqtt/osd/TopicOsdRequest.java new file mode 100644 index 0000000..be4df6e --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/osd/TopicOsdRequest.java @@ -0,0 +1,83 @@ +package com.dji.sdk.mqtt.osd; + +import com.dji.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicOsdRequest extends CommonTopicRequest { + + private String gateway; + + private String from; + + public TopicOsdRequest() { + } + + @Override + public String toString() { + return "TopicOsdRequest{" + + "gateway='" + gateway + '\'' + + ", from='" + from + '\'' + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + public String getTid() { + return tid; + } + + public TopicOsdRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicOsdRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicOsdRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicOsdRequest setData(T data) { + this.data = data; + return this; + } + + public String getGateway() { + return gateway; + } + + public TopicOsdRequest setGateway(String gateway) { + this.gateway = gateway; + return this; + } + + public String getFrom() { + return from; + } + + public TopicOsdRequest setFrom(String from) { + this.from = from; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/property/PropertySetPublish.java b/src/main/java/com/dji/sdk/mqtt/property/PropertySetPublish.java new file mode 100644 index 0000000..3426a85 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/property/PropertySetPublish.java @@ -0,0 +1,40 @@ +package com.dji.sdk.mqtt.property; + +import com.dji.sdk.mqtt.MqttGatewayPublish; +import com.dji.sdk.mqtt.TopicConst; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Objects; +import java.util.UUID; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class PropertySetPublish { + + @Resource + private MqttGatewayPublish gatewayPublish; + + public PropertySetReplyResultEnum publish(String sn, Object data) { + return this.publish(sn, data, MqttGatewayPublish.DEFAULT_RETRY_COUNT); + } + + public PropertySetReplyResultEnum publish(String sn, Object data, int retryCount) { + return this.publish(sn, data, retryCount, MqttGatewayPublish.DEFAULT_RETRY_TIMEOUT); + } + + public PropertySetReplyResultEnum publish(String sn, Object data, int retryCount, long timeout) { + String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(sn) + TopicConst.PROPERTY_SUF + TopicConst.SET_SUF; + return gatewayPublish.publishWithReply( + PropertySetReplyResultEnum.class, topic, new TopicPropertySetRequest<>() + .setTid(UUID.randomUUID().toString()) + .setBid(null) + .setTimestamp(System.currentTimeMillis()) + .setData(Objects.requireNonNull(data)), retryCount, timeout).getData(); + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyHandler.java b/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyHandler.java new file mode 100644 index 0000000..1723e22 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyHandler.java @@ -0,0 +1,44 @@ +package com.dji.sdk.mqtt.property; + +import com.dji.sdk.common.Common; +import com.dji.sdk.mqtt.Chan; +import com.dji.sdk.mqtt.ChannelName; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.Objects; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +@Component +public class PropertySetReplyHandler { + + private static final String RESULT_KEY = "result"; + + /** + * Handle the reply message from topic "/property/set_reply". + * @param message reply message + * @throws IOException + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_PROPERTY_SET_REPLY) + public void propertySetReply(Message message) throws IOException { + byte[] payload = (byte[])message.getPayload(); + + TopicPropertySetResponse receiver = Common.getObjectMapper().readValue(payload, new TypeReference() {}); + Chan chan = Chan.getInstance(receiver.getTid(), false); + if (Objects.isNull(chan)) { + return; + } + receiver.setData(PropertySetReplyResultEnum.find( + Common.getObjectMapper().convertValue(receiver.getData(), JsonNode.class).findValue(RESULT_KEY).intValue())); + // Put the message to the chan object. + chan.put(receiver); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyResultEnum.java b/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyResultEnum.java new file mode 100644 index 0000000..8a17339 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/property/PropertySetReplyResultEnum.java @@ -0,0 +1,38 @@ +package com.dji.sdk.mqtt.property; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/28 + */ +public enum PropertySetReplyResultEnum { + + SUCCESS(0), + + FAILED(1), + + TIMEOUT(2), + + UNKNOWN(-1); + + private final int result; + + PropertySetReplyResultEnum(int result) { + this.result = result; + } + + @JsonValue + public int getResult() { + return result; + } + + @JsonCreator + public static PropertySetReplyResultEnum find(int result) { + return Arrays.stream(values()).filter(resultEnum -> resultEnum.result == result).findAny().orElse(UNKNOWN); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/property/PropertySetSubscribe.java b/src/main/java/com/dji/sdk/mqtt/property/PropertySetSubscribe.java new file mode 100644 index 0000000..6bcd266 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/property/PropertySetSubscribe.java @@ -0,0 +1,30 @@ +package com.dji.sdk.mqtt.property; + +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.mqtt.IMqttTopicService; +import com.dji.sdk.mqtt.TopicConst; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class PropertySetSubscribe { + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.PROPERTY_SUF + TopicConst.SET_SUF + TopicConst._REPLY_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway) { + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + + public void unsubscribe(GatewayManager gateway) { + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/property/TopicPropertySetRequest.java b/src/main/java/com/dji/sdk/mqtt/property/TopicPropertySetRequest.java new file mode 100644 index 0000000..30f2950 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/property/TopicPropertySetRequest.java @@ -0,0 +1,61 @@ +package com.dji.sdk.mqtt.property; + +import com.dji.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicPropertySetRequest extends CommonTopicRequest { + + public TopicPropertySetRequest() { + } + + @Override + public String toString() { + return "TopicPropertySetRequest{" + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getTid() { + return tid; + } + + public TopicPropertySetRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicPropertySetRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicPropertySetRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicPropertySetRequest setData(T data) { + this.data = data; + return this; + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/property/TopicPropertySetResponse.java b/src/main/java/com/dji/sdk/mqtt/property/TopicPropertySetResponse.java new file mode 100644 index 0000000..1844cf8 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/property/TopicPropertySetResponse.java @@ -0,0 +1,61 @@ +package com.dji.sdk.mqtt.property; + +import com.dji.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicPropertySetResponse extends CommonTopicResponse { + + @Override + public String toString() { + return "TopicPropertySetResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicPropertySetResponse() { + } + + public String getTid() { + return tid; + } + + public TopicPropertySetResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicPropertySetResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public T getData() { + return data; + } + + public TopicPropertySetResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicPropertySetResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/requests/RequestsMethodEnum.java b/src/main/java/com/dji/sdk/mqtt/requests/RequestsMethodEnum.java new file mode 100644 index 0000000..40e79a4 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/requests/RequestsMethodEnum.java @@ -0,0 +1,63 @@ +package com.dji.sdk.mqtt.requests; + +import com.dji.sdk.cloudapi.config.RequestsConfigRequest; +import com.dji.sdk.cloudapi.media.StorageConfigGet; +import com.dji.sdk.cloudapi.organization.AirportBindStatusRequest; +import com.dji.sdk.cloudapi.organization.AirportOrganizationBindRequest; +import com.dji.sdk.cloudapi.organization.AirportOrganizationGetRequest; +import com.dji.sdk.cloudapi.wayline.FlighttaskResourceGetRequest; +import com.dji.sdk.mqtt.ChannelName; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/25 + */ +public enum RequestsMethodEnum { + + STORAGE_CONFIG_GET("storage_config_get", ChannelName.INBOUND_REQUESTS_STORAGE_CONFIG_GET, StorageConfigGet.class), + + AIRPORT_BIND_STATUS("airport_bind_status", ChannelName.INBOUND_REQUESTS_AIRPORT_BIND_STATUS, AirportBindStatusRequest.class), + + AIRPORT_ORGANIZATION_BIND("airport_organization_bind", ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_BIND, AirportOrganizationBindRequest.class), + + AIRPORT_ORGANIZATION_GET("airport_organization_get", ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET, AirportOrganizationGetRequest.class), + + FLIGHT_TASK_RESOURCE_GET("flighttask_resource_get", ChannelName.INBOUND_REQUESTS_FLIGHTTASK_RESOURCE_GET, FlighttaskResourceGetRequest.class), + + CONFIG("config", ChannelName.INBOUND_REQUESTS_CONFIG, RequestsConfigRequest.class), + + UNKNOWN("", ChannelName.DEFAULT, Object.class); + + private final String method; + + private final String channelName; + + private final Class classType; + + RequestsMethodEnum(String method, String channelName, Class classType) { + this.method = method; + this.channelName = channelName; + this.classType = classType; + } + + public String getMethod() { + return method; + } + + public String getChannelName() { + return channelName; + } + + public Class getClassType() { + return classType; + } + + public static RequestsMethodEnum find(String method) { + return Arrays.stream(RequestsMethodEnum.values()) + .filter(methodEnum -> methodEnum.method.equals(method)) + .findAny().orElse(UNKNOWN); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/requests/RequestsRouter.java b/src/main/java/com/dji/sdk/mqtt/requests/RequestsRouter.java new file mode 100644 index 0000000..045afcd --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/requests/RequestsRouter.java @@ -0,0 +1,64 @@ +package com.dji.sdk.mqtt.requests; + +import com.dji.sdk.common.Common; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.MqttGatewayPublish; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.IntegrationFlows; +import org.springframework.messaging.MessageHeaders; + +import javax.annotation.Resource; +import java.io.IOException; +import java.util.Arrays; +import java.util.Objects; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/25 + */ +@Configuration +public class RequestsRouter { + + @Resource + private MqttGatewayPublish gatewayPublish; + + @Bean + public IntegrationFlow requestsMethodRouterFlow() { + return IntegrationFlows + .from(ChannelName.INBOUND_REQUESTS) + .transform(payload -> { + try { + TopicRequestsRequest response = Common.getObjectMapper().readValue(payload, TopicRequestsRequest.class); + return response.setData(Common.getObjectMapper().convertValue(response.getData(), RequestsMethodEnum.find(response.getMethod()).getClassType())); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }) + .route( + receiver -> RequestsMethodEnum.find(receiver.getMethod()), + mapping -> Arrays.stream(RequestsMethodEnum.values()).forEach( + methodEnum -> mapping.channelMapping(methodEnum, methodEnum.getChannelName()))) + .get(); + } + + @Bean + public IntegrationFlow replyRequestsMethod() { + return IntegrationFlows + .from(ChannelName.OUTBOUND_REQUESTS) + .handle(this::publish) + .nullChannel(); + } + + private TopicRequestsResponse publish(TopicRequestsResponse request, MessageHeaders headers) { + if (Objects.isNull(request)) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, "The return value cannot be null."); + } + gatewayPublish.publishReply(request, headers); + return request; + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/requests/RequestsSubscribe.java b/src/main/java/com/dji/sdk/mqtt/requests/RequestsSubscribe.java new file mode 100644 index 0000000..6f520fc --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/requests/RequestsSubscribe.java @@ -0,0 +1,34 @@ +package com.dji.sdk.mqtt.requests; + +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.mqtt.IMqttTopicService; +import com.dji.sdk.mqtt.TopicConst; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class RequestsSubscribe { + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.REQUESTS_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway) { + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + + public void unsubscribe(GatewayManager gateway) { + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + + public void subscribeWildcardsRequests() { + topicService.subscribe(TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "+" + TopicConst.REQUESTS_SUF); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/requests/TopicRequestsRequest.java b/src/main/java/com/dji/sdk/mqtt/requests/TopicRequestsRequest.java new file mode 100644 index 0000000..1cd659e --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/requests/TopicRequestsRequest.java @@ -0,0 +1,84 @@ +package com.dji.sdk.mqtt.requests; + +import com.dji.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicRequestsRequest extends CommonTopicRequest { + + private String method; + + private String gateway; + + public TopicRequestsRequest() { + } + + @Override + public String toString() { + return "TopicRequestsRequest{" + + "method='" + method + '\'' + + ", gateway='" + gateway + '\'' + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getTid() { + return tid; + } + + public TopicRequestsRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicRequestsRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicRequestsRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicRequestsRequest setData(T data) { + this.data = data; + return this; + } + + public String getGateway() { + return gateway; + } + + public TopicRequestsRequest setGateway(String gateway) { + this.gateway = gateway; + return this; + } + + public String getMethod() { + return method; + } + + public TopicRequestsRequest setMethod(String method) { + this.method = method; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/requests/TopicRequestsResponse.java b/src/main/java/com/dji/sdk/mqtt/requests/TopicRequestsResponse.java new file mode 100644 index 0000000..37fd816 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/requests/TopicRequestsResponse.java @@ -0,0 +1,73 @@ +package com.dji.sdk.mqtt.requests; + +import com.dji.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicRequestsResponse extends CommonTopicResponse { + + private String method; + + @Override + public String toString() { + return "TopicRequestsResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", method='" + method + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicRequestsResponse() { + } + + public String getTid() { + return tid; + } + + public TopicRequestsResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicRequestsResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public String getMethod() { + return method; + } + + public TopicRequestsResponse setMethod(String method) { + this.method = method; + return this; + } + + public T getData() { + return data; + } + + public TopicRequestsResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicRequestsResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/services/IServicesErrorCode.java b/src/main/java/com/dji/sdk/mqtt/services/IServicesErrorCode.java new file mode 100644 index 0000000..810c1b7 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/services/IServicesErrorCode.java @@ -0,0 +1,22 @@ +package com.dji.sdk.mqtt.services; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public interface IServicesErrorCode { + + /** + * Get error message. + * @return error message + */ + String getMessage(); + + /** + * Get error code. + * @return error code + */ + Integer getCode(); + +} diff --git a/src/main/java/com/dji/sdk/mqtt/services/ServicesErrorCode.java b/src/main/java/com/dji/sdk/mqtt/services/ServicesErrorCode.java new file mode 100644 index 0000000..bea7e92 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/services/ServicesErrorCode.java @@ -0,0 +1,93 @@ +package com.dji.sdk.mqtt.services; + +import com.dji.sdk.cloudapi.control.ControlErrorCodeEnum; +import com.dji.sdk.cloudapi.debug.DebugErrorCodeEnum; +import com.dji.sdk.cloudapi.firmware.FirmwareErrorCodeEnum; +import com.dji.sdk.cloudapi.livestream.LiveErrorCodeEnum; +import com.dji.sdk.cloudapi.log.LogErrorCodeEnum; +import com.dji.sdk.cloudapi.wayline.WaylineErrorCodeEnum; +import com.dji.sdk.common.CommonErrorEnum; +import com.dji.sdk.common.ErrorCodeSourceEnum; +import com.dji.sdk.common.IErrorInfo; +import com.dji.sdk.mqtt.MqttReply; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/14 + */ +public class ServicesErrorCode implements IErrorInfo { + + private static final int MOD = 100_000; + + private ErrorCodeSourceEnum source; + + private IServicesErrorCode errorCode; + + private boolean success; + + private Integer sourceCode; + + @Override + public String toString() { + return "{" + + "errorCode=" + getCode() + + ", errorMsg=" + getMessage() + + '}'; + } + + @JsonCreator + public ServicesErrorCode(int code) { + this.sourceCode = code; + if (MqttReply.CODE_SUCCESS == code) { + this.success = true; + return; + } + this.source = ErrorCodeSourceEnum.find(code / MOD); + this.errorCode = LiveErrorCodeEnum.find(code % MOD); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = DebugErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = ControlErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = LogErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = FirmwareErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = WaylineErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = CommonErrorEnum.find(code); + } + + @Override + public String getMessage() { + return errorCode.getMessage(); + } + + @JsonValue + public Integer getCode() { + return sourceCode; + } + + public boolean isSuccess() { + return success; + } + + public ErrorCodeSourceEnum getSource() { + return source; + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/services/ServicesPublish.java b/src/main/java/com/dji/sdk/mqtt/services/ServicesPublish.java new file mode 100644 index 0000000..9ca29d2 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/services/ServicesPublish.java @@ -0,0 +1,89 @@ +package com.dji.sdk.mqtt.services; + +import com.dji.sdk.common.Common; +import com.dji.sdk.mqtt.MqttGatewayPublish; +import com.dji.sdk.mqtt.TopicConst; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Objects; +import java.util.UUID; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class ServicesPublish { + + @Resource + private MqttGatewayPublish gatewayPublish; + + public TopicServicesResponse> publish(TypeReference clazz, String sn, String method) { + return this.publish(clazz, sn, method, null); + } + + public TopicServicesResponse> publish(TypeReference clazz, String sn, String method, Object data) { + return this.publish(clazz, sn, method, data, MqttGatewayPublish.DEFAULT_RETRY_COUNT); + } + + public TopicServicesResponse> publish(TypeReference clazz, String sn, String method, Object data, int retryCount) { + return this.publish(clazz, sn, method, data, retryCount, MqttGatewayPublish.DEFAULT_RETRY_TIMEOUT); + } + + public TopicServicesResponse> publish(TypeReference clazz, String sn, String method, Object data, int retryCount, long timeout) { + return this.publish(clazz, sn, method, data, null, retryCount, timeout); + } + + public TopicServicesResponse publish(String sn, String method) { + return this.publish(sn, method, null, null); + } + + public TopicServicesResponse publish(String sn, String method, Object data) { + return this.publish(sn, method, data, null); + } + + public TopicServicesResponse publish(String sn, String method, Object data, String bid) { + return this.publish(sn, method, data, bid, MqttGatewayPublish.DEFAULT_RETRY_COUNT); + } + + public TopicServicesResponse publish(String sn, String method, Object data, String bid, int retryCount) { + return this.publish(sn, method, data, bid, retryCount, MqttGatewayPublish.DEFAULT_RETRY_TIMEOUT); + } + + public TopicServicesResponse publish(String sn, String method, Object data, String bid, int retryCount, long timeout) { + return (TopicServicesResponse) this.publish(null, sn, method, data, bid, retryCount, timeout); + } + + public TopicServicesResponse> publish( + TypeReference clazz, String sn, String method, Object data, String bid, int retryCount, long timeout) { + String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(sn) + TopicConst.SERVICES_SUF; + TopicServicesResponse response = (TopicServicesResponse) gatewayPublish.publishWithReply( + ServicesReplyReceiver.class, topic, new TopicServicesRequest<>() + .setTid(UUID.randomUUID().toString()) + .setBid(bid) + .setTimestamp(System.currentTimeMillis()) + .setMethod(method) + .setData(Objects.requireNonNullElse(data, "")), retryCount, timeout); + ServicesReplyReceiver replyReceiver = (ServicesReplyReceiver) response.getData(); + ServicesReplyData reply = new ServicesReplyData().setResult(replyReceiver.getResult()); + if (Objects.isNull(clazz)) { + reply.setOutput((T) Objects.requireNonNullElse( + replyReceiver.getOutput(), Objects.requireNonNullElse(replyReceiver.getInfo(), ""))); + return response.setData(reply); + } + // put together in "output" + ObjectMapper mapper = Common.getObjectMapper(); + if (Objects.nonNull(replyReceiver.getInfo())) { + reply.setOutput(mapper.convertValue(replyReceiver.getInfo(), clazz)); + } + if (Objects.nonNull(replyReceiver.getOutput())) { + reply.setOutput(mapper.convertValue(replyReceiver.getOutput(), clazz)); + } + return response.setData(reply); + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyData.java b/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyData.java new file mode 100644 index 0000000..05445af --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyData.java @@ -0,0 +1,42 @@ +package com.dji.sdk.mqtt.services; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/22 + */ +public class ServicesReplyData { + + private ServicesErrorCode result; + + private T output; + + public ServicesReplyData() { + } + + @Override + public String toString() { + return "DrcUpData{" + + "result=" + result + + ", output=" + output + + '}'; + } + + public ServicesErrorCode getResult() { + return result; + } + + public ServicesReplyData setResult(ServicesErrorCode result) { + this.result = result; + return this; + } + + public T getOutput() { + return output; + } + + public ServicesReplyData setOutput(T output) { + this.output = output; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyHandler.java b/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyHandler.java new file mode 100644 index 0000000..01ee174 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyHandler.java @@ -0,0 +1,45 @@ +package com.dji.sdk.mqtt.services; + +import com.dji.sdk.cloudapi.log.FileUploadListResponse; +import com.dji.sdk.cloudapi.log.LogMethodEnum; +import com.dji.sdk.common.Common; +import com.dji.sdk.mqtt.Chan; +import com.dji.sdk.mqtt.ChannelName; +import com.fasterxml.jackson.core.type.TypeReference; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.Objects; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +@Component +public class ServicesReplyHandler { + + /** + * Handle the reply message from topic "/services_reply". + * @param message reply message + * @throws IOException + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_SERVICES_REPLY) + public void servicesReply(Message message) throws IOException { + byte[] payload = (byte[])message.getPayload(); + + TopicServicesResponse receiver = Common.getObjectMapper() + .readValue(payload, new TypeReference>() {}); + Chan chan = Chan.getInstance(receiver.getTid(), false); + if (Objects.isNull(chan)) { + return; + } + if (LogMethodEnum.FILE_UPLOAD_LIST.getMethod().equals(receiver.getMethod())) { + receiver.getData().setOutput(Common.getObjectMapper().convertValue(receiver.getData(), + new TypeReference() {})); + } + chan.put(receiver); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyReceiver.java b/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyReceiver.java new file mode 100644 index 0000000..74fdaca --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/services/ServicesReplyReceiver.java @@ -0,0 +1,66 @@ +package com.dji.sdk.mqtt.services; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/22 + */ +public class ServicesReplyReceiver { + + private ServicesErrorCode result; + + private T info; + + private T output; + + private T files; + + public ServicesReplyReceiver() { + } + + @Override + public String toString() { + return "ServicesReplyReceiver{" + + "result=" + result + + ", info=" + info + + ", output=" + output + + ", files=" + files + + '}'; + } + + public ServicesErrorCode getResult() { + return result; + } + + public ServicesReplyReceiver setResult(ServicesErrorCode result) { + this.result = result; + return this; + } + + public T getInfo() { + return info; + } + + public ServicesReplyReceiver setInfo(T info) { + this.info = info; + return this; + } + + public T getOutput() { + return output; + } + + public ServicesReplyReceiver setOutput(T output) { + this.output = output; + return this; + } + + public T getFiles() { + return files; + } + + public ServicesReplyReceiver setFiles(T files) { + this.files = files; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/services/ServicesSubscribe.java b/src/main/java/com/dji/sdk/mqtt/services/ServicesSubscribe.java new file mode 100644 index 0000000..a3b92a9 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/services/ServicesSubscribe.java @@ -0,0 +1,30 @@ +package com.dji.sdk.mqtt.services; + +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.mqtt.IMqttTopicService; +import com.dji.sdk.mqtt.TopicConst; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class ServicesSubscribe { + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.SERVICES_SUF + TopicConst._REPLY_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway) { + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + + public void unsubscribe(GatewayManager gateway) { + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/services/TopicServicesRequest.java b/src/main/java/com/dji/sdk/mqtt/services/TopicServicesRequest.java new file mode 100644 index 0000000..405d004 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/services/TopicServicesRequest.java @@ -0,0 +1,73 @@ +package com.dji.sdk.mqtt.services; + +import com.dji.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicServicesRequest extends CommonTopicRequest { + + private String method; + + public TopicServicesRequest() { + } + + @Override + public String toString() { + return "TopicServicesRequest{" + + "method='" + method + '\'' + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getMethod() { + return method; + } + + public TopicServicesRequest setMethod(String method) { + this.method = method; + return this; + } + + public String getTid() { + return tid; + } + + public TopicServicesRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicServicesRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicServicesRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicServicesRequest setData(T data) { + this.data = data; + return this; + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/services/TopicServicesResponse.java b/src/main/java/com/dji/sdk/mqtt/services/TopicServicesResponse.java new file mode 100644 index 0000000..2deae35 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/services/TopicServicesResponse.java @@ -0,0 +1,73 @@ +package com.dji.sdk.mqtt.services; + +import com.dji.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicServicesResponse extends CommonTopicResponse { + + private String method; + + @Override + public String toString() { + return "TopicServicesResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", method='" + method + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicServicesResponse() { + } + + public String getTid() { + return tid; + } + + public TopicServicesResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicServicesResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public String getMethod() { + return method; + } + + public TopicServicesResponse setMethod(String method) { + this.method = method; + return this; + } + + public T getData() { + return data; + } + + public TopicServicesResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicServicesResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/state/DockStateDataKeyEnum.java b/src/main/java/com/dji/sdk/mqtt/state/DockStateDataKeyEnum.java new file mode 100644 index 0000000..f657eb0 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/state/DockStateDataKeyEnum.java @@ -0,0 +1,55 @@ +package com.dji.sdk.mqtt.state; + +import com.dji.sdk.cloudapi.device.*; +import com.dji.sdk.cloudapi.livestream.DockLivestreamAbilityUpdate; +import com.dji.sdk.exception.CloudSDKException; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; + +/** + * + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public enum DockStateDataKeyEnum { + + FIRMWARE_VERSION(Set.of("firmware_version"), DockFirmwareVersion.class), + + LIVE_CAPACITY(Set.of("live_capacity"), DockLivestreamAbilityUpdate.class), + + CONTROL_SOURCE(Set.of("control_source"), DockDroneControlSource.class), + + LIVE_STATUS(Set.of("live_status"), DockLiveStatus.class), + + WPMZ_VERSION(Set.of("wpmz_version"), DockWpmzVersion.class), + + PAYLOAD(PayloadModelEnum.getAllIndexWithPosition(), DockPayload.class) + ; + + private final Set keys; + + private final Class classType; + + + DockStateDataKeyEnum(Set keys, Class classType) { + this.keys = keys; + this.classType = classType; + } + + public Class getClassType() { + return classType; + } + + public Set getKeys() { + return keys; + } + + public static DockStateDataKeyEnum find(Set keys) { + return Arrays.stream(values()).filter(keyEnum -> !Collections.disjoint(keys, keyEnum.keys)).findAny() + .orElseThrow(() -> new CloudSDKException(DockStateDataKeyEnum.class, keys)); + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/state/RcStateDataKeyEnum.java b/src/main/java/com/dji/sdk/mqtt/state/RcStateDataKeyEnum.java new file mode 100644 index 0000000..b0dfb1d --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/state/RcStateDataKeyEnum.java @@ -0,0 +1,53 @@ +package com.dji.sdk.mqtt.state; + +import com.dji.sdk.cloudapi.device.*; +import com.dji.sdk.cloudapi.livestream.DockLivestreamAbilityUpdate; +import com.dji.sdk.exception.CloudSDKException; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; + +/** + * + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public enum RcStateDataKeyEnum { + + FIRMWARE_VERSION(Set.of("firmware_version"), RcFirmwareVersion.class), + + LIVE_CAPACITY(Set.of("live_capacity"), DockLivestreamAbilityUpdate.class), + + CONTROL_SOURCE(Set.of("control_source"), RcDroneControlSource.class), + + LIVE_STATUS(Set.of("live_status"), RcLiveStatus.class), + + PAYLOAD_FIRMWARE(PayloadModelEnum.getAllModelWithPosition(), PayloadFirmwareVersion.class), + ; + + private final Set keys; + + private final Class classType; + + + RcStateDataKeyEnum(Set keys, Class classType) { + this.keys = keys; + this.classType = classType; + } + + public Class getClassType() { + return classType; + } + + public Set getKeys() { + return keys; + } + + public static RcStateDataKeyEnum find(Set keys) { + return Arrays.stream(values()).filter(keyEnum -> !Collections.disjoint(keys, keyEnum.keys)).findAny() + .orElseThrow(() -> new CloudSDKException(RcStateDataKeyEnum.class, keys)); + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/state/StateDataKeyEnum.java b/src/main/java/com/dji/sdk/mqtt/state/StateDataKeyEnum.java new file mode 100644 index 0000000..12fcdff --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/state/StateDataKeyEnum.java @@ -0,0 +1,64 @@ +package com.dji.sdk.mqtt.state; + +import com.dji.sdk.cloudapi.device.*; +import com.dji.sdk.cloudapi.livestream.DockLivestreamAbilityUpdate; +import com.dji.sdk.cloudapi.livestream.RcLivestreamAbilityUpdate; +import com.dji.sdk.mqtt.ChannelName; + +import java.util.Arrays; + +/** + * + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public enum StateDataKeyEnum { + + RC_FIRMWARE_VERSION(ChannelName.INBOUND_STATE_RC_FIRMWARE_VERSION, RcFirmwareVersion.class), + + RC_LIVE_CAPACITY(ChannelName.INBOUND_STATE_RC_LIVESTREAM_ABILITY_UPDATE, RcLivestreamAbilityUpdate.class), + + RC_CONTROL_SOURCE(ChannelName.INBOUND_STATE_RC_CONTROL_SOURCE, RcDroneControlSource.class), + + RC_LIVE_STATUS(ChannelName.INBOUND_STATE_RC_LIVE_STATUS, RcLiveStatus.class), + + RC_PAYLOAD_FIRMWARE(ChannelName.INBOUND_STATE_RC_PAYLOAD_FIRMWARE, PayloadFirmwareVersion.class), + + DOCK_FIRMWARE_VERSION(ChannelName.INBOUND_STATE_DOCK_FIRMWARE_VERSION, DockFirmwareVersion.class), + + DOCK_LIVE_CAPACITY(ChannelName.INBOUND_STATE_DOCK_LIVESTREAM_ABILITY_UPDATE, DockLivestreamAbilityUpdate.class), + + DOCK_CONTROL_SOURCE(ChannelName.INBOUND_STATE_DOCK_CONTROL_SOURCE, DockDroneControlSource.class), + + DOCK_LIVE_STATUS(ChannelName.INBOUND_STATE_DOCK_LIVE_STATUS, DockLiveStatus.class), + + WPMZ_VERSION(ChannelName.INBOUND_STATE_DOCK_WPMZ_VERSION, DockWpmzVersion.class), + + DOCK_PAYLOAD(ChannelName.INBOUND_STATE_DOCK_PAYLOAD, DockPayload.class), + + UNKNOWN(ChannelName.DEFAULT, Object.class); + + private final String channelName; + + private final Class classType; + + StateDataKeyEnum(String channelName, Class classType) { + this.channelName = channelName; + this.classType = classType; + } + + public Class getClassType() { + return classType; + } + + public String getChannelName() { + return channelName; + } + + public static StateDataKeyEnum find(Class clazz) { + return Arrays.stream(values()).filter(keyEnum -> keyEnum.classType == clazz).findAny() + .orElse(UNKNOWN); + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java b/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java new file mode 100644 index 0000000..b26c00e --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/state/StateRouter.java @@ -0,0 +1,63 @@ +package com.dji.sdk.mqtt.state; + +import com.dji.sdk.common.Common; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import com.dji.sdk.mqtt.ChannelName; +import com.fasterxml.jackson.core.type.TypeReference; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.IntegrationFlows; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.Message; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import java.util.Set; + +import static com.dji.sdk.mqtt.TopicConst.*; + +/** + * + * @author sean.zhou + * @date 2021/11/17 + * @version 0.1 + */ +@Configuration +public class StateRouter { + + @Bean + public IntegrationFlow stateDataRouterFlow() { + return IntegrationFlows + .from(ChannelName.INBOUND_STATE) + .transform(Message.class, source -> { + try { + TopicStateRequest response = Common.getObjectMapper().readValue((byte[]) source.getPayload(), new TypeReference() {}); + String topic = String.valueOf(source.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)); + String from = topic.substring((THING_MODEL_PRE + PRODUCT).length(), topic.indexOf(STATE_SUF)); + return response.setFrom(from) + .setData(Common.getObjectMapper().convertValue(response.getData(), getTypeReference(response.getGateway(), response.getData()))); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }, null) + .route(response -> StateDataKeyEnum.find(response.getData().getClass()), + mapping -> Arrays.stream(StateDataKeyEnum.values()).forEach(key -> mapping.channelMapping(key, key.getChannelName()))) + .get(); + } + + private Class getTypeReference(String gatewaySn, Object data) { + Set keys = ((Map) data).keySet(); + switch (SDKManager.getDeviceSDK(gatewaySn).getType()) { + case RC: + return RcStateDataKeyEnum.find(keys).getClassType(); + case DOCK: + return DockStateDataKeyEnum.find(keys).getClassType(); + default: + throw new CloudSDKException(CloudSDKErrorEnum.WRONG_DATA, "Unexpected value: " + SDKManager.getDeviceSDK(gatewaySn).getType()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/state/StateSubscribe.java b/src/main/java/com/dji/sdk/mqtt/state/StateSubscribe.java new file mode 100644 index 0000000..7a1a746 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/state/StateSubscribe.java @@ -0,0 +1,44 @@ +package com.dji.sdk.mqtt.state; + +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.IMqttTopicService; +import com.dji.sdk.mqtt.TopicConst; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class StateSubscribe { + + @Resource + private IMqttTopicService topicService; + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.STATE_SUF; + + public void subscribe(GatewayManager gateway, boolean unsubscribeSubDevice) { + SDKManager.registerDevice(gateway); + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (unsubscribeSubDevice) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + return; + } + if (null != gateway.getDroneSn()) { + topicService.subscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } + + public void unsubscribe(GatewayManager gateway) { + SDKManager.logoutDevice(gateway.getGatewaySn()); + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (null != gateway.getDroneSn()) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/state/TopicStateRequest.java b/src/main/java/com/dji/sdk/mqtt/state/TopicStateRequest.java new file mode 100644 index 0000000..555772c --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/state/TopicStateRequest.java @@ -0,0 +1,83 @@ +package com.dji.sdk.mqtt.state; + +import com.dji.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicStateRequest extends CommonTopicRequest { + + private String gateway; + + private String from; + + public TopicStateRequest() { + } + + @Override + public String toString() { + return "TopicStateRequest{" + + "gateway='" + gateway + '\'' + + ", from='" + from + '\'' + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + public String getTid() { + return tid; + } + + public TopicStateRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicStateRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicStateRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicStateRequest setData(T data) { + this.data = data; + return this; + } + + public String getGateway() { + return gateway; + } + + public TopicStateRequest setGateway(String gateway) { + this.gateway = gateway; + return this; + } + + public String getFrom() { + return from; + } + + public TopicStateRequest setFrom(String from) { + this.from = from; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/status/StatusRouter.java b/src/main/java/com/dji/sdk/mqtt/status/StatusRouter.java new file mode 100644 index 0000000..396bd2e --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/status/StatusRouter.java @@ -0,0 +1,73 @@ +package com.dji.sdk.mqtt.status; + +import com.dji.sdk.cloudapi.device.UpdateTopo; +import com.dji.sdk.common.Common; +import com.dji.sdk.exception.CloudSDKException; +import com.dji.sdk.mqtt.ChannelName; +import com.dji.sdk.mqtt.MqttGatewayPublish; +import com.fasterxml.jackson.core.type.TypeReference; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.IntegrationFlows; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.io.IOException; +import java.util.Objects; +import java.util.Optional; + +import static com.dji.sdk.mqtt.TopicConst.*; + +/** + * + * @author sean.zhou + * @date 2021/11/12 + * @version 0.1 + */ +@Configuration +public class StatusRouter { + + @Resource + private MqttGatewayPublish gatewayPublish; + + @Bean + public IntegrationFlow statusRouterFlow() { + return IntegrationFlows + .from(ChannelName.INBOUND_STATUS) + .transform(Message.class, source -> { + try { + TopicStatusRequest response = Common.getObjectMapper().readValue((byte[]) source.getPayload(), new TypeReference>() {}); + String topic = String.valueOf(source.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)); + return response.setFrom(topic.substring((BASIC_PRE + PRODUCT).length(), topic.indexOf(STATUS_SUF))); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }, null) + ., Boolean>route( + response -> Optional.ofNullable(response.getData()).map(UpdateTopo::getSubDevices).map(CollectionUtils::isEmpty).orElse(true), + mapping -> mapping.channelMapping(true, ChannelName.INBOUND_STATUS_OFFLINE) + .channelMapping(false, ChannelName.INBOUND_STATUS_ONLINE)) + .get(); + } + + @Bean + public IntegrationFlow replySuccessStatus() { + return IntegrationFlows + .from(ChannelName.OUTBOUND_STATUS) + .handle(this::publish) + .nullChannel(); + + } + + private TopicStatusResponse publish(TopicStatusResponse request, MessageHeaders headers) { + if (Objects.isNull(request)) { + return null; + } + gatewayPublish.publishReply(request, headers); + return request; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/mqtt/status/StatusSubscribe.java b/src/main/java/com/dji/sdk/mqtt/status/StatusSubscribe.java new file mode 100644 index 0000000..2412067 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/status/StatusSubscribe.java @@ -0,0 +1,39 @@ +package com.dji.sdk.mqtt.status; + +import com.dji.sdk.common.GatewayManager; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.IMqttTopicService; +import com.dji.sdk.mqtt.TopicConst; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class StatusSubscribe { + + public static final String TOPIC = TopicConst.BASIC_PRE + TopicConst.PRODUCT + "%s" + TopicConst.STATUS_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway) { + SDKManager.registerDevice(gateway); + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + + public void subscribeWildcardsStatus() { + topicService.subscribe(String.format(TOPIC, "+")); + } + + public void unsubscribe(GatewayManager gateway) { + SDKManager.logoutDevice(gateway.getGatewaySn()); + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + +} diff --git a/src/main/java/com/dji/sdk/mqtt/status/TopicStatusRequest.java b/src/main/java/com/dji/sdk/mqtt/status/TopicStatusRequest.java new file mode 100644 index 0000000..ff54553 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/status/TopicStatusRequest.java @@ -0,0 +1,84 @@ +package com.dji.sdk.mqtt.status; + +import com.dji.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicStatusRequest extends CommonTopicRequest { + + private String method; + + private String from; + + public TopicStatusRequest() { + } + + @Override + public String toString() { + return "TopicStatusRequest{" + + "method='" + method + '\'' + + ", from='" + from + '\'' + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getTid() { + return tid; + } + + public TopicStatusRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicStatusRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicStatusRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicStatusRequest setData(T data) { + this.data = data; + return this; + } + + public String getMethod() { + return method; + } + + public TopicStatusRequest setMethod(String method) { + this.method = method; + return this; + } + + public String getFrom() { + return from; + } + + public TopicStatusRequest setFrom(String from) { + this.from = from; + return this; + } +} diff --git a/src/main/java/com/dji/sdk/mqtt/status/TopicStatusResponse.java b/src/main/java/com/dji/sdk/mqtt/status/TopicStatusResponse.java new file mode 100644 index 0000000..943fdb9 --- /dev/null +++ b/src/main/java/com/dji/sdk/mqtt/status/TopicStatusResponse.java @@ -0,0 +1,73 @@ +package com.dji.sdk.mqtt.status; + +import com.dji.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicStatusResponse extends CommonTopicResponse { + + private String method; + + @Override + public String toString() { + return "TopicStatusResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", method='" + method + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicStatusResponse() { + } + + public String getTid() { + return tid; + } + + public TopicStatusResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicStatusResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public String getMethod() { + return method; + } + + public TopicStatusResponse setMethod(String method) { + this.method = method; + return this; + } + + public T getData() { + return data; + } + + public TopicStatusResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicStatusResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/swagger/SwaggerConfig.java b/src/main/java/com/dji/sdk/swagger/SwaggerConfig.java new file mode 100644 index 0000000..46be817 --- /dev/null +++ b/src/main/java/com/dji/sdk/swagger/SwaggerConfig.java @@ -0,0 +1,56 @@ +package com.dji.sdk.swagger; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springdoc.core.GroupedOpenApi; +import org.springdoc.core.SpringDocConfigProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/14 + */ +@Configuration +@OpenAPIDefinition(security = {@SecurityRequirement(name = "default")}) +public class SwaggerConfig { + + @Bean + public OpenAPI openAPI() { + return new OpenAPI() + .info(new Info().title("CloudSDK API").description("All HTTP interfaces encapsulated by CloudSDK.") + .license(new License().name("LICENSE").url("https://github.com/dji-sdk/DJI-Cloud-API-Demo/blob/main/LICENSE")) + .version("1.0.0")).components(components()); + } + + @Bean + public SecurityScheme securityScheme() { + return new SecurityScheme().type(SecurityScheme.Type.APIKEY).in(SecurityScheme.In.HEADER).name("x-auth-token"); + } + + @Bean + public Components components() { + return new Components() + .addSecuritySchemes("default", securityScheme()); + } + + @Bean + public GroupedOpenApi sdkOpenApi() { + return GroupedOpenApi.builder().group("CloudSDK") + .packagesToScan("com.dji").build(); + } + + @Bean + public SpringDocConfigProperties springDocConfigProperties(SpringDocConfigProperties properties) { + properties.setDefaultFlatParamObject(false); + properties.setDefaultSupportFormData(true); + properties.setDefaultProducesMediaType("application/json"); + return properties; + } +} diff --git a/src/main/java/com/dji/sdk/websocket/BizCodeEnum.java b/src/main/java/com/dji/sdk/websocket/BizCodeEnum.java new file mode 100644 index 0000000..bb68d39 --- /dev/null +++ b/src/main/java/com/dji/sdk/websocket/BizCodeEnum.java @@ -0,0 +1,42 @@ +package com.dji.sdk.websocket; + +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @author sean + * @version 0.1 + * @date 2021/11/26 + */ +@Schema(enumAsRef = true, description = "Pilot2 will receive these bizCode, and then do corresponding processing according to the value.") +public enum BizCodeEnum { + + DEVICE_ONLINE("device_online"), + + DEVICE_OFFLINE("device_offline"), + + DEVICE_UPDATE_TOPO("device_update_topo"), + + DEVICE_OSD("device_osd"), + + MAP_ELEMENT_CREATE("map_element_create"), + + MAP_ELEMENT_UPDATE("map_element_update"), + + MAP_ELEMENT_DELETE("map_element_delete"), + + MAP_GROUP_REFRESH("map_group_refresh"); + + private final String code; + + BizCodeEnum(String code) { + this.code = code; + } + + @JsonValue + public String getCode() { + return code; + } + + +} diff --git a/src/main/java/com/dji/sample/component/websocket/config/ConcurrentWebSocketSession.java b/src/main/java/com/dji/sdk/websocket/ConcurrentWebSocketSession.java similarity index 93% rename from src/main/java/com/dji/sample/component/websocket/config/ConcurrentWebSocketSession.java rename to src/main/java/com/dji/sdk/websocket/ConcurrentWebSocketSession.java index cd13365..e4c3938 100644 --- a/src/main/java/com/dji/sample/component/websocket/config/ConcurrentWebSocketSession.java +++ b/src/main/java/com/dji/sdk/websocket/ConcurrentWebSocketSession.java @@ -1,4 +1,4 @@ -package com.dji.sample.component.websocket.config; +package com.dji.sdk.websocket; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator; diff --git a/src/main/java/com/dji/sample/component/websocket/config/WebSocketMessageConfiguration.java b/src/main/java/com/dji/sdk/websocket/WebSocketConfiguration.java similarity index 62% rename from src/main/java/com/dji/sample/component/websocket/config/WebSocketMessageConfiguration.java rename to src/main/java/com/dji/sdk/websocket/WebSocketConfiguration.java index 85a696c..52ceb9b 100644 --- a/src/main/java/com/dji/sample/component/websocket/config/WebSocketMessageConfiguration.java +++ b/src/main/java/com/dji/sdk/websocket/WebSocketConfiguration.java @@ -1,4 +1,4 @@ -package com.dji.sample.component.websocket.config; +package com.dji.sdk.websocket; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; @@ -6,6 +6,8 @@ import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBr import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration; +import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory; +import org.springframework.web.socket.server.HandshakeHandler; /** * @@ -15,25 +17,24 @@ import org.springframework.web.socket.config.annotation.WebSocketTransportRegist */ @EnableWebSocketMessageBroker @Configuration -public class WebSocketMessageConfiguration implements WebSocketMessageBrokerConfigurer { +public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer { - @Autowired - private AuthPrincipalHandler authPrincipalHandler; + @Autowired(required = false) + private HandshakeHandler handshakeHandler; @Autowired - private WebSocketDefaultFactory webSocketDefaultFactory; + private WebSocketHandlerDecoratorFactory webSocketHandlerDecoratorFactory; @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // Set the WebSocket connection address registry.addEndpoint("/api/v1/ws").setAllowedOriginPatterns("*") - .setHandshakeHandler(authPrincipalHandler); + .setHandshakeHandler(handshakeHandler); } @Override public void configureWebSocketTransport(WebSocketTransportRegistration registry) { - registry.addDecoratorFactory(webSocketDefaultFactory); - registry.setTimeToFirstMessage(60000 * 60 * 24 * 10); + registry.addDecoratorFactory(webSocketHandlerDecoratorFactory); } } \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/websocket/WebSocketDefaultFactory.java b/src/main/java/com/dji/sdk/websocket/WebSocketDefaultFactory.java new file mode 100644 index 0000000..1d03b1f --- /dev/null +++ b/src/main/java/com/dji/sdk/websocket/WebSocketDefaultFactory.java @@ -0,0 +1,20 @@ +package com.dji.sdk.websocket; + +import org.springframework.stereotype.Component; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory; + +/** + * + * @author sean.zhou + * @date 2021/11/16 + * @version 0.1 + */ +@Component +public class WebSocketDefaultFactory implements WebSocketHandlerDecoratorFactory { + + @Override + public WebSocketHandler decorate(WebSocketHandler handler) { + return new WebSocketDefaultHandler(handler); + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/websocket/WebSocketDefaultHandler.java b/src/main/java/com/dji/sdk/websocket/WebSocketDefaultHandler.java new file mode 100644 index 0000000..01e72b3 --- /dev/null +++ b/src/main/java/com/dji/sdk/websocket/WebSocketDefaultHandler.java @@ -0,0 +1,40 @@ +package com.dji.sdk.websocket; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.WebSocketMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.WebSocketHandlerDecorator; + +/** + * + * @author sean.zhou + * @date 2021/11/16 + * @version 0.1 + */ +public class WebSocketDefaultHandler extends WebSocketHandlerDecorator { + + private static final Logger log = LoggerFactory.getLogger(WebSocketDefaultHandler.class); + + public WebSocketDefaultHandler(WebSocketHandler delegate) { + super(delegate); + } + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + log.debug("{} is connected.", session.getId()); + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { + log.debug("{} is disconnected.", session.getId()); + } + + @Override + public void handleMessage(WebSocketSession session, WebSocketMessage message) throws Exception { + log.info("received message: {}, from: {}", message.getPayload(), session.getId()); + } + +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/websocket/WebSocketMessageResponse.java b/src/main/java/com/dji/sdk/websocket/WebSocketMessageResponse.java new file mode 100644 index 0000000..816d555 --- /dev/null +++ b/src/main/java/com/dji/sdk/websocket/WebSocketMessageResponse.java @@ -0,0 +1,83 @@ +package com.dji.sdk.websocket; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * The format of WebSocket messages that the pilot can receive. + * @author sean.zhou + * @date 2021/11/17 + * @version 0.1 + */ +@Schema(description = "The format of WebSocket messages that the pilot can receive.") +public class WebSocketMessageResponse { + + @JsonProperty("biz_code") + @NotNull + @Schema(description = "webSocket messages identity", implementation = BizCodeEnum.class) + private String bizCode; + + @Schema(description = "webSocket messages version") + private String version = "1.0"; + + @NotNull + @Min(123456789012L) + @Schema(description = "timestamp (milliseconds)") + private Long timestamp; + + @NotNull + @Schema(description = "Data corresponding to business functions") + private T data; + + public WebSocketMessageResponse() { + } + + @Override + public String toString() { + return "WebSocketMessageResponse{" + + "bizCode=" + bizCode + + ", version='" + version + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getBizCode() { + return bizCode; + } + + public WebSocketMessageResponse setBizCode(String bizCode) { + this.bizCode = bizCode; + return this; + } + + public String getVersion() { + return version; + } + + public WebSocketMessageResponse setVersion(String version) { + this.version = version; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public WebSocketMessageResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public WebSocketMessageResponse setData(T data) { + this.data = data; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/dji/sdk/websocket/api/WebSocketMessageSend.java b/src/main/java/com/dji/sdk/websocket/api/WebSocketMessageSend.java new file mode 100644 index 0000000..9caee08 --- /dev/null +++ b/src/main/java/com/dji/sdk/websocket/api/WebSocketMessageSend.java @@ -0,0 +1,64 @@ +package com.dji.sdk.websocket.api; + +import com.dji.sdk.common.Common; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.exception.CloudSDKException; +import com.dji.sdk.websocket.ConcurrentWebSocketSession; +import com.dji.sdk.websocket.WebSocketMessageResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.socket.TextMessage; + +import java.io.IOException; +import java.util.Collection; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/24 + */ +public class WebSocketMessageSend { + + private static final Logger log = LoggerFactory.getLogger(WebSocketMessageSend.class); + + public void sendMessage(ConcurrentWebSocketSession session, WebSocketMessageResponse message) { + if (session == null) { + return; + } + + try { + if (!session.isOpen()) { + session.close(); + log.info("This session is closed."); + return; + } + + session.sendMessage(new TextMessage(Common.getObjectMapper().writeValueAsBytes(message))); + } catch (IOException e) { + throw new CloudSDKException(CloudSDKErrorEnum.WEBSOCKET_PUBLISH_ABNORMAL, e.getLocalizedMessage()); + } + } + + public void sendBatch(Collection sessions, WebSocketMessageResponse message) { + if (sessions.isEmpty()) { + return; + } + + try { + + TextMessage data = new TextMessage(Common.getObjectMapper().writeValueAsBytes(message)); + + for (ConcurrentWebSocketSession session : sessions) { + if (!session.isOpen()) { + session.close(); + log.info("This session is closed."); + return; + } + session.sendMessage(data); + } + + } catch (IOException e) { + throw new CloudSDKException(CloudSDKErrorEnum.WEBSOCKET_PUBLISH_ABNORMAL, e.getLocalizedMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a5c937a..b5ebbe7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,8 @@ server: port: 6789 spring: + main: + allow-bean-definition-overriding: true application: name: cloud-api-sample datasource: @@ -50,13 +52,18 @@ mqtt: client-id: 123456 # If the protocol is ws/wss, this value is required. path: - # Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",". - inbound-topic: sys/product/+/status,thing/product/+/requests DRC: protocol: WS # @see com.dji.sample.component.mqtt.model.MqttProtocolEnum host: Please enter your ip. port: 8083 path: /mqtt + username: JavaServer + password: 123456 + +cloud-sdk: + mqtt: + # Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",". + inbound-topic: sys/product/+/status,thing/product/+/requests url: manage: @@ -81,7 +88,7 @@ url: # Tutorial: https://www.alibabacloud.com/help/en/object-storage-service/latest/use-a-temporary-credential-provided-by-sts-to-access-oss oss: enable: false - provider: ali # @see com.dji.sample.component.OssConfiguration.model.enums.OssTypeEnum + provider: ALIYUN # @see com.dji.sample.component.OssConfiguration.model.enums.OssTypeEnum endpoint: https://oss-cn-hangzhou.aliyuncs.com access-key: Please enter your access key. secret-key: Please enter your secret key. @@ -118,7 +125,7 @@ oss: logging: level: - com.dji.sample: debug + com.dji: debug file: name: logs/cloud-api-sample.log diff --git a/src/main/resources/image/1.png b/src/main/resources/image/1.png new file mode 100644 index 0000000..8d57aa8 Binary files /dev/null and b/src/main/resources/image/1.png differ diff --git a/src/main/resources/image/2.png b/src/main/resources/image/2.png new file mode 100644 index 0000000..7fc331a Binary files /dev/null and b/src/main/resources/image/2.png differ diff --git a/src/main/resources/image/3.png b/src/main/resources/image/3.png new file mode 100644 index 0000000..c31bdb6 Binary files /dev/null and b/src/main/resources/image/3.png differ diff --git a/src/main/resources/image/4.png b/src/main/resources/image/4.png new file mode 100644 index 0000000..23a277b Binary files /dev/null and b/src/main/resources/image/4.png differ diff --git a/src/main/resources/image/5.png b/src/main/resources/image/5.png new file mode 100644 index 0000000..5e81513 Binary files /dev/null and b/src/main/resources/image/5.png differ diff --git a/src/main/resources/image/6.png b/src/main/resources/image/6.png new file mode 100644 index 0000000..6a9169c Binary files /dev/null and b/src/main/resources/image/6.png differ diff --git a/src/main/resources/image/7.png b/src/main/resources/image/7.png new file mode 100644 index 0000000..52ee49f Binary files /dev/null and b/src/main/resources/image/7.png differ