Browse Source

What's new?

CloudSDK V1.0.0 was released to adapt to multiple versions of device protocols, simplify access to mqtt and http protocols, and provide protocol verification and error code modules.
v1.7.0
sean.zhou 1 year ago
parent
commit
12887aed11
  1. 389
      pom.xml
  2. 6
      sql/cloud_sample.sql
  3. 3
      src/main/java/com/dji/sample/CloudApiSampleApplication.java
  4. 7
      src/main/java/com/dji/sample/common/error/CommonErrorEnum.java
  5. 78
      src/main/java/com/dji/sample/common/error/LiveErrorEnum.java
  6. 36
      src/main/java/com/dji/sample/common/model/Pagination.java
  7. 27
      src/main/java/com/dji/sample/common/model/PaginationData.java
  8. 69
      src/main/java/com/dji/sample/common/model/ResponseResult.java
  9. 2
      src/main/java/com/dji/sample/common/util/JwtUtil.java
  10. 30
      src/main/java/com/dji/sample/common/util/SpringBeanUtilsTest.java
  11. 19
      src/main/java/com/dji/sample/component/ApplicationBootInitial.java
  12. 4
      src/main/java/com/dji/sample/component/AuthInterceptor.java
  13. 14
      src/main/java/com/dji/sample/component/GlobalExceptionHandler.java
  14. 18
      src/main/java/com/dji/sample/component/GlobalScheduleService.java
  15. 145
      src/main/java/com/dji/sample/component/mqtt/config/MqttMessageChannel.java
  16. 47
      src/main/java/com/dji/sample/component/mqtt/config/MqttOutboundConfiguration.java
  17. 22
      src/main/java/com/dji/sample/component/mqtt/config/MqttPropertyConfiguration.java
  18. 39
      src/main/java/com/dji/sample/component/mqtt/handler/AbstractStateTopicHandler.java
  19. 68
      src/main/java/com/dji/sample/component/mqtt/handler/EventsRouter.java
  20. 40
      src/main/java/com/dji/sample/component/mqtt/handler/PropertySetReplyHandler.java
  21. 45
      src/main/java/com/dji/sample/component/mqtt/handler/RequestsRouter.java
  22. 53
      src/main/java/com/dji/sample/component/mqtt/handler/ServicesReplyHandler.java
  23. 26
      src/main/java/com/dji/sample/component/mqtt/handler/StateDefaultHandler.java
  24. 38
      src/main/java/com/dji/sample/component/mqtt/handler/StateDeviceBasicHandler.java
  25. 62
      src/main/java/com/dji/sample/component/mqtt/handler/StateFirmwareVersionHandler.java
  26. 39
      src/main/java/com/dji/sample/component/mqtt/handler/StateLiveCapacityHandler.java
  27. 104
      src/main/java/com/dji/sample/component/mqtt/handler/StateRouter.java
  28. 67
      src/main/java/com/dji/sample/component/mqtt/handler/StatusRouter.java
  29. 45
      src/main/java/com/dji/sample/component/mqtt/model/Chan.java
  30. 91
      src/main/java/com/dji/sample/component/mqtt/model/ChannelName.java
  31. 34
      src/main/java/com/dji/sample/component/mqtt/model/CommonTopicReceiver.java
  32. 35
      src/main/java/com/dji/sample/component/mqtt/model/CommonTopicResponse.java
  33. 32
      src/main/java/com/dji/sample/component/mqtt/model/ConfigScopeEnum.java
  34. 23
      src/main/java/com/dji/sample/component/mqtt/model/ErrorInfoReply.java
  35. 83
      src/main/java/com/dji/sample/component/mqtt/model/EventsMethodEnum.java
  36. 18
      src/main/java/com/dji/sample/component/mqtt/model/EventsOutputProgressReceiver.java
  37. 53
      src/main/java/com/dji/sample/component/mqtt/model/EventsReceiver.java
  38. 49
      src/main/java/com/dji/sample/component/mqtt/model/EventsResultStatusEnum.java
  39. 22
      src/main/java/com/dji/sample/component/mqtt/model/MapKeyConst.java
  40. 2
      src/main/java/com/dji/sample/component/mqtt/model/MqttProtocolEnum.java
  41. 18
      src/main/java/com/dji/sample/component/mqtt/model/OutputProgressReceiver.java
  42. 44
      src/main/java/com/dji/sample/component/mqtt/model/RequestsMethodEnum.java
  43. 44
      src/main/java/com/dji/sample/component/mqtt/model/RequestsReply.java
  44. 20
      src/main/java/com/dji/sample/component/mqtt/model/ServiceReply.java
  45. 14
      src/main/java/com/dji/sample/component/mqtt/model/SetReply.java
  46. 30
      src/main/java/com/dji/sample/component/mqtt/model/SetReplyStatusResultEnum.java
  47. 26
      src/main/java/com/dji/sample/component/mqtt/model/StateDataEnum.java
  48. 90
      src/main/java/com/dji/sample/component/mqtt/service/IMessageSenderService.java
  49. 116
      src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java
  50. 44
      src/main/java/com/dji/sample/component/mqtt/service/impl/MqttTopicServiceImpl.java
  51. 7
      src/main/java/com/dji/sample/component/oss/model/OssConfiguration.java
  52. 7
      src/main/java/com/dji/sample/component/oss/service/IOssService.java
  53. 14
      src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java
  54. 14
      src/main/java/com/dji/sample/component/oss/service/impl/AmazonS3ServiceImpl.java
  55. 16
      src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java
  56. 8
      src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java
  57. 12
      src/main/java/com/dji/sample/component/redis/RedisConst.java
  58. 25
      src/main/java/com/dji/sample/component/websocket/config/MyConcurrentWebSocketSession.java
  59. 8
      src/main/java/com/dji/sample/component/websocket/config/MyWebSocketFactory.java
  60. 8
      src/main/java/com/dji/sample/component/websocket/config/MyWebSocketHandler.java
  61. 2
      src/main/java/com/dji/sample/component/websocket/model/BizCodeEnum.java
  62. 30
      src/main/java/com/dji/sample/component/websocket/model/CustomWebSocketMessage.java
  63. 8
      src/main/java/com/dji/sample/component/websocket/service/IWebSocketManageService.java
  64. 10
      src/main/java/com/dji/sample/component/websocket/service/IWebSocketMessageService.java
  65. 14
      src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketManageServiceImpl.java
  66. 25
      src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketMessageServiceImpl.java
  67. 1
      src/main/java/com/dji/sample/configuration/SpringBeanConfiguration.java
  68. 53
      src/main/java/com/dji/sample/configuration/mvc/GetSnakeDataBinder.java
  69. 14
      src/main/java/com/dji/sample/configuration/mvc/GlobalMVCConfigurer.java
  70. 23
      src/main/java/com/dji/sample/control/controller/DockController.java
  71. 18
      src/main/java/com/dji/sample/control/controller/DrcController.java
  72. 22
      src/main/java/com/dji/sample/control/model/dto/AirConditionerMode.java
  73. 10
      src/main/java/com/dji/sample/control/model/dto/AlarmState.java
  74. 11
      src/main/java/com/dji/sample/control/model/dto/BatteryStoreMode.java
  75. 32
      src/main/java/com/dji/sample/control/model/dto/DrcModeDTO.java
  76. 15
      src/main/java/com/dji/sample/control/model/dto/DrcModeReasonReceiver.java
  77. 18
      src/main/java/com/dji/sample/control/model/dto/DrcStatusNotifyReceiver.java
  78. 22
      src/main/java/com/dji/sample/control/model/dto/FlyToProgressReceiver.java
  79. 22
      src/main/java/com/dji/sample/control/model/dto/LinkWorkMode.java
  80. 31
      src/main/java/com/dji/sample/control/model/dto/MqttBrokerDTO.java
  81. 31
      src/main/java/com/dji/sample/control/model/dto/PointDTO.java
  82. 6
      src/main/java/com/dji/sample/control/model/dto/RemoteDebugOpenState.java
  83. 28
      src/main/java/com/dji/sample/control/model/dto/ReturnHomeCancelState.java
  84. 19
      src/main/java/com/dji/sample/control/model/dto/ReturnHomeState.java
  85. 25
      src/main/java/com/dji/sample/control/model/dto/TakeoffProgressReceiver.java
  86. 29
      src/main/java/com/dji/sample/control/model/enums/BatteryStoreModeEnum.java
  87. 26
      src/main/java/com/dji/sample/control/model/enums/CameraStateEnum.java
  88. 29
      src/main/java/com/dji/sample/control/model/enums/LinkWorkModeEnum.java
  89. 32
      src/main/java/com/dji/sample/control/model/enums/PayloadCommandsEnum.java
  90. 74
      src/main/java/com/dji/sample/control/model/enums/RemoteDebugMethodEnum.java
  91. 2
      src/main/java/com/dji/sample/control/model/param/DrcModeParam.java
  92. 6
      src/main/java/com/dji/sample/control/model/param/DronePayloadParam.java
  93. 4
      src/main/java/com/dji/sample/control/model/param/FlyToPointParam.java
  94. 3
      src/main/java/com/dji/sample/control/model/param/RemoteDebugParam.java
  95. 25
      src/main/java/com/dji/sample/control/model/param/TakeoffToPointParam.java
  96. 27
      src/main/java/com/dji/sample/control/service/IControlService.java
  97. 4
      src/main/java/com/dji/sample/control/service/IDrcService.java
  98. 7
      src/main/java/com/dji/sample/control/service/impl/CameraFocalLengthSetImpl.java
  99. 2
      src/main/java/com/dji/sample/control/service/impl/CameraModeSwitchImpl.java
  100. 2
      src/main/java/com/dji/sample/control/service/impl/CameraPhotoTakeImpl.java
  101. Some files were not shown because too many files have changed in this diff Show More

389
pom.xml

@ -1,85 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.11</version> <version>2.7.12</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<groupId>com.dji</groupId> <groupId>com.dji</groupId>
<artifactId>cloud-api-sample</artifactId> <artifactId>cloud-api-sample</artifactId>
<version>1.5.0</version> <version>1.7.0</version>
<name>cloud-api-sample</name> <name>cloud-api-sample</name>
<properties> <properties>
<java.version>11</java.version> <java.version>11</java.version>
<mybatis-plus.version>3.4.2</mybatis-plus.version> <mybatis-plus.version>3.4.2</mybatis-plus.version>
<druid.version>1.2.6</druid.version> <druid.version>1.2.6</druid.version>
<jwt.version>3.12.1</jwt.version> <jwt.version>3.12.1</jwt.version>
<mqtt.version>5.5.5</mqtt.version> <mqtt.version>5.5.5</mqtt.version>
<minio.version>8.3.7</minio.version> <minio.version>8.3.7</minio.version>
<okhttp3.version>4.9.1</okhttp3.version> <okhttp3.version>4.9.1</okhttp3.version>
<aliyun-sdk-sts.version>3.1.0</aliyun-sdk-sts.version> <aliyun-sdk-sts.version>3.1.0</aliyun-sdk-sts.version>
<aliyun-oss.version>3.12.0</aliyun-oss.version> <aliyun-oss.version>3.12.0</aliyun-oss.version>
<javax-activation.version>1.1.1</javax-activation.version> <javax-activation.version>1.1.1</javax-activation.version>
<glassfish-jaxb.version>2.3.3</glassfish-jaxb.version> <glassfish-jaxb.version>2.3.3</glassfish-jaxb.version>
<log4j2.version>2.15.0</log4j2.version> <log4j2.version>2.15.0</log4j2.version>
<javax-jaxb.version>2.3.0</javax-jaxb.version> <javax-jaxb.version>2.3.0</javax-jaxb.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
</dependency> <version>8.0.31</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId> <dependency>
<artifactId>lombok</artifactId> <groupId>org.projectlombok</groupId>
<optional>true</optional> <artifactId>lombok</artifactId>
</dependency> <optional>true</optional>
<dependency> </dependency>
<groupId>org.springframework.boot</groupId> <dependency>
<artifactId>spring-boot-starter-test</artifactId> <groupId>org.springframework.boot</groupId>
<scope>test</scope> <artifactId>spring-boot-starter-test</artifactId>
</dependency> <scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId> <dependency>
<artifactId>mybatis-plus-boot-starter</artifactId> <groupId>com.baomidou</groupId>
<version>${mybatis-plus.version}</version> <artifactId>mybatis-plus-boot-starter</artifactId>
</dependency> <version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId> <dependency>
<artifactId>druid-spring-boot-starter</artifactId> <groupId>com.alibaba</groupId>
<version>${druid.version}</version> <artifactId>druid-spring-boot-starter</artifactId>
</dependency> <version>${druid.version}</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId> <dependency>
<artifactId>java-jwt</artifactId> <groupId>com.auth0</groupId>
<version>${jwt.version}</version> <artifactId>java-jwt</artifactId>
</dependency> <version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId> <dependency>
<artifactId>spring-integration-mqtt</artifactId> <groupId>org.springframework.integration</groupId>
<version>${mqtt.version}</version> <artifactId>spring-integration-mqtt</artifactId>
</dependency> <version>${mqtt.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId> <dependency>
<artifactId>spring-boot-starter-websocket</artifactId> <groupId>org.springframework.boot</groupId>
</dependency> <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.jetbrains</groupId> <groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId> <artifactId>annotations</artifactId>
@ -87,115 +88,121 @@
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.minio</groupId> <groupId>io.minio</groupId>
<artifactId>minio</artifactId> <artifactId>minio</artifactId>
<version>${minio.version}</version> <version>${minio.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.squareup.okhttp3</groupId> <groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId> <artifactId>okhttp</artifactId>
<version>${okhttp3.version}</version> <version>${okhttp3.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.aliyun</groupId> <groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-sts</artifactId> <artifactId>aliyun-java-sdk-sts</artifactId>
<version>${aliyun-sdk-sts.version}</version> <version>${aliyun-sdk-sts.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.aliyun.oss</groupId> <groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId> <artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun-oss.version}</version> <version>${aliyun-oss.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.xml.bind</groupId> <groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId> <artifactId>jaxb-api</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.activation</groupId> <groupId>javax.activation</groupId>
<artifactId>activation</artifactId> <artifactId>activation</artifactId>
<version>${javax-activation.version}</version> <version>${javax-activation.version}</version>
</dependency> </dependency>
<!-- no more than 2.3.3--> <!-- no more than 2.3.3-->
<dependency> <dependency>
<groupId>org.glassfish.jaxb</groupId> <groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId> <artifactId>jaxb-runtime</artifactId>
<version>${glassfish-jaxb.version}</version> <version>${glassfish-jaxb.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId> <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.amazonaws</groupId> <groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId> <artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.261</version> <version>1.12.261</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.amazonaws</groupId> <groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId> <artifactId>aws-java-sdk-sts</artifactId>
<version>1.12.261</version> <version>1.12.261</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.datatype</groupId> <groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId> <artifactId>jackson-datatype-jsr310</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId> <artifactId>spring-boot-starter-aop</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId> <artifactId>dom4j</artifactId>
<version>2.1.3</version> <version>2.1.3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>jaxen</groupId> <groupId>jaxen</groupId>
<artifactId>jaxen</artifactId> <artifactId>jaxen</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.bouncycastle</groupId> <groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId> <artifactId>bcpkix-jdk15on</artifactId>
<version>1.69</version> <version>1.69</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId> <artifactId>spring-boot-starter-validation</artifactId>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui -->
</dependencies> <dependency>
<groupId>org.springdoc</groupId>
<build> <artifactId>springdoc-openapi-ui</artifactId>
<plugins> <version>1.7.0</version>
<plugin> </dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> </dependencies>
<configuration>
<excludes> <build>
<exclude> <plugins>
<groupId>org.projectlombok</groupId> <plugin>
<artifactId>lombok</artifactId> <groupId>org.springframework.boot</groupId>
</exclude> <artifactId>spring-boot-maven-plugin</artifactId>
</excludes> <configuration>
</configuration> <excludes>
</plugin> <exclude>
</plugins> <groupId>org.projectlombok</groupId>
</build> <artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project> </project>

6
sql/cloud_sample.sql

@ -21,7 +21,7 @@ CREATE TABLE `logs_file` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT, `id` bigint unsigned NOT NULL AUTO_INCREMENT,
`file_id` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'uuid', `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.', `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.', `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.', `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', `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', `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', `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.', `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.', `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, `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.', `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, `id` int unsigned NOT NULL AUTO_INCREMENT,
`file_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'uuid', `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_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.', `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.', `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.', `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.',

3
src/main/java/com/dji/sample/CloudApiSampleApplication.java

@ -3,12 +3,13 @@ package com.dji.sample;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
@MapperScan("com.dji.sample.*.dao") @MapperScan("com.dji.sample.*.dao")
@SpringBootApplication @SpringBootApplication
@EnableScheduling @EnableScheduling
//@EnableConfigurationProperties(OssConfiguration.class) @ComponentScan("com.dji")
public class CloudApiSampleApplication { public class CloudApiSampleApplication {
public static void main(String[] args) { public static void main(String[] args) {

7
src/main/java/com/dji/sample/common/error/CommonErrorEnum.java

@ -1,5 +1,7 @@
package com.dji.sample.common.error; package com.dji.sample.common.error;
import com.dji.sdk.common.IErrorInfo;
/** /**
* @author sean.zhou * @author sean.zhou
* @version 0.1 * @version 0.1
@ -43,12 +45,13 @@ public enum CommonErrorEnum implements IErrorInfo {
} }
@Override @Override
public String getErrorMsg() { public String getMessage() {
return this.msg; return this.msg;
} }
@Override @Override
public Integer getErrorCode() { public Integer getCode() {
return this.code; return this.code;
} }
} }

78
src/main/java/com/dji/sample/common/error/LiveErrorEnum.java

@ -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;
}
}

36
src/main/java/com/dji/sample/common/model/Pagination.java

@ -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();
}
}

27
src/main/java/com/dji/sample/common/model/PaginationData.java

@ -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<T> {
/**
* The collection in which the data list is stored.
*/
private List<T> list;
private Pagination pagination;
public PaginationData(List<T> list, Pagination pagination) {
this.list = list;
this.pagination = pagination;
}
}

69
src/main/java/com/dji/sample/common/model/ResponseResult.java

@ -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<T> {
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 <T> ResponseResult<T> success(T data) {
return ResponseResult.<T>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();
}
}

2
src/main/java/com/dji/sample/common/util/JwtUtil.java

@ -105,7 +105,7 @@ public class JwtUtil {
} }
if (Objects.nonNull(age)) { if (Objects.nonNull(age)) {
builder.withExpiresAt(new Date(now.getTime() + age * 1000)); builder.withExpiresAt(new Date(now.getTime() + age));
} }
String token = builder String token = builder

30
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> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
public static Object getBean(String beanName) {
return applicationContext.getBean(beanName);
}
}

19
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.RedisConst;
import com.dji.sample.component.redis.RedisOpsUtils; 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.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.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Optional;
/** /**
* @author sean.zhou * @author sean.zhou
* @date 2021/11/24 * @date 2021/11/24
@ -18,6 +24,9 @@ public class ApplicationBootInitial implements CommandLineRunner {
@Autowired @Autowired
private IDeviceService deviceService; private IDeviceService deviceService;
@Autowired
private IDeviceRedisService deviceRedisService;
/** /**
* Subscribe to the devices that exist in the redis when the program starts, * 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. * 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(); int start = RedisConst.DEVICE_ONLINE_PREFIX.length();
RedisOpsUtils.getAllKeys(RedisConst.DEVICE_ONLINE_PREFIX + "*") 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))));
} }
} }

4
src/main/java/com/dji/sample/component/AuthInterceptor.java

@ -26,7 +26,7 @@ public class AuthInterceptor implements HandlerInterceptor {
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String uri = request.getRequestURI(); String uri = request.getRequestURI();
log.debug("request uri: {}", uri); log.debug("request uri: {}, IP: {}", uri, request.getRemoteAddr());
// The options method is passed directly. // The options method is passed directly.
if (HttpMethod.OPTIONS.matches(request.getMethod())) { if (HttpMethod.OPTIONS.matches(request.getMethod())) {
response.setStatus(HttpStatus.OK.value()); response.setStatus(HttpStatus.OK.value());
@ -36,7 +36,7 @@ public class AuthInterceptor implements HandlerInterceptor {
// Check if the token exists. // Check if the token exists.
if (!StringUtils.hasText(token)) { if (!StringUtils.hasText(token)) {
response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setStatus(HttpStatus.UNAUTHORIZED.value());
log.error(CommonErrorEnum.NO_TOKEN.getErrorMsg()); log.error(CommonErrorEnum.NO_TOKEN.getMessage());
return false; return false;
} }

14
src/main/java/com/dji/sample/component/GlobalExceptionHandler.java

@ -1,6 +1,6 @@
package com.dji.sample.component; 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.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ControllerAdvice;
@ -22,21 +22,21 @@ public class GlobalExceptionHandler {
* @return * @return
*/ */
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
public ResponseResult exceptionHandler(Exception e) { public HttpResultResponse exceptionHandler(Exception e) {
e.printStackTrace(); e.printStackTrace();
return ResponseResult.error(e.getLocalizedMessage()); return HttpResultResponse.error(e.getLocalizedMessage());
} }
@ExceptionHandler(NullPointerException.class) @ExceptionHandler(NullPointerException.class)
public ResponseResult nullPointerExceptionHandler(NullPointerException e) { public HttpResultResponse nullPointerExceptionHandler(NullPointerException e) {
e.printStackTrace(); e.printStackTrace();
return ResponseResult.error("A null object appeared."); return HttpResultResponse.error("A null object appeared.");
} }
@ExceptionHandler({MethodArgumentNotValidException.class, BindException.class}) @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
public ResponseResult methodArgumentNotValidExceptionHandler(BindException e) { public HttpResultResponse methodArgumentNotValidExceptionHandler(BindException e) {
e.printStackTrace(); e.printStackTrace();
return ResponseResult.error(e.getFieldError().getField() + e.getFieldError().getDefaultMessage()); return HttpResultResponse.error(e.getFieldError().getField() + e.getFieldError().getDefaultMessage());
} }
} }

18
src/main/java/com/dji/sample/component/GlobalScheduleService.java

@ -1,12 +1,11 @@
package com.dji.sample.component; 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.RedisConst;
import com.dji.sample.component.redis.RedisOpsUtils; import com.dji.sample.component.redis.RedisOpsUtils;
import com.dji.sample.manage.model.dto.DeviceDTO; 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.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 com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -31,8 +30,6 @@ public class GlobalScheduleService {
@Autowired @Autowired
private IMqttTopicService topicService; private IMqttTopicService topicService;
@Autowired
private IWaylineJobService waylineJobService;
@Autowired @Autowired
private ObjectMapper mapper; private ObjectMapper mapper;
/** /**
@ -46,14 +43,13 @@ public class GlobalScheduleService {
long expire = RedisOpsUtils.getExpire(key); long expire = RedisOpsUtils.getExpire(key);
if (expire <= 30) { if (expire <= 30) {
DeviceDTO device = (DeviceDTO) RedisOpsUtils.get(key); 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)); deviceService.subDeviceOffline(key.substring(start));
} else { } else {
deviceService.unsubscribeTopicOffline(key.substring(start)); deviceService.gatewayOffline(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());
} }
RedisOpsUtils.del(key); RedisOpsUtils.del(key);
} }

145
src/main/java/com/dji/sample/component/mqtt/config/MqttMessageChannel.java

@ -1,6 +1,6 @@
package com.dji.sample.component.mqtt.config; 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.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -27,18 +27,13 @@ public class MqttMessageChannel {
return new ExecutorChannel(threadPool); return new ExecutorChannel(threadPool);
} }
@Bean(name = ChannelName.INBOUND_STATUS) @Bean(name = ChannelName.DEFAULT)
public MessageChannel statusChannel() { public MessageChannel defaultChannel() {
return new DirectChannel();
}
@Bean(name = ChannelName.INBOUND_STATUS_ONLINE)
public MessageChannel statusOnlineChannel() {
return new DirectChannel(); return new DirectChannel();
} }
@Bean(name = ChannelName.INBOUND_STATUS_OFFLINE) @Bean(name = ChannelName.INBOUND_STATUS)
public MessageChannel statusOffChannel() { public MessageChannel statusChannel() {
return new DirectChannel(); return new DirectChannel();
} }
@ -47,158 +42,34 @@ public class MqttMessageChannel {
return new DirectChannel(); return new DirectChannel();
} }
@Bean(name = ChannelName.INBOUND_STATE_BASIC) @Bean(name = ChannelName.INBOUND_SERVICES_REPLY)
public MessageChannel stateBasicChannel() {
return new DirectChannel();
}
@Bean(name = ChannelName.INBOUND_STATE_PAYLOAD)
public MessageChannel statePayloadChannel() {
return new DirectChannel();
}
@Bean(name = ChannelName.INBOUND_SERVICE_REPLY)
public MessageChannel serviceReplyChannel() { public MessageChannel serviceReplyChannel() {
return new DirectChannel(); 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) @Bean(name = ChannelName.INBOUND_OSD)
public MessageChannel osdChannel() { public MessageChannel osdChannel() {
return new ExecutorChannel(threadPool); 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) @Bean(name = ChannelName.INBOUND_REQUESTS)
public MessageChannel requestsChannel() { public MessageChannel requestsChannel() {
return new DirectChannel(); return new DirectChannel();
} }
@Bean(name = ChannelName.INBOUND_REQUESTS_STORAGE_CONFIG_GET)
public MessageChannel requestsConfigGetChannel() {
return new DirectChannel();
}
@Bean(name = ChannelName.INBOUND_EVENTS) @Bean(name = ChannelName.INBOUND_EVENTS)
public MessageChannel eventsChannel() { public MessageChannel eventsChannel() {
return new DirectChannel(); 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) @Bean(name = ChannelName.INBOUND_PROPERTY_SET_REPLY)
public MessageChannel propertySetReply() { public MessageChannel propertySetReply() {
return new DirectChannel(); return new DirectChannel();
} }
@Bean(name = ChannelName.INBOUND_REQUESTS_CONFIG) @Bean(name = ChannelName.INBOUND_DRC_UP)
public MessageChannel requestsConfig() { public MessageChannel drcUp() {
return new DirectChannel(); 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();
}
} }

47
src/main/java/com/dji/sample/component/mqtt/config/MqttOutboundConfiguration.java

@ -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;
}
}

22
src/main/java/com/dji/sample/component/mqtt/config/MqttConfiguration.java → 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.MqttClientOptions;
import com.dji.sample.component.mqtt.model.MqttProtocolEnum; import com.dji.sample.component.mqtt.model.MqttProtocolEnum;
import com.dji.sample.component.mqtt.model.MqttUseEnum; 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 lombok.Data;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@ -26,12 +26,12 @@ import java.util.Map;
@Configuration @Configuration
@Data @Data
@ConfigurationProperties @ConfigurationProperties
public class MqttConfiguration { public class MqttPropertyConfiguration {
private static Map<MqttUseEnum, MqttClientOptions> mqtt; private static Map<MqttUseEnum, MqttClientOptions> mqtt;
public void setMqtt(Map<MqttUseEnum, MqttClientOptions> mqtt) { public void setMqtt(Map<MqttUseEnum, MqttClientOptions> mqtt) {
MqttConfiguration.mqtt = mqtt; MqttPropertyConfiguration.mqtt = mqtt;
} }
/** /**
@ -79,7 +79,7 @@ public class MqttConfiguration {
* @param map Custom data added in token. * @param map Custom data added in token.
* @return * @return
*/ */
public static MqttBrokerDTO getMqttBrokerWithDrc(String clientId, String username, Long age, Map<String, ?> map) { public static DrcModeMqttBroker getMqttBrokerWithDrc(String clientId, String username, Long age, Map<String, ?> map) {
if (!mqtt.containsKey(MqttUseEnum.DRC)) { if (!mqtt.containsKey(MqttUseEnum.DRC)) {
throw new RuntimeException("Please configure the drc link parameters of mqtt in the backend configuration file first."); 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); String token = JwtUtil.createToken(map, age, algorithm, null, null);
return MqttBrokerDTO.builder() return new DrcModeMqttBroker()
.address(getMqttAddress(mqtt.get(MqttUseEnum.DRC))) .setAddress(getMqttAddress(mqtt.get(MqttUseEnum.DRC)))
.username(username) .setUsername(username)
.clientId(clientId) .setClientId(clientId)
.expireTime(System.currentTimeMillis() / 1000 + age) .setExpireTime(System.currentTimeMillis() / 1000 + age)
.password(token) .setPassword(token)
.build(); .setEnableTls(false);
} }

39
src/main/java/com/dji/sample/component/mqtt/handler/AbstractStateTopicHandler.java

@ -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<String, Object> dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException;
}

68
src/main/java/com/dji/sample/component/mqtt/handler/EventsRouter.java

@ -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)
.<byte[], CommonTopicReceiver>transform(payload -> {
try {
return mapper.readValue(payload, CommonTopicReceiver.class);
} catch (IOException e) {
e.printStackTrace();
}
return new CommonTopicReceiver();
})
.<CommonTopicReceiver, EventsMethodEnum>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());
}
}

40
src/main/java/com/dji/sample/component/mqtt/handler/PropertySetReplyHandler.java

@ -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<CommonTopicReceiver>() {});
Chan<CommonTopicReceiver<?>> chan = Chan.getInstance();
// Put the message to the chan object.
chan.put(receiver);
}
}

45
src/main/java/com/dji/sample/component/mqtt/handler/RequestsRouter.java

@ -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)
.<byte[], CommonTopicReceiver>transform(payload -> {
try {
return mapper.readValue(payload, CommonTopicReceiver.class);
} catch (IOException e) {
e.printStackTrace();
}
return new CommonTopicReceiver();
})
.<CommonTopicReceiver, RequestsMethodEnum>route(
receiver -> RequestsMethodEnum.find(receiver.getMethod()),
mapping -> Arrays.stream(RequestsMethodEnum.values()).forEach(
methodEnum -> mapping.channelMapping(methodEnum, methodEnum.getChannelName())))
.get();
}
}

53
src/main/java/com/dji/sample/component/mqtt/handler/ServicesReplyHandler.java

@ -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<CommonTopicReceiver>() {});
ServiceReply reply;
if (LogsFileMethodEnum.FILE_UPLOAD_LIST.getMethod().equals(receiver.getMethod())) {
LogsFileUploadList list = mapper.convertValue(receiver.getData(), new TypeReference<LogsFileUploadList>() {});
reply = new ServiceReply();
reply.setResult(list.getResult());
reply.setOutput(list.getFiles());
} else {
reply = mapper.convertValue(receiver.getData(), new TypeReference<ServiceReply>() {});
}
receiver.setData(reply);
Chan<CommonTopicReceiver<?>> chan = Chan.getInstance();
// Put the message to the chan object.
chan.put(receiver);
}
}

26
src/main/java/com/dji/sample/component/mqtt/handler/StateDefaultHandler.java

@ -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<String, Object> dataNode, CommonTopicReceiver stateReceiver, String sn) throws JsonProcessingException {
// If no suitable handler is found for the data, it is not processed.
return stateReceiver;
}
}

38
src/main/java/com/dji/sample/component/mqtt/handler/StateDeviceBasicHandler.java

@ -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<String, Object> 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);
}
}

62
src/main/java/com/dji/sample/component/mqtt/handler/StateFirmwareVersionHandler.java

@ -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<String, Object> 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<String> 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<String, String>)(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);
}
}

39
src/main/java/com/dji/sample/component/mqtt/handler/StateLiveCapacityHandler.java

@ -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<String, Object> 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);
}
}

104
src/main/java/com/dji/sample/component/mqtt/handler/StateRouter.java

@ -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<String, Object> data = (Map<String, Object>) (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<Object> splitState(CommonTopicReceiver receiver) {
ArrayList<Object> 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;
}
}

67
src/main/java/com/dji/sample/component/mqtt/handler/StatusRouter.java

@ -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<StatusGatewayReceiver> resolveStatus(Message<?> message) {
CommonTopicReceiver<StatusGatewayReceiver> statusReceiver = new CommonTopicReceiver<>();
try {
statusReceiver = mapper.readValue(
(byte[])message.getPayload(),
new TypeReference<CommonTopicReceiver<StatusGatewayReceiver>>() {});
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<StatusGatewayReceiver> 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;
}
}

45
src/main/java/com/dji/sample/component/mqtt/model/Chan.java

@ -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<T> {
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<>();
}
}

91
src/main/java/com/dji/sample/component/mqtt/model/ChannelName.java

@ -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";
}

34
src/main/java/com/dji/sample/component/mqtt/model/CommonTopicReceiver.java

@ -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<T> {
/**
* 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;
}

35
src/main/java/com/dji/sample/component/mqtt/model/CommonTopicResponse.java

@ -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<T> {
/**
* 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;
}

32
src/main/java/com/dji/sample/component/mqtt/model/ConfigScopeEnum.java

@ -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<? extends IRequestsConfigService> clazz;
ConfigScopeEnum(String scope, Class<? extends IRequestsConfigService> clazz) {
this.scope = scope;
this.clazz = clazz;
}
public static Optional<ConfigScopeEnum> find(String scope) {
return Arrays.stream(ConfigScopeEnum.values()).filter(scopeEnum -> scopeEnum.scope.equals(scope)).findAny();
}
}

23
src/main/java/com/dji/sample/component/mqtt/model/ErrorInfoReply.java

@ -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);
}
}

83
src/main/java/com/dji/sample/component/mqtt/model/EventsMethodEnum.java

@ -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);
}
}

18
src/main/java/com/dji/sample/component/mqtt/model/EventsOutputProgressReceiver.java

@ -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<T> {
private String status;
private OutputProgressReceiver progress;
private T ext;
}

53
src/main/java/com/dji/sample/component/mqtt/model/EventsReceiver.java

@ -1,29 +1,64 @@
package com.dji.sample.component.mqtt.model; 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 com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor; import lombok.*;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/** /**
* @author sean * @author sean
* @version 1.1 * @version 1.1
* @date 2022/6/9 * @date 2022/6/9
*/ */
@EqualsAndHashCode(callSuper = true)
@Data @Data
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class EventsReceiver<T> { public class EventsReceiver<T> extends EventsDataRequest<T> {
private Integer result;
private T output;
private String bid; private String bid;
private String sn; private String sn;
@Override
public EventsErrorCode getResult() {
return super.getResult();
}
@Override
public EventsReceiver<T> setResult(EventsErrorCode result) {
super.setResult(result);
return this;
}
@Override
public T getOutput() {
return super.getOutput();
}
@Override
public EventsReceiver<T> setOutput(T output) {
super.setOutput(output);
return this;
}
public String getBid() {
return bid;
}
public EventsReceiver<T> setBid(String bid) {
this.bid = bid;
return this;
}
public String getSn() {
return sn;
}
public EventsReceiver<T> setSn(String sn) {
this.sn = sn;
return this;
}
} }

49
src/main/java/com/dji/sample/component/mqtt/model/EventsResultStatusEnum.java

@ -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);
}
}

22
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"; public static final String ACL = "acl";
} }

2
src/main/java/com/dji/sample/component/mqtt/model/MqttProtocolEnum.java

@ -12,7 +12,7 @@ public enum MqttProtocolEnum {
MQTT("tcp"), MQTT("tcp"),
MQTTS("tcp"), MQTTS("ssl"),
WS("ws"), WS("ws"),

18
src/main/java/com/dji/sample/component/mqtt/model/OutputProgressReceiver.java

@ -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;
}

44
src/main/java/com/dji/sample/component/mqtt/model/RequestsMethodEnum.java

@ -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);
}
}

44
src/main/java/com/dji/sample/component/mqtt/model/RequestsReply.java

@ -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<T> {
private Integer result;
private T output;
public static RequestsReply error(IErrorInfo errorInfo) {
return RequestsReply.builder()
.result(errorInfo.getErrorCode())
.output(errorInfo.getErrorMsg())
.build();
}
public static <T> 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();
}
}

20
src/main/java/com/dji/sample/component/mqtt/model/ServiceReply.java

@ -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<T> {
private Integer result;
private T info;
private T output;
}

14
src/main/java/com/dji/sample/component/mqtt/model/SetReply.java

@ -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;
}

30
src/main/java/com/dji/sample/component/mqtt/model/SetReplyStatusResultEnum.java

@ -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;
}
}

26
src/main/java/com/dji/sample/component/mqtt/model/StateDataEnum.java

@ -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;
}
}

90
src/main/java/com/dji/sample/component/mqtt/service/IMessageSenderService.java

@ -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> T publishWithReply(Class<T> clazz, String topic, CommonTopicResponse response);
/**
* Send message and receive a response at the same time.
* @param clazz
* @param topic
* @param response
* @param retryTime
* @param <T>
* @return
*/
<T> T publishWithReply(Class<T> 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 <T>
* @return
*/
<T> ServiceReply<T> publishServicesTopic(TypeReference<T> 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 <T>
* @return
*/
<T> ServiceReply<T> publishServicesTopic(TypeReference<T> 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);
}

116
src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java

@ -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> T publishWithReply(Class<T> clazz, String topic, CommonTopicResponse response) {
return this.publishWithReply(clazz, topic, response, 2);
}
public <T> T publishWithReply(Class<T> clazz, String topic, CommonTopicResponse response, int retryTime) {
AtomicInteger time = new AtomicInteger(0);
// Retry three times
while (time.getAndIncrement() <= retryTime) {
this.publish(topic, response);
Chan<CommonTopicReceiver<T>> chan = Chan.getInstance();
// If the message is not received in 0.5 seconds then resend it again.
CommonTopicReceiver<T> 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 <T> ServiceReply<T> publishServicesTopic(TypeReference<T> 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 <T> ServiceReply<T> publishServicesTopic(TypeReference<T> 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);
}
}

44
src/main/java/com/dji/sample/component/mqtt/service/impl/MqttTopicServiceImpl.java

@ -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();
}
}

7
src/main/java/com/dji/sample/component/oss/model/OssConfiguration.java

@ -1,5 +1,6 @@
package com.dji.sample.component.oss.model; package com.dji.sample.component.oss.model;
import com.dji.sdk.cloudapi.storage.OssTypeEnum;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -13,9 +14,9 @@ import org.springframework.stereotype.Component;
public class OssConfiguration { 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. * Whether to use the object storage service.
@ -43,7 +44,7 @@ public class OssConfiguration {
public static String objectDirPrefix; public static String objectDirPrefix;
public void setProvider(String provider) { public void setProvider(OssTypeEnum provider) {
OssConfiguration.provider = provider; OssConfiguration.provider = provider;
} }

7
src/main/java/com/dji/sample/component/oss/service/IOssService.java

@ -1,6 +1,7 @@
package com.dji.sample.component.oss.service; 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.io.InputStream;
import java.net.URL; import java.net.URL;
@ -12,13 +13,13 @@ import java.net.URL;
*/ */
public interface IOssService { public interface IOssService {
String getOssType(); OssTypeEnum getOssType();
/** /**
* Get temporary credentials. * Get temporary credentials.
* @return * @return
*/ */
CredentialsDTO getCredentials(); CredentialsToken getCredentials();
/** /**
* Get the address of the object based on the bucket name and the object name. * Get the address of the object based on the bucket name and the object name.

14
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.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse; import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.dji.sample.component.oss.model.OssConfiguration; 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.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 lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -36,12 +36,12 @@ public class AliyunOssServiceImpl implements IOssService {
private OSS ossClient; private OSS ossClient;
@Override @Override
public String getOssType() { public OssTypeEnum getOssType() {
return OssTypeEnum.ALIYUN.getType(); return OssTypeEnum.ALIYUN;
} }
@Override @Override
public CredentialsDTO getCredentials() { public CredentialsToken getCredentials() {
try { try {
DefaultProfile profile = DefaultProfile.getProfile( DefaultProfile profile = DefaultProfile.getProfile(
@ -54,7 +54,7 @@ public class AliyunOssServiceImpl implements IOssService {
request.setRoleSessionName(OssConfiguration.roleSessionName); request.setRoleSessionName(OssConfiguration.roleSessionName);
AssumeRoleResponse response = client.getAcsResponse(request); AssumeRoleResponse response = client.getAcsResponse(request);
return new CredentialsDTO(response.getCredentials(), OssConfiguration.expire); return new CredentialsToken(response.getCredentials(), OssConfiguration.expire);
} catch (ClientException e) { } catch (ClientException e) {
log.debug("Failed to obtain sts."); log.debug("Failed to obtain sts.");
@ -95,7 +95,7 @@ public class AliyunOssServiceImpl implements IOssService {
throw new RuntimeException("The filename already exists."); throw new RuntimeException("The filename already exists.");
} }
PutObjectResult objectResult = ossClient.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata())); 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() { public void createClient() {

14
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.amazonaws.services.securitytoken.model.Credentials;
import com.dji.sample.component.AuthInterceptor; import com.dji.sample.component.AuthInterceptor;
import com.dji.sample.component.oss.model.OssConfiguration; 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.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 lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -39,12 +39,12 @@ public class AmazonS3ServiceImpl implements IOssService {
private AmazonS3 client; private AmazonS3 client;
@Override @Override
public String getOssType() { public OssTypeEnum getOssType() {
return OssTypeEnum.AWS.getType(); return OssTypeEnum.AWS;
} }
@Override @Override
public CredentialsDTO getCredentials() { public CredentialsToken getCredentials() {
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard() AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider( .withCredentials(new AWSStaticCredentialsProvider(
new BasicAWSCredentials(OssConfiguration.accessKey, OssConfiguration.secretKey))) new BasicAWSCredentials(OssConfiguration.accessKey, OssConfiguration.secretKey)))
@ -56,7 +56,7 @@ public class AmazonS3ServiceImpl implements IOssService {
.withDurationSeconds(Math.toIntExact(OssConfiguration.expire)); .withDurationSeconds(Math.toIntExact(OssConfiguration.expire));
AssumeRoleResult result = stsClient.assumeRole(request); AssumeRoleResult result = stsClient.assumeRole(request);
Credentials credentials = result.getCredentials(); Credentials credentials = result.getCredentials();
return new CredentialsDTO(credentials); return new CredentialsToken(credentials);
} }
@Override @Override
@ -84,7 +84,7 @@ public class AmazonS3ServiceImpl implements IOssService {
throw new RuntimeException("The filename already exists."); throw new RuntimeException("The filename already exists.");
} }
PutObjectResult objectResult = client.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata())); 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() { public void createClient() {

16
src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java

@ -1,9 +1,9 @@
package com.dji.sample.component.oss.service.impl; package com.dji.sample.component.oss.service.impl;
import com.dji.sample.component.oss.model.OssConfiguration; 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.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.*;
import io.minio.credentials.AssumeRoleProvider; import io.minio.credentials.AssumeRoleProvider;
import io.minio.errors.*; import io.minio.errors.*;
@ -31,17 +31,17 @@ public class MinIOServiceImpl implements IOssService {
private MinioClient client; private MinioClient client;
@Override @Override
public String getOssType() { public OssTypeEnum getOssType() {
return OssTypeEnum.MINIO.getType(); return OssTypeEnum.MINIO;
} }
@Override @Override
public CredentialsDTO getCredentials() { public CredentialsToken getCredentials() {
try { try {
AssumeRoleProvider provider = new AssumeRoleProvider(OssConfiguration.endpoint, OssConfiguration.accessKey, AssumeRoleProvider provider = new AssumeRoleProvider(OssConfiguration.endpoint, OssConfiguration.accessKey,
OssConfiguration.secretKey, Math.toIntExact(OssConfiguration.expire), OssConfiguration.secretKey, Math.toIntExact(OssConfiguration.expire),
null, OssConfiguration.region, null, null, null, null); null, OssConfiguration.region, null, null, null, null);
return new CredentialsDTO(provider.fetch(), OssConfiguration.expire); return new CredentialsToken(provider.fetch(), OssConfiguration.expire);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
log.debug("Failed to obtain sts."); log.debug("Failed to obtain sts.");
e.printStackTrace(); e.printStackTrace();
@ -100,9 +100,9 @@ public class MinIOServiceImpl implements IOssService {
try { try {
ObjectWriteResponse response = client.putObject( ObjectWriteResponse response = client.putObject(
PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(input, input.available(), 0).build()); 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) { } catch (MinioException | IOException | InvalidKeyException | NoSuchAlgorithmException ex) {
log.error("Failed to upload File {}.", objectKey); log.error("Failed to upload FlighttaskCreateFile {}.", objectKey);
ex.printStackTrace(); ex.printStackTrace();
} }
} }

8
src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java

@ -1,9 +1,9 @@
package com.dji.sample.component.oss.service.impl; package com.dji.sample.component.oss.service.impl;
import com.dji.sample.component.oss.model.OssConfiguration; 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.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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -29,7 +29,7 @@ public class OssServiceContext {
return; return;
} }
this.ossService = ossServices.stream() this.ossService = ossServices.stream()
.filter(ossService -> ossService.getOssType().equals(OssConfiguration.provider)) .filter(ossService -> ossService.getOssType() == OssConfiguration.provider)
.findFirst() .findFirst()
.orElseThrow(() -> new IllegalArgumentException("Oss provider is illegal. Optional: " + .orElseThrow(() -> new IllegalArgumentException("Oss provider is illegal. Optional: " +
Arrays.toString(Arrays.stream(OssTypeEnum.values()).map(OssTypeEnum::getType).toArray()))); Arrays.toString(Arrays.stream(OssTypeEnum.values()).map(OssTypeEnum::getType).toArray())));
@ -39,7 +39,7 @@ public class OssServiceContext {
return this.ossService; return this.ossService;
} }
public CredentialsDTO getCredentials() { public CredentialsToken getCredentials() {
return this.ossService.getCredentials(); return this.ossService.getCredentials();
} }

12
src/main/java/com/dji/sample/component/redis/RedisConst.java

@ -1,7 +1,5 @@
package com.dji.sample.component.redis; package com.dji.sample.component.redis;
import com.dji.sample.manage.model.enums.DeviceDomainEnum;
/** /**
* @author sean * @author sean
* @version 1.0 * @version 1.0
@ -21,9 +19,7 @@ public final class RedisConst {
public static final Integer WEBSOCKET_ALIVE_SECOND = 60 * 60 * 24; 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" + DELIMITER;
public static final String DEVICE_ONLINE_PREFIX = ONLINE_PREFIX + DeviceDomainEnum.SUB_DEVICE + DELIMITER;
public static final String WEBSOCKET_PREFIX = "webSocket" + 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 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; public static final String WAYLINE_JOB_BLOCK_PREFIX = "wayline_job_block" + DELIMITER;

25
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);
}
}

8
src/main/java/com/dji/sample/component/websocket/config/WebSocketDefaultFactory.java → src/main/java/com/dji/sample/component/websocket/config/MyWebSocketFactory.java

@ -1,10 +1,11 @@
package com.dji.sample.component.websocket.config; package com.dji.sample.component.websocket.config;
import com.dji.sample.component.websocket.service.IWebSocketManageService; import com.dji.sample.component.websocket.service.IWebSocketManageService;
import com.dji.sdk.websocket.WebSocketDefaultFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler; 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 * @version 0.1
*/ */
@Component @Component
public class WebSocketDefaultFactory implements WebSocketHandlerDecoratorFactory { @Primary
public class MyWebSocketFactory extends WebSocketDefaultFactory {
@Autowired @Autowired
private IWebSocketManageService webSocketManageService; private IWebSocketManageService webSocketManageService;
@Override @Override
public WebSocketHandler decorate(WebSocketHandler handler) { public WebSocketHandler decorate(WebSocketHandler handler) {
return new WebSocketDefaultHandler(handler, webSocketManageService); return new MyWebSocketHandler(handler, webSocketManageService);
} }
} }

8
src/main/java/com/dji/sample/component/websocket/config/WebSocketDefaultHandler.java → src/main/java/com/dji/sample/component/websocket/config/MyWebSocketHandler.java

@ -1,13 +1,13 @@
package com.dji.sample.component.websocket.config; package com.dji.sample.component.websocket.config;
import com.dji.sample.component.websocket.service.IWebSocketManageService; import com.dji.sample.component.websocket.service.IWebSocketManageService;
import com.dji.sdk.websocket.WebSocketDefaultHandler;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage; import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
import java.security.Principal; import java.security.Principal;
@ -18,11 +18,11 @@ import java.security.Principal;
* @version 0.1 * @version 0.1
*/ */
@Slf4j @Slf4j
public class WebSocketDefaultHandler extends WebSocketHandlerDecorator { public class MyWebSocketHandler extends WebSocketDefaultHandler {
private IWebSocketManageService webSocketManageService; private IWebSocketManageService webSocketManageService;
WebSocketDefaultHandler(WebSocketHandler delegate, IWebSocketManageService webSocketManageService) { MyWebSocketHandler(WebSocketHandler delegate, IWebSocketManageService webSocketManageService) {
super(delegate); super(delegate);
this.webSocketManageService = webSocketManageService; this.webSocketManageService = webSocketManageService;
} }
@ -31,7 +31,7 @@ public class WebSocketDefaultHandler extends WebSocketHandlerDecorator {
public void afterConnectionEstablished(WebSocketSession session) throws Exception { public void afterConnectionEstablished(WebSocketSession session) throws Exception {
Principal principal = session.getPrincipal(); Principal principal = session.getPrincipal();
if (StringUtils.hasText(principal.getName())) { 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: {}]", log.debug("{} is connected. ID: {}. WebSocketSession[current count: {}]",
principal.getName(), session.getId(), webSocketManageService.getConnectedCount()); principal.getName(), session.getId(), webSocketManageService.getConnectedCount());
return; return;

2
src/main/java/com/dji/sample/component/websocket/model/BizCodeEnum.java

@ -15,7 +15,7 @@ public enum BizCodeEnum {
DEVICE_OSD("device_osd"), DEVICE_OSD("device_osd"),
GATEWAY_OSD("gateway_osd"), RC_OSD("gateway_osd"),
DOCK_OSD("dock_osd"), DOCK_OSD("dock_osd"),

30
src/main/java/com/dji/sample/component/websocket/model/CustomWebSocketMessage.java

@ -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<T> {
/**
* @see BizCodeEnum
* specific value
*/
@JsonProperty("biz_code")
private String bizCode;
@Builder.Default
private String version = "1.0";
private Long timestamp;
private T data;
}

8
src/main/java/com/dji/sample/component/websocket/service/IWebSocketManageService.java

@ -1,6 +1,6 @@
package com.dji.sample.component.websocket.service; 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; import java.util.Collection;
@ -11,13 +11,13 @@ import java.util.Collection;
*/ */
public interface IWebSocketManageService { public interface IWebSocketManageService {
void put(String key, ConcurrentWebSocketSession val); void put(String key, MyConcurrentWebSocketSession val);
void remove(String key, String sessionId); void remove(String key, String sessionId);
Collection<ConcurrentWebSocketSession> getValueWithWorkspace(String workspaceId); Collection<MyConcurrentWebSocketSession> getValueWithWorkspace(String workspaceId);
Collection<ConcurrentWebSocketSession> getValueWithWorkspaceAndUserType(String workspaceId, Integer userType); Collection<MyConcurrentWebSocketSession> getValueWithWorkspaceAndUserType(String workspaceId, Integer userType);
Long getConnectedCount(); Long getConnectedCount();
} }

10
src/main/java/com/dji/sample/component/websocket/service/ISendMessageService.java → src/main/java/com/dji/sample/component/websocket/service/IWebSocketMessageService.java

@ -1,7 +1,7 @@
package com.dji.sample.component.websocket.service; package com.dji.sample.component.websocket.service;
import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession; import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession;
import com.dji.sample.component.websocket.model.CustomWebSocketMessage; import com.dji.sdk.websocket.WebSocketMessageResponse;
import java.util.Collection; import java.util.Collection;
@ -10,21 +10,21 @@ import java.util.Collection;
* @date 2021/11/24 * @date 2021/11/24
* @version 0.1 * @version 0.1
*/ */
public interface ISendMessageService { public interface IWebSocketMessageService {
/** /**
* Send a message to the specific connection. * Send a message to the specific connection.
* @param session A WebSocket connection object * @param session A WebSocket connection object
* @param message message * @param message message
*/ */
void sendMessage(ConcurrentWebSocketSession session, CustomWebSocketMessage message); void sendMessage(MyConcurrentWebSocketSession session, WebSocketMessageResponse message);
/** /**
* Send the same message to specific connection. * Send the same message to specific connection.
* @param sessions A collection of WebSocket connection objects. * @param sessions A collection of WebSocket connection objects.
* @param message message * @param message message
*/ */
void sendBatch(Collection<ConcurrentWebSocketSession> sessions, CustomWebSocketMessage message); void sendBatch(Collection<MyConcurrentWebSocketSession> sessions, WebSocketMessageResponse message);
void sendBatch(String workspaceId, Integer userType, String bizCode, Object data); void sendBatch(String workspaceId, Integer userType, String bizCode, Object data);

14
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.RedisConst;
import com.dji.sample.component.redis.RedisOpsUtils; 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.component.websocket.service.IWebSocketManageService;
import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.model.enums.UserTypeEnum;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -24,10 +24,10 @@ import java.util.stream.Collectors;
@Service @Service
public class WebSocketManageServiceImpl implements IWebSocketManageService { public class WebSocketManageServiceImpl implements IWebSocketManageService {
private static final ConcurrentHashMap<String, ConcurrentWebSocketSession> SESSIONS = new ConcurrentHashMap<>(16); private static final ConcurrentHashMap<String, MyConcurrentWebSocketSession> SESSIONS = new ConcurrentHashMap<>(16);
@Override @Override
public void put(String key, ConcurrentWebSocketSession val) { public void put(String key, MyConcurrentWebSocketSession val) {
String[] name = key.split("/"); String[] name = key.split("/");
if (name.length != 3) { if (name.length != 3) {
log.debug("The key is out of format. [{workspaceId}/{userType}/{userId}]"); log.debug("The key is out of format. [{workspaceId}/{userType}/{userId}]");
@ -56,7 +56,7 @@ public class WebSocketManageServiceImpl implements IWebSocketManageService {
} }
@Override @Override
public Collection<ConcurrentWebSocketSession> getValueWithWorkspace(String workspaceId) { public Collection<MyConcurrentWebSocketSession> getValueWithWorkspace(String workspaceId) {
if (!StringUtils.hasText(workspaceId)) { if (!StringUtils.hasText(workspaceId)) {
return Collections.emptySet(); return Collections.emptySet();
} }
@ -70,12 +70,12 @@ public class WebSocketManageServiceImpl implements IWebSocketManageService {
} }
@Override @Override
public Collection<ConcurrentWebSocketSession> getValueWithWorkspaceAndUserType(String workspaceId, Integer userType) { public Collection<MyConcurrentWebSocketSession> getValueWithWorkspaceAndUserType(String workspaceId, Integer userType) {
String key = RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(userType).getDesc(); String key = RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(userType).getDesc();
return RedisOpsUtils.hashKeys(key) return RedisOpsUtils.hashKeys(key)
.stream() .stream()
.map(SESSIONS::get) .map(SESSIONS::get)
.filter(this.getValueWithWorkspace(workspaceId)::contains) .filter(getValueWithWorkspace(workspaceId)::contains)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }

25
src/main/java/com/dji/sample/component/websocket/service/impl/SendMessageServiceImpl.java → src/main/java/com/dji/sample/component/websocket/service/impl/WebSocketMessageServiceImpl.java

@ -1,9 +1,9 @@
package com.dji.sample.component.websocket.service.impl; package com.dji.sample.component.websocket.service.impl;
import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession; import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession;
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.IWebSocketManageService;
import com.dji.sample.component.websocket.service.IWebSocketMessageService;
import com.dji.sdk.websocket.WebSocketMessageResponse;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -22,7 +22,7 @@ import java.util.Objects;
*/ */
@Service @Service
@Slf4j @Slf4j
public class SendMessageServiceImpl implements ISendMessageService { public class WebSocketMessageServiceImpl implements IWebSocketMessageService {
@Autowired @Autowired
private ObjectMapper mapper; private ObjectMapper mapper;
@ -31,7 +31,7 @@ public class SendMessageServiceImpl implements ISendMessageService {
private IWebSocketManageService webSocketManageService; private IWebSocketManageService webSocketManageService;
@Override @Override
public void sendMessage(ConcurrentWebSocketSession session, CustomWebSocketMessage message) { public void sendMessage(MyConcurrentWebSocketSession session, WebSocketMessageResponse message) {
if (session == null) { if (session == null) {
return; return;
} }
@ -52,7 +52,7 @@ public class SendMessageServiceImpl implements ISendMessageService {
} }
@Override @Override
public void sendBatch(Collection<ConcurrentWebSocketSession> sessions, CustomWebSocketMessage message) { public void sendBatch(Collection<MyConcurrentWebSocketSession> sessions, WebSocketMessageResponse message) {
if (sessions.isEmpty()) { if (sessions.isEmpty()) {
return; return;
} }
@ -61,7 +61,7 @@ public class SendMessageServiceImpl implements ISendMessageService {
TextMessage data = new TextMessage(mapper.writeValueAsBytes(message)); TextMessage data = new TextMessage(mapper.writeValueAsBytes(message));
for (ConcurrentWebSocketSession session : sessions) { for (MyConcurrentWebSocketSession session : sessions) {
if (!session.isOpen()) { if (!session.isOpen()) {
session.close(); session.close();
log.debug("This session is closed."); log.debug("This session is closed.");
@ -82,15 +82,14 @@ public class SendMessageServiceImpl implements ISendMessageService {
if (!StringUtils.hasText(workspaceId)) { if (!StringUtils.hasText(workspaceId)) {
throw new RuntimeException("Workspace ID does not exist."); throw new RuntimeException("Workspace ID does not exist.");
} }
Collection<ConcurrentWebSocketSession> sessions = Objects.isNull(userType) ? Collection<MyConcurrentWebSocketSession> sessions = Objects.isNull(userType) ?
webSocketManageService.getValueWithWorkspace(workspaceId) : webSocketManageService.getValueWithWorkspace(workspaceId) :
webSocketManageService.getValueWithWorkspaceAndUserType(workspaceId, userType); webSocketManageService.getValueWithWorkspaceAndUserType(workspaceId, userType);
this.sendBatch(sessions, CustomWebSocketMessage.builder() this.sendBatch(sessions, new WebSocketMessageResponse()
.data(data) .setData(Objects.requireNonNullElse(data, ""))
.timestamp(System.currentTimeMillis()) .setTimestamp(System.currentTimeMillis())
.bizCode(bizCode) .setBizCode(bizCode));
.build());
} }
@Override @Override

1
src/main/java/com/dji/sample/configuration/SpringBeanConfiguration.java

@ -23,7 +23,6 @@ public class SpringBeanConfiguration {
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build(); ObjectMapper objectMapper = builder.createXmlMapper(false).build();
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
JavaTimeModule timeModule = new JavaTimeModule(); JavaTimeModule timeModule = new JavaTimeModule();

53
src/main/java/com/dji/sample/configuration/mvc/GetSnakeDataBinder.java

@ -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<PropertyValue> propertyValueList = mpvs.getPropertyValueList();
List<PropertyValue> 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();
}
}

14
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.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration; 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.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ -29,14 +28,13 @@ public class GlobalMVCConfigurer implements WebMvcConfigurer {
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
// Exclude the login interface. // Exclude the login interface.
excludePaths.add(managePrefix + manageVersion + "/login"); excludePaths.add("/" + managePrefix + manageVersion + "/login");
excludePaths.add(managePrefix + manageVersion + "/token/refresh"); 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. // Intercept for all request interfaces.
registry.addInterceptor(authInterceptor).addPathPatterns("/**").excludePathPatterns(excludePaths); registry.addInterceptor(authInterceptor).addPathPatterns("/**").excludePathPatterns(excludePaths);
} }
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new GetSnakeArgumentProcessor(true));
}
} }

23
src/main/java/com/dji/sample/control/controller/DockController.java

@ -1,9 +1,10 @@
package com.dji.sample.control.controller; 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.DroneAuthorityEnum;
import com.dji.sample.control.model.enums.RemoteDebugMethodEnum;
import com.dji.sample.control.model.param.*; import com.dji.sample.control.model.param.*;
import com.dji.sample.control.service.IControlService; import com.dji.sample.control.service.IControlService;
import com.dji.sdk.common.HttpResultResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -24,39 +25,39 @@ public class DockController {
private IControlService controlService; private IControlService controlService;
@PostMapping("/{sn}/jobs/{service_identifier}") @PostMapping("/{sn}/jobs/{service_identifier}")
public ResponseResult createControlJob(@PathVariable String sn, public HttpResultResponse createControlJob(@PathVariable String sn,
@PathVariable("service_identifier") String serviceIdentifier, @PathVariable("service_identifier") String serviceIdentifier,
@RequestBody(required = false) RemoteDebugParam param) { @Valid @RequestBody(required = false) RemoteDebugParam param) {
return controlService.controlDockDebug(sn, serviceIdentifier, param); return controlService.controlDockDebug(sn, RemoteDebugMethodEnum.find(serviceIdentifier), param);
} }
@PostMapping("/{sn}/jobs/fly-to-point") @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); return controlService.flyToPoint(sn, param);
} }
@DeleteMapping("/{sn}/jobs/fly-to-point") @DeleteMapping("/{sn}/jobs/fly-to-point")
public ResponseResult flyToPointStop(@PathVariable String sn) { public HttpResultResponse flyToPointStop(@PathVariable String sn) {
return controlService.flyToPointStop(sn); return controlService.flyToPointStop(sn);
} }
@PostMapping("/{sn}/jobs/takeoff-to-point") @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); return controlService.takeoffToPoint(sn, param);
} }
@PostMapping("/{sn}/authority/flight") @PostMapping("/{sn}/authority/flight")
public ResponseResult seizeFlightAuthority(@PathVariable String sn) { public HttpResultResponse seizeFlightAuthority(@PathVariable String sn) {
return controlService.seizeAuthority(sn, DroneAuthorityEnum.FLIGHT, null); return controlService.seizeAuthority(sn, DroneAuthorityEnum.FLIGHT, null);
} }
@PostMapping("/{sn}/authority/payload") @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); return controlService.seizeAuthority(sn, DroneAuthorityEnum.PAYLOAD, param);
} }
@PostMapping("/{sn}/payload/commands") @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); param.setSn(sn);
return controlService.payloadCommands(param); return controlService.payloadCommands(param);
} }

18
src/main/java/com/dji/sample/control/controller/DrcController.java

@ -1,12 +1,12 @@
package com.dji.sample.control.controller; package com.dji.sample.control.controller;
import com.dji.sample.common.model.CustomClaim; 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.JwtAclDTO;
import com.dji.sample.control.model.dto.MqttBrokerDTO;
import com.dji.sample.control.model.param.DrcConnectParam; import com.dji.sample.control.model.param.DrcConnectParam;
import com.dji.sample.control.model.param.DrcModeParam; import com.dji.sample.control.model.param.DrcModeParam;
import com.dji.sample.control.service.IDrcService; 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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -30,25 +30,25 @@ public class DrcController {
private IDrcService drcService; private IDrcService drcService;
@PostMapping("/workspaces/{workspace_id}/drc/connect") @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); CustomClaim claims = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
MqttBrokerDTO brokerDTO = drcService.userDrcAuth(workspaceId, claims.getId(), claims.getUsername(), param); DrcModeMqttBroker brokerDTO = drcService.userDrcAuth(workspaceId, claims.getId(), claims.getUsername(), param);
return ResponseResult.success(brokerDTO); return HttpResultResponse.success(brokerDTO);
} }
@PostMapping("/workspaces/{workspace_id}/drc/enter") @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); JwtAclDTO acl = drcService.deviceDrcEnter(workspaceId, param);
return ResponseResult.success(acl); return HttpResultResponse.success(acl);
} }
@PostMapping("/workspaces/{workspace_id}/drc/exit") @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); drcService.deviceDrcExit(workspaceId, param);
return ResponseResult.success(); return HttpResultResponse.success();
} }

22
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;
}

10
src/main/java/com/dji/sample/control/model/dto/AlarmState.java

@ -1,14 +1,12 @@
package com.dji.sample.control.model.dto; package com.dji.sample.control.model.dto;
import com.dji.sample.control.service.impl.RemoteDebugHandler; 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.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.Objects;
/** /**
* @author sean * @author sean
* @version 1.3 * @version 1.3
@ -20,10 +18,6 @@ import java.util.Objects;
@NoArgsConstructor @NoArgsConstructor
public class AlarmState extends RemoteDebugHandler { public class AlarmState extends RemoteDebugHandler {
private Integer action; private SwitchActionEnum action;
@Override
public boolean valid() {
return Objects.nonNull(action) && StateSwitchEnum.find(action).isPresent();
}
} }

11
src/main/java/com/dji/sample/control/model/dto/BatteryStoreMode.java

@ -1,14 +1,12 @@
package com.dji.sample.control.model.dto; 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.sample.control.service.impl.RemoteDebugHandler;
import com.dji.sdk.cloudapi.device.BatteryStoreModeEnum;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.Objects;
/** /**
* @author sean * @author sean
* @version 1.3 * @version 1.3
@ -20,10 +18,5 @@ import java.util.Objects;
@NoArgsConstructor @NoArgsConstructor
public class BatteryStoreMode extends RemoteDebugHandler { public class BatteryStoreMode extends RemoteDebugHandler {
private Integer action; private BatteryStoreModeEnum action;
@Override
public boolean valid() {
return Objects.nonNull(action) && BatteryStoreModeEnum.find(action).isPresent();
}
} }

32
src/main/java/com/dji/sample/control/model/dto/DrcModeDTO.java

@ -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;
}

15
src/main/java/com/dji/sample/control/model/dto/DrcModeReasonReceiver.java

@ -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;
}

18
src/main/java/com/dji/sample/control/model/dto/DrcStatusNotifyReceiver.java

@ -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;
}

22
src/main/java/com/dji/sample/control/model/dto/FlyToProgressReceiver.java

@ -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;
}

22
src/main/java/com/dji/sample/control/model/dto/LinkWorkMode.java

@ -1,14 +1,15 @@
package com.dji.sample.control.model.dto; 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.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 com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor; import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.Objects; import java.util.Map;
/** /**
* @author sean * @author sean
@ -17,15 +18,18 @@ import java.util.Objects;
*/ */
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data @Data
@AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public class LinkWorkMode extends RemoteDebugHandler { public class LinkWorkMode extends RemoteDebugHandler {
@JsonProperty("link_workmode") private LinkWorkModeEnum linkWorkMode;
private Integer linkWorkMode;
@Override @JsonCreator
public boolean valid() { public LinkWorkMode(@JsonProperty("action") Integer linkWorkMode) {
return Objects.nonNull(linkWorkMode) && LinkWorkModeEnum.find(linkWorkMode).isPresent(); this.linkWorkMode = LinkWorkModeEnum.find(linkWorkMode);
}
@JsonValue
public Map toMap() {
return Map.of("link_workmode", linkWorkMode.getMode());
} }
} }

31
src/main/java/com/dji/sample/control/model/dto/MqttBrokerDTO.java

@ -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;
}

31
src/main/java/com/dji/sample/control/model/dto/PointDTO.java

@ -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;
}

6
src/main/java/com/dji/sample/control/model/dto/RemoteDebugOpenState.java

@ -1,9 +1,9 @@
package com.dji.sample.control.model.dto; 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.control.service.impl.RemoteDebugHandler;
import com.dji.sample.manage.model.enums.DockModeCodeEnum;
import com.dji.sample.manage.service.IDeviceService; import com.dji.sample.manage.service.IDeviceService;
import com.dji.sdk.cloudapi.device.DockModeCodeEnum;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -18,7 +18,7 @@ public class RemoteDebugOpenState extends RemoteDebugHandler {
@Override @Override
public boolean canPublish(String sn) { public boolean canPublish(String sn) {
IDeviceService deviceService = SpringBeanUtils.getBean(IDeviceService.class); IDeviceService deviceService = SpringBeanUtilsTest.getBean(IDeviceService.class);
DockModeCodeEnum dockMode = deviceService.getDockMode(sn); DockModeCodeEnum dockMode = deviceService.getDockMode(sn);
return DockModeCodeEnum.IDLE == dockMode; return DockModeCodeEnum.IDLE == dockMode;
} }

28
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);
}
}

19
src/main/java/com/dji/sample/control/model/dto/ReturnHomeState.java

@ -1,10 +1,11 @@
package com.dji.sample.control.model.dto; 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.control.service.impl.RemoteDebugHandler;
import com.dji.sample.manage.model.dto.DeviceDTO; 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.sample.manage.service.IDeviceRedisService;
import com.dji.sdk.cloudapi.device.DroneModeCodeEnum;
import com.dji.sdk.cloudapi.device.OsdDockDrone;
/** /**
* @author sean * @author sean
@ -16,12 +17,18 @@ public class ReturnHomeState extends RemoteDebugHandler {
@Override @Override
public boolean canPublish(String sn) { public boolean canPublish(String sn) {
IDeviceRedisService deviceRedisService = SpringBeanUtils.getBean(IDeviceRedisService.class); IDeviceRedisService deviceRedisService = SpringBeanUtilsTest.getBean(IDeviceRedisService.class);
return deviceRedisService.getDeviceOnline(sn) return deviceRedisService.getDeviceOnline(sn)
.map(DeviceDTO::getChildDeviceSn) .map(DeviceDTO::getChildDeviceSn)
.flatMap(deviceSn -> deviceRedisService.getDeviceOsd(deviceSn, OsdSubDeviceReceiver.class)) .flatMap(deviceSn -> deviceRedisService.getDeviceOsd(deviceSn, OsdDockDrone.class))
.map(OsdSubDeviceReceiver::getElevation) .map(osd -> osd.getElevation() > 0 && modeCodeCanReturnHome(osd.getModeCode()))
.map(elevation -> elevation > 0)
.orElse(false); .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;
}
} }

25
src/main/java/com/dji/sample/control/model/dto/TakeoffProgressReceiver.java

@ -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;
}

29
src/main/java/com/dji/sample/control/model/enums/BatteryStoreModeEnum.java

@ -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<BatteryStoreModeEnum> find(int mode) {
return Arrays.stream(BatteryStoreModeEnum.values()).filter(modeEnum -> modeEnum.mode == mode).findAny();
}
}

26
src/main/java/com/dji/sample/control/model/enums/CameraStateEnum.java

@ -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();
}
}

29
src/main/java/com/dji/sample/control/model/enums/LinkWorkModeEnum.java

@ -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<LinkWorkModeEnum> find(int mode) {
return Arrays.stream(LinkWorkModeEnum.values()).filter(modeEnum -> modeEnum.mode == mode).findAny();
}
}

32
src/main/java/com/dji/sample/control/model/enums/PayloadCommandsEnum.java

@ -1,6 +1,7 @@
package com.dji.sample.control.model.enums; package com.dji.sample.control.model.enums;
import com.dji.sample.control.service.impl.*; 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.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.annotation.JsonValue;
@ -13,40 +14,45 @@ import java.util.Arrays;
*/ */
public enum PayloadCommandsEnum { 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<? extends PayloadCommandsHandler> clazz; Class<? extends PayloadCommandsHandler> clazz;
PayloadCommandsEnum(String cmd, Class<? extends PayloadCommandsHandler> clazz) { PayloadCommandsEnum(PayloadControlMethodEnum cmd, Class<? extends PayloadCommandsHandler> clazz) {
this.cmd = cmd; this.cmd = cmd;
this.clazz = clazz; this.clazz = clazz;
} }
@JsonValue @JsonValue
public String getCmd() { public String getMethod() {
return cmd; return cmd.getPayloadMethod().getMethod();
} }
public Class<? extends PayloadCommandsHandler> getClazz() { public Class<? extends PayloadCommandsHandler> getClazz() {
return clazz; return clazz;
} }
public PayloadControlMethodEnum getCmd() {
return cmd;
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING) @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static PayloadCommandsEnum find(String cmd) { public static PayloadCommandsEnum find(String method) {
return Arrays.stream(values()).filter(cmdEnum -> cmdEnum.cmd.equals(cmd)).findAny().get(); return Arrays.stream(values()).filter(methodEnum -> methodEnum.cmd.getPayloadMethod().getMethod().equals(method)).findAny()
.orElseThrow();
} }
} }

74
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.model.dto.*;
import com.dji.sample.control.service.impl.RemoteDebugHandler; 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 lombok.Getter;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
/** /**
* @author sean * @author sean
@ -14,67 +17,80 @@ import java.util.Arrays;
@Getter @Getter
public enum RemoteDebugMethodEnum { 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), 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), BATTERY_MAINTENANCE_SWITCH(DebugMethodEnum.BATTERY_MAINTENANCE_SWITCH, false, AlarmState.class),
ALARM_STATE_SWITCH("alarm_state_switch", true, AlarmState.class),
BATTERY_STORE_MODE_SWITCH("battery_store_mode_switch", true, BatteryStoreMode.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 String method;
private Boolean progress; private boolean progress;
private Class<? extends RemoteDebugHandler> clazz; private Class<? extends RemoteDebugHandler> clazz;
RemoteDebugMethodEnum(String method, Boolean progress, Class<? extends RemoteDebugHandler> clazz) { RemoteDebugMethodEnum(DebugMethodEnum debugMethodEnum, boolean progress, Class<? extends RemoteDebugHandler> clazz) {
this.method = method; this.debugMethodEnum = debugMethodEnum;
this.progress = progress; this.progress = progress;
this.clazz = clazz; this.clazz = clazz;
this.method = debugMethodEnum.getMethod();
}
RemoteDebugMethodEnum(String method, boolean progress, Class<? extends RemoteDebugHandler> clazz) {
this.debugMethodEnum = null;
this.progress = progress;
this.clazz = clazz;
this.method = method;
} }
@JsonCreator
public static RemoteDebugMethodEnum find(String method) { public static RemoteDebugMethodEnum find(String method) {
return Arrays.stream(RemoteDebugMethodEnum.values()) return Arrays.stream(values())
.filter(methodEnum -> methodEnum.method.equals(method)) .filter(methodEnum -> methodEnum.method.equals(method)
|| (Objects.nonNull(methodEnum.debugMethodEnum)
&& methodEnum.debugMethodEnum.getMethod().equals(method)))
.findAny() .findAny()
.orElse(UNKNOWN); .orElseThrow();
} }
} }

2
src/main/java/com/dji/sample/control/model/param/DrcModeParam.java

@ -28,8 +28,10 @@ public class DrcModeParam {
private String dockSn; private String dockSn;
@Range(min = 1800, max = 86400) @Range(min = 1800, max = 86400)
@Builder.Default
private long expireSec = RedisConst.DRC_MODE_ALIVE_SECOND; private long expireSec = RedisConst.DRC_MODE_ALIVE_SECOND;
@Valid @Valid
@Builder.Default
private DeviceDrcInfoParam deviceInfo = new DeviceDrcInfoParam(); private DeviceDrcInfoParam deviceInfo = new DeviceDrcInfoParam();
} }

6
src/main/java/com/dji/sample/control/model/param/DronePayloadParam.java

@ -1,8 +1,8 @@
package com.dji.sample.control.model.param; package com.dji.sample.control.model.param;
import com.dji.sample.control.model.enums.CameraModeEnum; import com.dji.sdk.cloudapi.control.CameraTypeEnum;
import com.dji.sample.control.model.enums.CameraTypeEnum; import com.dji.sdk.cloudapi.control.GimbalResetModeEnum;
import com.dji.sample.control.model.enums.GimbalResetModeEnum; import com.dji.sdk.cloudapi.device.CameraModeEnum;
import lombok.Data; import lombok.Data;
import org.hibernate.validator.constraints.Range; import org.hibernate.validator.constraints.Range;

4
src/main/java/com/dji/sample/control/model/param/FlyToPointParam.java

@ -1,6 +1,6 @@
package com.dji.sample.control.model.param; 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.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -33,5 +33,5 @@ public class FlyToPointParam {
@Size(min = 1) @Size(min = 1)
@Valid @Valid
@NotNull @NotNull
private List<PointDTO> points; private List<Point> points;
} }

3
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 lombok.Data;
import javax.validation.constraints.NotNull;
/** /**
* @author sean * @author sean
* @version 1.3 * @version 1.3
@ -10,6 +12,7 @@ import lombok.Data;
@Data @Data
public class RemoteDebugParam { public class RemoteDebugParam {
@NotNull
private Integer action; private Integer action;
} }

25
src/main/java/com/dji/sample/control/model/param/TakeoffToPointParam.java

@ -1,10 +1,15 @@
package com.dji.sample.control.model.param; package com.dji.sample.control.model.param;
import com.dji.sample.manage.model.enums.DroneRcLostActionEnum; import com.dji.sdk.cloudapi.control.CommanderFlightModeEnum;
import com.dji.sample.manage.model.enums.WaylineRcLostActionEnum; 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 lombok.Data;
import org.hibernate.validator.constraints.Range; import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
/** /**
@ -25,7 +30,7 @@ public class TakeoffToPointParam {
@NotNull @NotNull
private Double targetLatitude; private Double targetLatitude;
@Range(min = 2, max = 1500) @Range(min = 2, max = 10000)
@NotNull @NotNull
private Double targetHeight; private Double targetHeight;
@ -38,12 +43,22 @@ public class TakeoffToPointParam {
private Double rthAltitude; private Double rthAltitude;
@NotNull @NotNull
private DroneRcLostActionEnum rcLostAction; private RcLostActionEnum rcLostAction;
@NotNull @NotNull
private WaylineRcLostActionEnum exitWaylineWhenRcLost; private ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost;
@Range(min = 1, max = 15) @Range(min = 1, max = 15)
@NotNull @NotNull
private Double maxSpeed; private Double maxSpeed;
private RthModeEnum rthMode;
private CommanderModeLostActionEnum commanderModeLostAction;
private CommanderFlightModeEnum commanderFlightMode;
@Min(2)
@Max(3000)
private Float commanderFlightHeight;
} }

27
src/main/java/com/dji/sample/control/service/IControlService.java

@ -1,10 +1,9 @@
package com.dji.sample.control.service; 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.DroneAuthorityEnum;
import com.dji.sample.control.model.enums.RemoteDebugMethodEnum;
import com.dji.sample.control.model.param.*; import com.dji.sample.control.model.param.*;
import org.springframework.messaging.MessageHeaders; import com.dji.sdk.common.HttpResultResponse;
/** /**
* @author sean * @author sean
@ -20,7 +19,7 @@ public interface IControlService {
* @param param * @param param
* @return * @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. * Make the drone fly to the target point.
@ -28,14 +27,14 @@ public interface IControlService {
* @param param * @param param
* @return * @return
*/ */
ResponseResult flyToPoint(String sn, FlyToPointParam param); HttpResultResponse flyToPoint(String sn, FlyToPointParam param);
/** /**
* End the mission of flying the drone to the target point. * End the mission of flying the drone to the target point.
* @param sn * @param sn
* @return * @return
*/ */
ResponseResult flyToPointStop(String sn); HttpResultResponse flyToPointStop(String sn);
/** /**
* Handle progress result notifications for fly to target point. * Handle progress result notifications for fly to target point.
@ -43,7 +42,7 @@ public interface IControlService {
* @param headers * @param headers
* @return * @return
*/ */
CommonTopicReceiver handleFlyToPointProgress(CommonTopicReceiver receiver, MessageHeaders headers); // CommonTopicReceiver handleFlyToPointProgress(CommonTopicReceiver receiver, MessageHeaders headers);
/** /**
* Control the drone to take off. * Control the drone to take off.
@ -51,15 +50,7 @@ public interface IControlService {
* @param param * @param param
* @return * @return
*/ */
ResponseResult takeoffToPoint(String sn, TakeoffToPointParam param); HttpResultResponse 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);
/** /**
* Seize the control authority of the drone or the payload control authority. * Seize the control authority of the drone or the payload control authority.
@ -68,12 +59,12 @@ public interface IControlService {
* @param param * @param param
* @return * @return
*/ */
ResponseResult seizeAuthority(String sn, DroneAuthorityEnum authority, DronePayloadParam param); HttpResultResponse seizeAuthority(String sn, DroneAuthorityEnum authority, DronePayloadParam param);
/** /**
* Control the payload of the drone. * Control the payload of the drone.
* @param param * @param param
* @return * @return
*/ */
ResponseResult payloadCommands(PayloadCommandsParam param) throws Exception; HttpResultResponse payloadCommands(PayloadCommandsParam param) throws Exception;
} }

4
src/main/java/com/dji/sample/control/service/IDrcService.java

@ -1,9 +1,9 @@
package com.dji.sample.control.service; package com.dji.sample.control.service;
import com.dji.sample.control.model.dto.JwtAclDTO; 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.DrcConnectParam;
import com.dji.sample.control.model.param.DrcModeParam; import com.dji.sample.control.model.param.DrcModeParam;
import com.dji.sdk.cloudapi.control.DrcModeMqttBroker;
/** /**
* @author sean * @author sean
@ -41,7 +41,7 @@ public interface IDrcService {
* @param param * @param param
* @return * @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. * Make the dock enter drc mode. And grant relevant permissions.

7
src/main/java/com/dji/sample/control/service/impl/CameraFocalLengthSetImpl.java

@ -1,8 +1,8 @@
package com.dji.sample.control.service.impl; 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.sample.control.model.param.DronePayloadParam;
import com.dji.sdk.cloudapi.control.CameraTypeEnum;
import com.dji.sdk.cloudapi.device.CameraStateEnum;
import java.util.Objects; import java.util.Objects;
@ -32,7 +32,8 @@ public class CameraFocalLengthSetImpl extends PayloadCommandsHandler {
} }
switch (param.getCameraType()) { switch (param.getCameraType()) {
case IR: case IR:
return param.getZoomFactor().intValue() != osdCamera.getIrZoomFactor(); return Objects.nonNull(osdCamera.getIrZoomFactor())
&& param.getZoomFactor().intValue() != osdCamera.getIrZoomFactor();
case ZOOM: case ZOOM:
return param.getZoomFactor().intValue() != osdCamera.getZoomFactor(); return param.getZoomFactor().intValue() != osdCamera.getZoomFactor();
} }

2
src/main/java/com/dji/sample/control/service/impl/CameraModeSwitchImpl.java

@ -1,7 +1,7 @@
package com.dji.sample.control.service.impl; 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.sample.control.model.param.DronePayloadParam;
import com.dji.sdk.cloudapi.device.CameraStateEnum;
import java.util.Objects; import java.util.Objects;

2
src/main/java/com/dji/sample/control/service/impl/CameraPhotoTakeImpl.java

@ -1,7 +1,7 @@
package com.dji.sample.control.service.impl; 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.sample.control.model.param.DronePayloadParam;
import com.dji.sdk.cloudapi.device.CameraStateEnum;
/** /**
* @author sean * @author sean

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save