diff --git a/api/Cloud API Demo.postman_collection.json b/api/Cloud API Demo.postman_collection.json
index 9c96972..b9af814 100644
--- a/api/Cloud API Demo.postman_collection.json
+++ b/api/Cloud API Demo.postman_collection.json
@@ -703,6 +703,36 @@
}
},
"response": []
+ },
+ {
+ "name": "Set Property",
+ "request": {
+ "method": "PUT",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\r\n \"night_lights_state\": 0\r\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{base_url}}{{manage_version}}/devices/{{workspace_id}}/devices/{{device_sn}}/property",
+ "host": [
+ "{{base_url}}{{manage_version}}"
+ ],
+ "path": [
+ "devices",
+ "{{workspace_id}}",
+ "devices",
+ "{{device_sn}}",
+ "property"
+ ]
+ }
+ },
+ "response": []
}
],
"auth": {
@@ -710,7 +740,7 @@
"apikey": [
{
"key": "value",
- "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ3b3Jrc3BhY2VfaWQiOiJlM2RlYTBmNS0zN2YyLTRkNzktYWU1OC00OTBhZjMyMjgwNjkiLCJzdWIiOiJDbG91ZEFwaVNhbXBsZSIsInVzZXJfdHlwZSI6IjEiLCJuYmYiOjE2NjM1NTkxMTAsImxvZyI6IkxvZ2dlcltjb20uZGppLnNhbXBsZS5jb21tb24ubW9kZWwuQ3VzdG9tQ2xhaW1dIiwiaXNzIjoiREpJIiwiaWQiOiJhMTU1OWU3Yy04ZGQ4LTQ3ODAtYjk1Mi0xMDBjYzQ3OTdkYTIiLCJleHAiOjE2NjM2NDU1MTAsImlhdCI6MTY2MzU1OTExMCwidXNlcm5hbWUiOiJhZG1pblBDIn0.LG1JXZkuTdMaqnXn5WMJvnysNkHHbc4HLe_qZPWz_nM",
+ "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ3b3Jrc3BhY2VfaWQiOiJlM2RlYTBmNS0zN2YyLTRkNzktYWU1OC00OTBhZjMyMjgwNjkiLCJzdWIiOiJDbG91ZEFwaVNhbXBsZSIsInVzZXJfdHlwZSI6IjEiLCJuYmYiOjE2Njc0NzcwNTUsImxvZyI6IkxvZ2dlcltjb20uZGppLnNhbXBsZS5jb21tb24ubW9kZWwuQ3VzdG9tQ2xhaW1dIiwiaXNzIjoiREpJIiwiaWQiOiJhMTU1OWU3Yy04ZGQ4LTQ3ODAtYjk1Mi0xMDBjYzQ3OTdkYTIiLCJleHAiOjE2Njc1NjM0NTUsImlhdCI6MTY2NzQ3NzA1NSwidXNlcm5hbWUiOiJhZG1pblBDIn0.VMJ0ZKn895uvkMDjg2fw3p4trVCUx9ltVFKeP7QmYpo",
"type": "string"
},
{
@@ -1322,6 +1352,37 @@
}
},
"response": []
+ },
+ {
+ "name": "Import KMZ File",
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "formdata",
+ "formdata": [
+ {
+ "key": "file",
+ "type": "file",
+ "src": []
+ }
+ ]
+ },
+ "url": {
+ "raw": "{{base_url}}{{wayline_version}}/workspaces/{{workspace_id}}/waylines/file/upload",
+ "host": [
+ "{{base_url}}{{wayline_version}}"
+ ],
+ "path": [
+ "workspaces",
+ "{{workspace_id}}",
+ "waylines",
+ "file",
+ "upload"
+ ]
+ }
+ },
+ "response": []
}
],
"auth": {
@@ -1329,7 +1390,7 @@
"apikey": [
{
"key": "value",
- "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ3b3Jrc3BhY2VfaWQiOiJlM2RlYTBmNS0zN2YyLTRkNzktYWU1OC00OTBhZjMyMjgwNjkiLCJzdWIiOiJDbG91ZEFwaVNhbXBsZSIsInVzZXJfdHlwZSI6IjEiLCJuYmYiOjE2NTU0NDk2MDIsImxvZyI6IkxvZ2dlcltjb20uZGppLnNhbXBsZS5jb21tb24ubW9kZWwuQ3VzdG9tQ2xhaW1dIiwiaXNzIjoiREpJIiwiaWQiOiJhMTU1OWU3Yy04ZGQ4LTQ3ODAtYjk1Mi0xMDBjYzQ3OTdkYTIiLCJleHAiOjE2NTU1MzYwMDIsImlhdCI6MTY1NTQ0OTYwMiwidXNlcm5hbWUiOiJhZG1pblBDIn0.YZWHJ65Pl_DT2Ampxk0WC01KD_fNTm_rYVUBIHAZD-4",
+ "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ3b3Jrc3BhY2VfaWQiOiJlM2RlYTBmNS0zN2YyLTRkNzktYWU1OC00OTBhZjMyMjgwNjkiLCJzdWIiOiJDbG91ZEFwaVNhbXBsZSIsInVzZXJfdHlwZSI6IjEiLCJuYmYiOjE2Njc1MzMwNDMsImxvZyI6IkxvZ2dlcltjb20uZGppLnNhbXBsZS5jb21tb24ubW9kZWwuQ3VzdG9tQ2xhaW1dIiwiaXNzIjoiREpJIiwiaWQiOiJhMTU1OWU3Yy04ZGQ4LTQ3ODAtYjk1Mi0xMDBjYzQ3OTdkYTIiLCJleHAiOjE2Njc2MTk0NDMsImlhdCI6MTY2NzUzMzA0MywidXNlcm5hbWUiOiJhZG1pblBDIn0.es0boeLSuSD8ysMft7OP701zYuaAHlrmf68iNCvqvnw",
"type": "string"
},
{
diff --git a/pom.xml b/pom.xml
index e71dc5f..ee1fe8c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
com.dji
cloud-api-sample
- 1.1.0
+ 1.3.0-beta2
cloud-api-sample
@@ -156,6 +156,17 @@
org.springframework.boot
spring-boot-starter-aop
+
+
+ org.dom4j
+ dom4j
+ 2.1.3
+
+
+
+ jaxen
+ jaxen
+
diff --git a/src/main/java/com/dji/sample/common/util/JwtUtil.java b/src/main/java/com/dji/sample/common/util/JwtUtil.java
index 629cea1..918f1d7 100644
--- a/src/main/java/com/dji/sample/common/util/JwtUtil.java
+++ b/src/main/java/com/dji/sample/common/util/JwtUtil.java
@@ -2,7 +2,6 @@ package com.dji.sample.common.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
-import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
@@ -85,14 +84,7 @@ public class JwtUtil {
* @throws TokenExpiredException
*/
public static DecodedJWT verifyToken(String token) {
- try {
- JWTVerifier verifier = JWT.require(algorithm).build();
- return verifier.verify(token);
- } catch (Exception e) {
- log.error(e.getMessage());
- e.printStackTrace();
- return null;
- }
+ return JWT.require(algorithm).build().verify(token);
}
/**
@@ -101,7 +93,13 @@ public class JwtUtil {
* @return custom claim
*/
public static Optional parseToken(String token) {
- DecodedJWT jwt = verifyToken(token);
- return jwt == null ? Optional.empty() : Optional.of(new CustomClaim(jwt.getClaims()));
+ DecodedJWT jwt;
+ try {
+ jwt = verifyToken(token);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return Optional.empty();
+ }
+ return Optional.of(new CustomClaim(jwt.getClaims()));
}
}
diff --git a/src/main/java/com/dji/sample/component/mqtt/config/MqttMessageChannel.java b/src/main/java/com/dji/sample/component/mqtt/config/MqttMessageChannel.java
index cbf27e0..2edba07 100644
--- a/src/main/java/com/dji/sample/component/mqtt/config/MqttMessageChannel.java
+++ b/src/main/java/com/dji/sample/component/mqtt/config/MqttMessageChannel.java
@@ -157,4 +157,9 @@ public class MqttMessageChannel {
return new DirectChannel();
}
+ @Bean(name = ChannelName.INBOUND_PROPERTY_SET_REPLY)
+ public MessageChannel propertySetReply() {
+ return new DirectChannel();
+ }
+
}
diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/InboundMessageRouter.java b/src/main/java/com/dji/sample/component/mqtt/handler/InboundMessageRouter.java
index 3047ea5..92458fc 100644
--- a/src/main/java/com/dji/sample/component/mqtt/handler/InboundMessageRouter.java
+++ b/src/main/java/com/dji/sample/component/mqtt/handler/InboundMessageRouter.java
@@ -1,7 +1,10 @@
package com.dji.sample.component.mqtt.handler;
import com.dji.sample.component.mqtt.model.ChannelName;
+import com.dji.sample.component.mqtt.model.DeviceTopicEnum;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
import org.springframework.integration.annotation.Router;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.integration.router.AbstractMessageRouter;
@@ -10,12 +13,9 @@ import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Component;
-import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
-import java.util.regex.Pattern;
-
-import static com.dji.sample.component.mqtt.model.TopicConst.*;
+import java.util.concurrent.ConcurrentHashMap;
/**
*
@@ -27,47 +27,10 @@ import static com.dji.sample.component.mqtt.model.TopicConst.*;
@Slf4j
public class InboundMessageRouter extends AbstractMessageRouter {
- @Resource(name = ChannelName.INBOUND)
- private MessageChannel inboundChannel;
-
- @Resource(name = ChannelName.INBOUND_STATUS)
- private MessageChannel statusChannel;
-
- @Resource(name = ChannelName.INBOUND_STATE)
- private MessageChannel stateChannel;
-
- @Resource(name = ChannelName.DEFAULT)
- private MessageChannel defaultChannel;
-
- @Resource(name = ChannelName.INBOUND_SERVICE_REPLY)
- private MessageChannel serviceReplyChannel;
-
- @Resource(name = ChannelName.INBOUND_OSD)
- private MessageChannel osdChannel;
-
- @Resource(name = ChannelName.INBOUND_REQUESTS)
- private MessageChannel requestsChannel;
-
- @Resource(name = ChannelName.INBOUND_EVENTS)
- private MessageChannel eventsChannel;
-
- private static final Pattern PATTERN_TOPIC_STATUS =
- Pattern.compile("^" + BASIC_PRE + PRODUCT + REGEX_SN + STATUS_SUF + "$");
-
- private static final Pattern PATTERN_TOPIC_STATE =
- Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + STATE_SUF + "$");
-
- private static final Pattern PATTERN_TOPIC_SERVICE_REPLY =
- Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + SERVICES_SUF + _REPLY_SUF + "$");
-
- private static final Pattern PATTERN_TOPIC_OSD =
- Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + OSD_SUF + "$");
+ @Autowired
+ private ApplicationContext applicationContext;
- private static final Pattern PATTERN_TOPIC_REQUESTS =
- Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + REQUESTS_SUF + "$");
-
- private static final Pattern PATTERN_TOPIC_EVENTS =
- Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + EVENTS_SUF + "$");
+ private static final ConcurrentHashMap channels = new ConcurrentHashMap<>(16);
/**
* All mqtt broker messages will arrive here before distributing them to different channels.
@@ -81,38 +44,15 @@ public class InboundMessageRouter extends AbstractMessageRouter {
String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString();
byte[] payload = (byte[])message.getPayload();
- // osd
- if (PATTERN_TOPIC_OSD.matcher(topic).matches()) {
- return Collections.singleton(osdChannel);
- }
-
log.debug("received topic :{} \t payload :{}", topic, new String(payload));
- // status
- if (PATTERN_TOPIC_STATUS.matcher(topic).matches()) {
- return Collections.singleton(statusChannel);
- }
-
- // state
- if (PATTERN_TOPIC_STATE.matcher(topic).matches()) {
- return Collections.singleton(stateChannel);
- }
-
- // services_reply
- if (PATTERN_TOPIC_SERVICE_REPLY.matcher(topic).matches()) {
- return Collections.singleton(serviceReplyChannel);
- }
-
- // requests
- if (PATTERN_TOPIC_REQUESTS.matcher(topic).matches()) {
- return Collections.singleton(requestsChannel);
- }
-
- // events
- if (PATTERN_TOPIC_EVENTS.matcher(topic).matches()) {
- return Collections.singleton(eventsChannel);
+ DeviceTopicEnum topicEnum = DeviceTopicEnum.find(topic);
+ if (channels.containsKey(topicEnum.getBeanName())) {
+ return Collections.singleton(channels.get(topicEnum.getBeanName()));
}
- return Collections.singleton(defaultChannel);
+ MessageChannel bean = (MessageChannel) applicationContext.getBean(topicEnum.getBeanName());
+ channels.put(topicEnum.getBeanName(), bean);
+ return Collections.singleton(bean);
}
}
diff --git a/src/main/java/com/dji/sample/component/mqtt/handler/PropertySetReplyHandler.java b/src/main/java/com/dji/sample/component/mqtt/handler/PropertySetReplyHandler.java
new file mode 100644
index 0000000..9b503eb
--- /dev/null
+++ b/src/main/java/com/dji/sample/component/mqtt/handler/PropertySetReplyHandler.java
@@ -0,0 +1,40 @@
+package com.dji.sample.component.mqtt.handler;
+
+import com.dji.sample.component.mqtt.model.Chan;
+import com.dji.sample.component.mqtt.model.ChannelName;
+import com.dji.sample.component.mqtt.model.CommonTopicReceiver;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.messaging.Message;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+/**
+ * @author sean
+ * @version 1.2
+ * @date 2022/9/9
+ */
+@Component
+public class PropertySetReplyHandler {
+
+ @Autowired
+ private ObjectMapper mapper;
+
+ /**
+ * Handle the reply message from the pilot side to the on-demand video.
+ * @param message reply message
+ * @throws IOException
+ */
+ @ServiceActivator(inputChannel = ChannelName.INBOUND_PROPERTY_SET_REPLY)
+ public void serviceReply(Message> message) throws IOException {
+ byte[] payload = (byte[])message.getPayload();
+
+ CommonTopicReceiver receiver = mapper.readValue(payload, new TypeReference() {});
+ Chan> chan = Chan.getInstance();
+ // Put the message to the chan object.
+ chan.put(receiver);
+ }
+}
diff --git a/src/main/java/com/dji/sample/component/mqtt/model/ChannelName.java b/src/main/java/com/dji/sample/component/mqtt/model/ChannelName.java
index 670ff33..1194493 100644
--- a/src/main/java/com/dji/sample/component/mqtt/model/ChannelName.java
+++ b/src/main/java/com/dji/sample/component/mqtt/model/ChannelName.java
@@ -70,4 +70,6 @@ public class ChannelName {
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";
}
diff --git a/src/main/java/com/dji/sample/component/mqtt/model/DeviceTopicEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/DeviceTopicEnum.java
new file mode 100644
index 0000000..00ab2a7
--- /dev/null
+++ b/src/main/java/com/dji/sample/component/mqtt/model/DeviceTopicEnum.java
@@ -0,0 +1,46 @@
+package com.dji.sample.component.mqtt.model;
+
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+import static com.dji.sample.component.mqtt.model.TopicConst.*;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/10/28
+ */
+@Getter
+public enum DeviceTopicEnum {
+
+ STATUS(Pattern.compile("^" + BASIC_PRE + PRODUCT + REGEX_SN + STATUS_SUF + "$"), ChannelName.INBOUND_STATUS),
+
+ STATE(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + STATE_SUF + "$"), ChannelName.INBOUND_STATE),
+
+ SERVICE_REPLY(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + SERVICES_SUF + _REPLY_SUF + "$"), ChannelName.INBOUND_SERVICE_REPLY),
+
+ OSD(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + OSD_SUF + "$"), ChannelName.INBOUND_OSD),
+
+ REQUESTS(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + REQUESTS_SUF + "$"), ChannelName.INBOUND_REQUESTS),
+
+ EVENTS(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + EVENTS_SUF + "$"), ChannelName.INBOUND_EVENTS),
+
+ PROPERTY_SET_REPLY(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + PROPERTY_SUF + SET_SUF + _REPLY_SUF + "$"), ChannelName.INBOUND_PROPERTY_SET_REPLY),
+
+ UNKNOWN(null, ChannelName.DEFAULT);
+
+ Pattern pattern;
+
+ String beanName;
+
+ DeviceTopicEnum(Pattern pattern, String beanName) {
+ this.pattern = pattern;
+ this.beanName = beanName;
+ }
+
+ public static DeviceTopicEnum find(String topic) {
+ return Arrays.stream(DeviceTopicEnum.values()).filter(topicEnum -> topicEnum.pattern.matcher(topic).matches()).findAny().orElse(UNKNOWN);
+ }
+}
diff --git a/src/main/java/com/dji/sample/component/mqtt/model/EventsResultStatusEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/EventsResultStatusEnum.java
index 321e2f8..dd37ac6 100644
--- a/src/main/java/com/dji/sample/component/mqtt/model/EventsResultStatusEnum.java
+++ b/src/main/java/com/dji/sample/component/mqtt/model/EventsResultStatusEnum.java
@@ -28,6 +28,8 @@ public enum EventsResultStatusEnum {
TIMEOUT("timeout", true),
+ PARTIALLY_DONE("partially_done", true),
+
UNKNOWN("unknown", false);
String desc;
diff --git a/src/main/java/com/dji/sample/component/mqtt/model/SetReply.java b/src/main/java/com/dji/sample/component/mqtt/model/SetReply.java
new file mode 100644
index 0000000..2c7f453
--- /dev/null
+++ b/src/main/java/com/dji/sample/component/mqtt/model/SetReply.java
@@ -0,0 +1,14 @@
+package com.dji.sample.component.mqtt.model;
+
+import lombok.Data;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/10/28
+ */
+@Data
+public class SetReply {
+
+ private Integer result;
+}
diff --git a/src/main/java/com/dji/sample/component/mqtt/model/SetReplyStatusResultEnum.java b/src/main/java/com/dji/sample/component/mqtt/model/SetReplyStatusResultEnum.java
new file mode 100644
index 0000000..5a127e4
--- /dev/null
+++ b/src/main/java/com/dji/sample/component/mqtt/model/SetReplyStatusResultEnum.java
@@ -0,0 +1,30 @@
+package com.dji.sample.component.mqtt.model;
+
+import lombok.Getter;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/10/28
+ */
+@Getter
+public enum SetReplyStatusResultEnum {
+
+ SUCCESS(0, "success"),
+
+ FAILED(1, "failed"),
+
+ TIMEOUT(2, "timeout"),
+
+ UNKNOWN(-1, "unknown");
+
+ int val;
+
+ String desc;
+
+ SetReplyStatusResultEnum(int val, String desc) {
+ this.val = val;
+ this.desc = desc;
+ }
+
+}
diff --git a/src/main/java/com/dji/sample/component/mqtt/model/TopicConst.java b/src/main/java/com/dji/sample/component/mqtt/model/TopicConst.java
index dc9df7c..215995a 100644
--- a/src/main/java/com/dji/sample/component/mqtt/model/TopicConst.java
+++ b/src/main/java/com/dji/sample/component/mqtt/model/TopicConst.java
@@ -28,6 +28,10 @@ public class TopicConst {
public static final String EVENTS_SUF = "/events";
+ public static final String PROPERTY_SUF = "/property";
+
+ public static final String SET_SUF = "/set";
+
public static final String REGEX_SN = "[A-Za-z0-9]+";
}
\ No newline at end of file
diff --git a/src/main/java/com/dji/sample/component/mqtt/service/IMessageSenderService.java b/src/main/java/com/dji/sample/component/mqtt/service/IMessageSenderService.java
index 15079a6..40f7f18 100644
--- a/src/main/java/com/dji/sample/component/mqtt/service/IMessageSenderService.java
+++ b/src/main/java/com/dji/sample/component/mqtt/service/IMessageSenderService.java
@@ -3,8 +3,6 @@ package com.dji.sample.component.mqtt.service;
import com.dji.sample.component.mqtt.model.CommonTopicResponse;
import com.dji.sample.component.mqtt.model.ServiceReply;
-import java.util.Optional;
-
/**
* @author sean.zhou
* @version 0.1
@@ -33,7 +31,7 @@ public interface IMessageSenderService {
* @param response notification of whether the start is successful.
* @return
*/
- Optional publishWithReply(String topic, CommonTopicResponse response);
+ ServiceReply publishWithReply(String topic, CommonTopicResponse response);
/**
* Send live streaming start message and receive a response at the same time.
@@ -44,5 +42,5 @@ public interface IMessageSenderService {
* @param
* @return
*/
- Optional publishWithReply(Class clazz, String topic, CommonTopicResponse response, int retryTime);
+ T publishWithReply(Class clazz, String topic, CommonTopicResponse response, int retryTime);
}
diff --git a/src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java b/src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java
index 10bb7e2..89e5093 100644
--- a/src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java
+++ b/src/main/java/com/dji/sample/component/mqtt/service/impl/MessageSenderServiceImpl.java
@@ -12,7 +12,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -49,28 +48,28 @@ public class MessageSenderServiceImpl implements IMessageSenderService {
}
}
- public Optional publishWithReply(String topic, CommonTopicResponse response) {
+ public ServiceReply publishWithReply(String topic, CommonTopicResponse response) {
return this.publishWithReply(ServiceReply.class, topic, response, 2);
}
- public Optional publishWithReply(Class clazz, String topic, CommonTopicResponse response, int retryTime) {
+ public T publishWithReply(Class clazz, String topic, CommonTopicResponse response, int retryTime) {
AtomicInteger time = new AtomicInteger(0);
// Retry three times
- while (time.getAndIncrement() < retryTime) {
+ while (time.getAndIncrement() <= retryTime) {
this.publish(topic, response);
Chan> chan = Chan.getInstance();
// If the message is not received in 0.5 seconds then resend it again.
- CommonTopicReceiver receiver = chan.get(response.getMethod());
+ CommonTopicReceiver receiver = chan.get(response.getTid());
if (receiver == null) {
continue;
}
// Need to match tid and bid.
if (receiver.getTid().equals(response.getTid()) &&
receiver.getBid().equals(response.getBid())) {
- return Optional.ofNullable(receiver.getData());
+ return receiver.getData();
}
}
- return Optional.empty();
+ throw new RuntimeException("No message reply received.");
}
}
\ No newline at end of file
diff --git a/src/main/java/com/dji/sample/component/oss/service/IOssService.java b/src/main/java/com/dji/sample/component/oss/service/IOssService.java
index 53746ef..f8441dd 100644
--- a/src/main/java/com/dji/sample/component/oss/service/IOssService.java
+++ b/src/main/java/com/dji/sample/component/oss/service/IOssService.java
@@ -2,6 +2,7 @@ package com.dji.sample.component.oss.service;
import com.dji.sample.media.model.CredentialsDTO;
+import java.io.InputStream;
import java.net.URL;
/**
@@ -41,5 +42,7 @@ public interface IOssService {
* @param objectKey
* @return
*/
- byte[] getObject(String bucket, String objectKey);
+ InputStream getObject(String bucket, String objectKey);
+
+ void putObject(String bucket, String objectKey, InputStream input);
}
diff --git a/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java b/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java
index d709b07..d855261 100644
--- a/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java
+++ b/src/main/java/com/dji/sample/component/oss/service/impl/AliyunOssServiceImpl.java
@@ -4,6 +4,9 @@ import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.OSSObject;
+import com.aliyun.oss.model.ObjectMetadata;
+import com.aliyun.oss.model.PutObjectRequest;
+import com.aliyun.oss.model.PutObjectResult;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
@@ -93,18 +96,30 @@ public class AliyunOssServiceImpl implements IOssService {
}
@Override
- public byte[] getObject(String bucket, String objectKey) {
+ public InputStream getObject(String bucket, String objectKey) {
OSS ossClient = this.createClient();
OSSObject object = ossClient.getObject(bucket, objectKey);
- try (InputStream stream = object.getObjectContent()) {
- return stream.readAllBytes();
+ try (InputStream input = object.getObjectContent()) {
+ return input;
} catch (IOException e) {
e.printStackTrace();
} finally {
ossClient.shutdown();
}
- return new byte[0];
+ return InputStream.nullInputStream();
+ }
+
+ @Override
+ public void putObject(String bucket, String objectKey, InputStream input) {
+ OSS ossClient = this.createClient();
+ if (ossClient.doesObjectExist(bucket, objectKey)) {
+ ossClient.shutdown();
+ throw new RuntimeException("The filename already exists.");
+ }
+ PutObjectResult objectResult = ossClient.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata()));
+ ossClient.shutdown();
+ log.info("Upload File: {}", objectResult.getETag());
}
private OSS createClient() {
diff --git a/src/main/java/com/dji/sample/component/oss/service/impl/AmazonS3ServiceImpl.java b/src/main/java/com/dji/sample/component/oss/service/impl/AmazonS3ServiceImpl.java
index f2bcdc5..b9cdfd3 100644
--- a/src/main/java/com/dji/sample/component/oss/service/impl/AmazonS3ServiceImpl.java
+++ b/src/main/java/com/dji/sample/component/oss/service/impl/AmazonS3ServiceImpl.java
@@ -5,9 +5,7 @@ import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
-import com.amazonaws.services.s3.model.BucketCrossOriginConfiguration;
-import com.amazonaws.services.s3.model.CORSRule;
-import com.amazonaws.services.s3.model.S3Object;
+import com.amazonaws.services.s3.model.*;
import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
@@ -18,6 +16,7 @@ import com.dji.sample.component.oss.model.OssConfiguration;
import com.dji.sample.component.oss.model.enums.OssTypeEnum;
import com.dji.sample.component.oss.service.IOssService;
import com.dji.sample.media.model.CredentialsDTO;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -34,6 +33,7 @@ import java.util.List;
* @version 1.0
* @date 2022/4/27
*/
+@Slf4j
@Service
public class AmazonS3ServiceImpl implements IOssService {
@@ -83,18 +83,29 @@ public class AmazonS3ServiceImpl implements IOssService {
return true;
}
- public byte[] getObject(String bucket, String objectKey) {
+ public InputStream getObject(String bucket, String objectKey) {
AmazonS3 client = this.createClient();
S3Object object = client.getObject(bucket, objectKey);
-
- try (InputStream stream = object.getObjectContent().getDelegateStream()) {
- return stream.readAllBytes();
+ try (InputStream input = object.getObjectContent().getDelegateStream()) {
+ return input;
} catch (IOException e) {
e.printStackTrace();
} finally {
client.shutdown();
}
- return new byte[0];
+ return InputStream.nullInputStream();
+ }
+
+ @Override
+ public void putObject(String bucket, String objectKey, InputStream input) {
+ AmazonS3 client = this.createClient();
+ if (client.doesObjectExist(bucket, objectKey)) {
+ client.shutdown();
+ throw new RuntimeException("The filename already exists.");
+ }
+ PutObjectResult objectResult = client.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata()));
+ client.shutdown();
+ log.info("Upload File: {}", objectResult.toString());
}
private AmazonS3 createClient() {
diff --git a/src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java b/src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java
index 009a1fb..b162751 100644
--- a/src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java
+++ b/src/main/java/com/dji/sample/component/oss/service/impl/MinIOServiceImpl.java
@@ -4,10 +4,7 @@ import com.dji.sample.component.oss.model.OssConfiguration;
import com.dji.sample.component.oss.model.enums.OssTypeEnum;
import com.dji.sample.component.oss.service.IOssService;
import com.dji.sample.media.model.CredentialsDTO;
-import io.minio.GetObjectArgs;
-import io.minio.GetPresignedObjectUrlArgs;
-import io.minio.MinioClient;
-import io.minio.RemoveObjectArgs;
+import io.minio.*;
import io.minio.credentials.AssumeRoleProvider;
import io.minio.errors.*;
import io.minio.http.Method;
@@ -15,11 +12,13 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
+import java.util.Objects;
/**
* @author sean
@@ -30,6 +29,8 @@ import java.security.NoSuchAlgorithmException;
@Slf4j
public class MinIOServiceImpl implements IOssService {
+ private MinioClient client;
+
@Autowired
private OssConfiguration configuration;
@@ -87,21 +88,44 @@ public class MinIOServiceImpl implements IOssService {
}
@Override
- public byte[] getObject(String bucket, String objectKey) {
- MinioClient client = this.createClient();
- try (InputStream objectResponse = client.getObject(GetObjectArgs.builder().bucket(bucket).object(objectKey).build())) {
- return objectResponse.readAllBytes();
- } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) {
+ public InputStream getObject(String bucket, String objectKey) {
+ try {
+ GetObjectResponse object = this.createClient().getObject(GetObjectArgs.builder().bucket(bucket).object(objectKey).build());
+ return new ByteArrayInputStream(object.readAllBytes());
+ } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | XmlParserException e) {
e.printStackTrace();
}
- return new byte[0];
+ return InputStream.nullInputStream();
+ }
+
+ @Override
+ public void putObject(String bucket, String objectKey, InputStream input) {
+ try {
+ MinioClient client = this.createClient();
+ client.statObject(StatObjectArgs.builder().bucket(bucket).object(objectKey).build());
+ throw new RuntimeException("The filename already exists.");
+ } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) {
+ log.info("The file does not exist, start uploading.");
+ try {
+ ObjectWriteResponse response = client.putObject(
+ PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(input, input.available(), 0).build());
+ log.info("Upload File: {}", response.etag());
+ } catch (MinioException | IOException | InvalidKeyException | NoSuchAlgorithmException ex) {
+ log.error("Failed to upload File {}.", objectKey);
+ ex.printStackTrace();
+ }
+ }
}
private MinioClient createClient() {
- return MinioClient.builder()
+ if (Objects.nonNull(this.client)) {
+ return this.client;
+ }
+ this.client = MinioClient.builder()
.endpoint(configuration.getEndpoint())
.credentials(configuration.getAccessKey(), configuration.getSecretKey())
.region(configuration.getRegion())
.build();
+ return this.client;
}
}
diff --git a/src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java b/src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java
index 9ac8059..e131889 100644
--- a/src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java
+++ b/src/main/java/com/dji/sample/component/oss/service/impl/OssServiceContext.java
@@ -7,6 +7,7 @@ import com.dji.sample.media.model.CredentialsDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
@@ -52,7 +53,11 @@ public class OssServiceContext {
return this.ossService.deleteObject(bucket, objectKey);
}
- public byte[] getObject(String bucket, String objectKey) {
+ public InputStream getObject(String bucket, String objectKey) {
return this.ossService.getObject(bucket, objectKey);
}
+
+ public void putObject(String bucket, String objectKey, InputStream stream) {
+ this.ossService.putObject(bucket, objectKey, stream);
+ }
}
diff --git a/src/main/java/com/dji/sample/component/redis/RedisConst.java b/src/main/java/com/dji/sample/component/redis/RedisConst.java
index dfbe44f..1fce89d 100644
--- a/src/main/java/com/dji/sample/component/redis/RedisConst.java
+++ b/src/main/java/com/dji/sample/component/redis/RedisConst.java
@@ -36,4 +36,6 @@ public final class RedisConst {
public static final String LOGS_FILE_PREFIX = "logs_file" + DELIMITER;
public static final String WAYLINE_JOB = "wayline_job";
+
+ public static final String OSD_PREFIX = "osd" + DELIMITER;
}
diff --git a/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java b/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java
index 182620c..c5d0201 100644
--- a/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java
+++ b/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java
@@ -11,6 +11,7 @@ import com.dji.sample.component.websocket.service.IWebSocketManageService;
import com.dji.sample.control.service.IControlService;
import com.dji.sample.manage.model.dto.DeviceDTO;
import com.dji.sample.manage.model.enums.UserTypeEnum;
+import com.dji.sample.manage.service.IDeviceService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
@@ -20,7 +21,6 @@ import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Service;
-import java.util.Optional;
import java.util.UUID;
/**
@@ -44,6 +44,9 @@ public class ControlServiceImpl implements IControlService {
@Autowired
private IWebSocketManageService webSocketManageService;
+ @Autowired
+ private IDeviceService deviceService;
+
@Autowired
private ObjectMapper mapper;
@@ -53,13 +56,13 @@ public class ControlServiceImpl implements IControlService {
if (servicesMethodEnum == ServicesMethodEnum.UNKNOWN) {
return ResponseResult.error("The " + serviceIdentifier + " method does not exist.");
}
- boolean isExist = redisOps.getExpire(RedisConst.DEVICE_ONLINE_PREFIX + sn) > 0;
+ boolean isExist = deviceService.checkDeviceOnline(sn);
if (!isExist) {
return ResponseResult.error("The dock is offline.");
}
String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + sn + TopicConst.SERVICES_SUF;
String bid = UUID.randomUUID().toString();
- Optional serviceReplyOpt = messageSenderService.publishWithReply(
+ ServiceReply serviceReplyOpt = messageSenderService.publishWithReply(
topic, CommonTopicResponse.builder()
.tid(UUID.randomUUID().toString())
.bid(bid)
@@ -67,11 +70,9 @@ public class ControlServiceImpl implements IControlService {
.timestamp(System.currentTimeMillis())
.data("")
.build());
- if (serviceReplyOpt.isEmpty()) {
- return ResponseResult.error("No message reply received.");
- }
+
ServiceReply serviceReply = mapper.convertValue(
- serviceReplyOpt.get(), new TypeReference>() {});
+ serviceReplyOpt, new TypeReference>() {});
if (serviceReply.getResult() != ResponseResult.CODE_SUCCESS) {
return ResponseResult.error(serviceReply.getResult(), serviceReply.getOutput().getStatus());
}
diff --git a/src/main/java/com/dji/sample/manage/controller/DeviceController.java b/src/main/java/com/dji/sample/manage/controller/DeviceController.java
index e9d80c0..192f45b 100644
--- a/src/main/java/com/dji/sample/manage/controller/DeviceController.java
+++ b/src/main/java/com/dji/sample/manage/controller/DeviceController.java
@@ -1,21 +1,20 @@
package com.dji.sample.manage.controller;
+import com.dji.sample.common.error.CommonErrorEnum;
import com.dji.sample.common.model.PaginationData;
import com.dji.sample.common.model.ResponseResult;
import com.dji.sample.component.mqtt.model.ChannelName;
import com.dji.sample.component.mqtt.model.CommonTopicReceiver;
import com.dji.sample.component.mqtt.model.CommonTopicResponse;
-import com.dji.sample.component.websocket.service.ISendMessageService;
import com.dji.sample.manage.model.dto.DeviceDTO;
import com.dji.sample.manage.model.dto.DeviceFirmwareUpgradeDTO;
-import com.dji.sample.manage.model.receiver.FirmwareVersionReceiver;
+import com.dji.sample.manage.model.enums.DeviceSetPropertyEnum;
import com.dji.sample.manage.model.receiver.StatusGatewayReceiver;
import com.dji.sample.manage.service.IDeviceService;
+import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.annotation.ServiceActivator;
-import org.springframework.integration.mqtt.support.MqttHeaders;
-import org.springframework.messaging.Message;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@@ -34,9 +33,6 @@ public class DeviceController {
@Autowired
private IDeviceService deviceService;
- @Autowired
- private ISendMessageService sendMessageService;
-
/**
* Handles the message that the drone goes online.
* @param receiver The drone information is not empty.
@@ -50,6 +46,8 @@ public class DeviceController {
CommonTopicResponse.builder()
.tid(receiver.getTid())
.bid(receiver.getBid())
+ .timestamp(System.currentTimeMillis())
+ .method(receiver.getMethod())
.build());
}
}
@@ -68,6 +66,8 @@ public class DeviceController {
CommonTopicResponse.builder()
.tid(receiver.getTid())
.bid(receiver.getBid())
+ .timestamp(System.currentTimeMillis())
+ .method(receiver.getMethod())
.build());
}
@@ -85,26 +85,6 @@ public class DeviceController {
return ResponseResult.success(devicesList);
}
- /**
- * Handle osd topic messages.
- * @param message
- */
- @ServiceActivator(inputChannel = ChannelName.INBOUND_OSD)
- public void osdRealTime(Message> message) {
- String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC).toString();
- byte[] payload = (byte[])message.getPayload();
- deviceService.handleOSD(topic, payload);
- }
-
- /**
- * Receive the reported firmware version data.
- * @param receiver
- */
- @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_FIRMWARE_VERSION)
- public void updateFirmwareVersion(FirmwareVersionReceiver receiver) {
- deviceService.updateFirmwareVersion(receiver);
- }
-
/**
* After binding the device to the workspace, the device data can only be seen on the web.
* @param device
@@ -186,4 +166,27 @@ public class DeviceController {
@RequestBody List upgradeDTOS) {
return deviceService.createDeviceOtaJob(workspaceId, upgradeDTOS);
}
+
+ /**
+ * Set the property parameters of the drone.
+ * @param workspaceId
+ * @param dockSn
+ * @param param
+ * @return
+ */
+ @PutMapping("/{workspace_id}/devices/{device_sn}/property")
+ public ResponseResult devicePropertySet(@PathVariable("workspace_id") String workspaceId,
+ @PathVariable("device_sn") String dockSn,
+ @RequestBody JsonNode param) {
+ if (param.size() != 1) {
+ return ResponseResult.error(CommonErrorEnum.ILLEGAL_ARGUMENT);
+ }
+ String property = param.fieldNames().next();
+ Optional propertyEnumOpt = DeviceSetPropertyEnum.find(property);
+ if (propertyEnumOpt.isEmpty()) {
+ return ResponseResult.error(CommonErrorEnum.ILLEGAL_ARGUMENT);
+ }
+ deviceService.devicePropertySet(workspaceId, dockSn, propertyEnumOpt.get(), param.get(property));
+ return ResponseResult.success();
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/dji/sample/manage/model/enums/DeviceSetPropertyEnum.java b/src/main/java/com/dji/sample/manage/model/enums/DeviceSetPropertyEnum.java
new file mode 100644
index 0000000..38f9428
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/enums/DeviceSetPropertyEnum.java
@@ -0,0 +1,41 @@
+package com.dji.sample.manage.model.enums;
+
+import com.dji.sample.manage.model.receiver.BasicDeviceProperty;
+import com.dji.sample.manage.model.receiver.DistanceLimitStatusReceiver;
+import com.dji.sample.manage.model.receiver.HeightLimitReceiver;
+import com.dji.sample.manage.model.receiver.ObstacleAvoidanceReceiver;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/10/27
+ */
+@Getter
+public enum DeviceSetPropertyEnum {
+
+ NIGHT_LIGHTS_STATE("night_lights_state", StateSwitchReceiver.class),
+
+ HEIGHT_LIMIT("height_limit", HeightLimitReceiver.class),
+
+ DISTANCE_LIMIT_STATUS("distance_limit_status", DistanceLimitStatusReceiver.class),
+
+ OBSTACLE_AVOIDANCE("obstacle_avoidance", ObstacleAvoidanceReceiver.class);
+
+
+ String property;
+
+ Class extends BasicDeviceProperty> clazz;
+
+ DeviceSetPropertyEnum(String property, Class extends BasicDeviceProperty> clazz) {
+ this.property = property;
+ this.clazz = clazz;
+ }
+
+ public static Optional find(String property) {
+ return Arrays.stream(DeviceSetPropertyEnum.values()).filter(propertyEnum -> propertyEnum.property.equals(property)).findAny();
+ }
+}
diff --git a/src/main/java/com/dji/sample/manage/model/enums/StateSwitchReceiver.java b/src/main/java/com/dji/sample/manage/model/enums/StateSwitchReceiver.java
new file mode 100644
index 0000000..27fb2a9
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/enums/StateSwitchReceiver.java
@@ -0,0 +1,30 @@
+package com.dji.sample.manage.model.enums;
+
+import com.dji.sample.manage.model.receiver.BasicDeviceProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Objects;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/10/28
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class StateSwitchReceiver extends BasicDeviceProperty {
+
+ public static final int DISABLE = 0;
+
+ public static final int ENABLE = 1;
+
+ private Integer value;
+
+ @Override
+ public boolean valid() {
+ return Objects.nonNull(this.value) && (this.value == DISABLE || this.value == ENABLE);
+ }
+}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/AlternateLandPointReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/AlternateLandPointReceiver.java
index bd69415..fa6924e 100644
--- a/src/main/java/com/dji/sample/manage/model/receiver/AlternateLandPointReceiver.java
+++ b/src/main/java/com/dji/sample/manage/model/receiver/AlternateLandPointReceiver.java
@@ -15,4 +15,6 @@ public class AlternateLandPointReceiver {
private Double longitude;
private Double safeLandHeight;
+
+ private Integer isConfigured;
}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/BackupBatteryReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/BackupBatteryReceiver.java
new file mode 100644
index 0000000..257316d
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/receiver/BackupBatteryReceiver.java
@@ -0,0 +1,20 @@
+package com.dji.sample.manage.model.receiver;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/11/3
+ */
+@Data
+public class BackupBatteryReceiver {
+
+ private Integer voltage;
+
+ private Float temperature;
+
+ @JsonProperty("switch")
+ private Integer batterySwitch;
+}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/BasicDeviceProperty.java b/src/main/java/com/dji/sample/manage/model/receiver/BasicDeviceProperty.java
new file mode 100644
index 0000000..e698a2f
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/receiver/BasicDeviceProperty.java
@@ -0,0 +1,20 @@
+package com.dji.sample.manage.model.receiver;
+
+import lombok.Data;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/10/27
+ */
+@Data
+public class BasicDeviceProperty {
+
+ public boolean valid() {
+ return false;
+ }
+
+ public boolean canPublish(String fieldName, OsdSubDeviceReceiver osd) {
+ return true;
+ }
+}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DeviceMaintainStatusReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DeviceMaintainStatusReceiver.java
new file mode 100644
index 0000000..05e3ed4
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/receiver/DeviceMaintainStatusReceiver.java
@@ -0,0 +1,16 @@
+package com.dji.sample.manage.model.receiver;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/11/3
+ */
+@Data
+public class DeviceMaintainStatusReceiver {
+
+ private List maintainStatusArray;
+}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java
new file mode 100644
index 0000000..72129c7
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/receiver/DistanceLimitStatusReceiver.java
@@ -0,0 +1,57 @@
+package com.dji.sample.manage.model.receiver;
+
+import com.dji.sample.manage.model.enums.StateSwitchReceiver;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Objects;
+
+/**
+ * The state of the drone's limited distance
+ * @author sean
+ * @version 1.3
+ * @date 2022/10/27
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DistanceLimitStatusReceiver extends BasicDeviceProperty {
+
+ private Integer state;
+
+ private Integer distanceLimit;
+
+ private static final int DISTANCE_MAX = 8000;
+
+ private static final int DISTANCE_MIN = 15;
+
+ @Override
+ public boolean valid() {
+ boolean valid = Objects.nonNull(state) || Objects.nonNull(distanceLimit);
+ if (Objects.nonNull(state)) {
+ valid = new StateSwitchReceiver(this.state).valid();
+ }
+ if (Objects.nonNull(distanceLimit)) {
+ valid &= distanceLimit >= DISTANCE_MIN && distanceLimit <= DISTANCE_MAX;
+ }
+ return valid;
+ }
+
+ @Override
+ public boolean canPublish(String fieldName, OsdSubDeviceReceiver osd) {
+ DistanceLimitStatusReceiver distanceLimitStatus = osd.getDistanceLimitStatus();
+ switch (fieldName) {
+ case "state":
+ return Objects.isNull(distanceLimitStatus.getState()) ||
+ Objects.nonNull(distanceLimitStatus.getState()) &&
+ distanceLimitStatus.getState().intValue() != this.state;
+ case "distance_limit":
+ return Objects.isNull(distanceLimitStatus.getDistanceLimit()) ||
+ Objects.nonNull(distanceLimitStatus.getDistanceLimit()) &&
+ distanceLimitStatus.getDistanceLimit().intValue() != this.distanceLimit;
+ default:
+ throw new RuntimeException("Property " + fieldName + " does not exist.");
+ }
+ }
+}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DockWirelessLinkReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DockWirelessLinkReceiver.java
new file mode 100644
index 0000000..83bfb3f
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/receiver/DockWirelessLinkReceiver.java
@@ -0,0 +1,38 @@
+package com.dji.sample.manage.model.receiver;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/11/3
+ */
+@Data
+public class DockWirelessLinkReceiver {
+
+ @JsonProperty("4g_freq_band")
+ private Float fourGFreqBand;
+
+ @JsonProperty("4g_gnd_quality")
+ private Integer fourGGndQuality;
+
+ @JsonProperty("4g_link_state")
+ private Integer fourGLinkState;
+
+ @JsonProperty("4g_quality")
+ private Integer fourGQuality;
+
+ @JsonProperty("4g_uav_quality")
+ private Integer fourGUavQuality;
+
+ private Integer dongleNumber;
+
+ private Integer linkWorkmode;
+
+ private Float sdrFreqBand;
+
+ private Integer sdrLinkState;
+
+ private Integer sdrQuality;
+}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/DroneBatteryMaintenanceInfoReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/DroneBatteryMaintenanceInfoReceiver.java
new file mode 100644
index 0000000..1718aca
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/receiver/DroneBatteryMaintenanceInfoReceiver.java
@@ -0,0 +1,16 @@
+package com.dji.sample.manage.model.receiver;
+
+import lombok.Data;
+
+/**
+ * @author sean
+ * @version 1.4
+ * @date 2022/11/3
+ */
+@Data
+public class DroneBatteryMaintenanceInfoReceiver {
+
+ private Integer maintenanceState;
+
+ private Long maintenanceTimeLeft;
+}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/HeightLimitReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/HeightLimitReceiver.java
new file mode 100644
index 0000000..7a07565
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/receiver/HeightLimitReceiver.java
@@ -0,0 +1,29 @@
+package com.dji.sample.manage.model.receiver;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Objects;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/10/28
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class HeightLimitReceiver extends BasicDeviceProperty {
+
+ private static final int HEIGHT_LIMIT_MAX = 1500;
+
+ private static final int HEIGHT_LIMIT_MIN = 20;
+
+ private Integer value;
+
+ @Override
+ public boolean valid() {
+ return Objects.nonNull(this.value) && this.value >= HEIGHT_LIMIT_MIN && this.value <= HEIGHT_LIMIT_MAX;
+ }
+}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/MaintainStatusReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/MaintainStatusReceiver.java
new file mode 100644
index 0000000..7896f31
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/receiver/MaintainStatusReceiver.java
@@ -0,0 +1,20 @@
+package com.dji.sample.manage.model.receiver;
+
+import lombok.Data;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/11/3
+ */
+@Data
+public class MaintainStatusReceiver {
+
+ private Integer state;
+
+ private Integer lastMaintainType;
+
+ private Long lastMaintainTime;
+
+ private Long lastMaintainWorkSorties;
+}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/NetworkStateReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/NetworkStateReceiver.java
index 84698cc..2aac8ae 100644
--- a/src/main/java/com/dji/sample/manage/model/receiver/NetworkStateReceiver.java
+++ b/src/main/java/com/dji/sample/manage/model/receiver/NetworkStateReceiver.java
@@ -14,5 +14,5 @@ public class NetworkStateReceiver {
private Integer quality;
- private float rate;
+ private Float rate;
}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/ObstacleAvoidanceReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/ObstacleAvoidanceReceiver.java
new file mode 100644
index 0000000..e40a341
--- /dev/null
+++ b/src/main/java/com/dji/sample/manage/model/receiver/ObstacleAvoidanceReceiver.java
@@ -0,0 +1,62 @@
+package com.dji.sample.manage.model.receiver;
+
+import com.dji.sample.manage.model.enums.StateSwitchReceiver;
+import lombok.Data;
+
+import java.util.Objects;
+
+/**
+ * @author sean
+ * @version 1.3
+ * @date 2022/10/27
+ */
+@Data
+public class ObstacleAvoidanceReceiver extends BasicDeviceProperty {
+
+ private Integer horizon;
+
+ private Integer upside;
+
+ private Integer downside;
+
+ @Override
+ public boolean valid() {
+ boolean valid = Objects.nonNull(this.horizon) || Objects.nonNull(this.upside) || Objects.nonNull(this.downside);
+
+ StateSwitchReceiver stateSwitch = new StateSwitchReceiver();
+ if (Objects.nonNull(this.horizon)) {
+ stateSwitch.setValue(this.horizon);
+ valid = stateSwitch.valid();
+ }
+ if (Objects.nonNull(this.upside)) {
+ stateSwitch.setValue(this.upside);
+ valid &= stateSwitch.valid();
+ }
+ if (Objects.nonNull(this.downside)) {
+ stateSwitch.setValue(this.downside);
+ valid &= stateSwitch.valid();
+ }
+ return valid;
+ }
+
+ @Override
+ public boolean canPublish(String fieldName, OsdSubDeviceReceiver osd) {
+ ObstacleAvoidanceReceiver obstacleAvoidance = osd.getObstacleAvoidance();
+ switch (fieldName) {
+ case "horizon":
+ return Objects.isNull(obstacleAvoidance.getHorizon()) ||
+ Objects.nonNull(obstacleAvoidance.getHorizon()) &&
+ obstacleAvoidance.getHorizon().intValue() != this.horizon;
+ case "upside":
+ return Objects.isNull(obstacleAvoidance.getUpside()) ||
+ Objects.nonNull(obstacleAvoidance.getUpside()) &&
+ obstacleAvoidance.getUpside().intValue() != this.upside;
+ case "downside":
+ return Objects.isNull(obstacleAvoidance.getDownside()) ||
+ Objects.nonNull(obstacleAvoidance.getDownside()) &&
+ obstacleAvoidance.getDownside().intValue() != this.downside;
+ default:
+ throw new RuntimeException("Property " + fieldName + " does not exist.");
+ }
+ }
+}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OsdDockReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OsdDockReceiver.java
index ebd8b34..0cd5196 100644
--- a/src/main/java/com/dji/sample/manage/model/receiver/OsdDockReceiver.java
+++ b/src/main/java/com/dji/sample/manage/model/receiver/OsdDockReceiver.java
@@ -4,8 +4,8 @@ import lombok.Data;
/**
* @author sean
- * @version 1.0
- * @date 2022/5/11
+ * @version 1.3
+ * @date 2022/11/3
*/
@Data
public class OsdDockReceiver {
@@ -22,8 +22,6 @@ public class OsdDockReceiver {
private Float environmentTemperature;
- private Integer environmentHumidity;
-
private Float temperature;
private Integer humidity;
@@ -36,32 +34,55 @@ public class OsdDockReceiver {
private AlternateLandPointReceiver alternateLandPoint;
- private Integer jobNumber;
-
- private Integer accTime;
-
private Long firstPowerOn;
private PositionStateReceiver positionState;
private StorageReceiver storage;
+ private Integer modeCode;
+
+ private Integer coverState;
+
+ private Integer supplementLightState;
+
+ private Integer emergencyStopState;
+
+ private Integer airConditionerMode;
+
+ private Integer batteryStoreMode;
+
+ private Integer alarmState;
+
+ private Integer putterState;
+
+ private DockSubDeviceReceiver subDevice;
+
+ private Integer jobNumber;
+
+ private Long accTime;
+
+ private Long activationTime;
+
+ private DeviceMaintainStatusReceiver maintainStatus;
+
private Integer electricSupplyVoltage;
private Integer workingVoltage;
private Integer workingCurrent;
- private Integer backupBatteryVoltage;
+ private BackupBatteryReceiver backupBattery;
- private Integer modeCode;
+ private DroneBatteryMaintenanceInfoReceiver droneBatteryMaintenanceInfo;
- private Integer coverState;
+ private Integer flighttaskStepCode;
- private Integer supplementLightState;
+ private Integer flighttaskPrepareCapacity;
- private Integer putterState;
+ private DockMediaFileDetailReceiver mediaFileDetail;
- private DockSubDeviceReceiver subDevice;
+ private DockSdrReceiver sdr;
+ private DockWirelessLinkReceiver wirelessLink;
}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OsdDockTransmissionReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OsdDockTransmissionReceiver.java
deleted file mode 100644
index cdd9abf..0000000
--- a/src/main/java/com/dji/sample/manage/model/receiver/OsdDockTransmissionReceiver.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.dji.sample.manage.model.receiver;
-
-import lombok.Data;
-
-/**
- * @author sean
- * @version 1.1
- * @date 2022/6/17
- */
-@Data
-public class OsdDockTransmissionReceiver {
-
- private Integer flighttaskStepCode;
-
- private DockMediaFileDetailReceiver mediaFileDetail;
-
- private DockSdrReceiver sdr;
-}
diff --git a/src/main/java/com/dji/sample/manage/model/receiver/OsdSubDeviceReceiver.java b/src/main/java/com/dji/sample/manage/model/receiver/OsdSubDeviceReceiver.java
index 2cb54df..b39fb09 100644
--- a/src/main/java/com/dji/sample/manage/model/receiver/OsdSubDeviceReceiver.java
+++ b/src/main/java/com/dji/sample/manage/model/receiver/OsdSubDeviceReceiver.java
@@ -58,4 +58,13 @@ public class OsdSubDeviceReceiver {
private List payloads;
private StorageReceiver storage;
+
+ private Integer nightLightsState;
+
+ private Integer heightLimit;
+
+ private DistanceLimitStatusReceiver distanceLimitStatus;
+
+ private ObstacleAvoidanceReceiver obstacleAvoidance;
+
}
\ No newline at end of file
diff --git a/src/main/java/com/dji/sample/manage/service/IDeviceDictionaryService.java b/src/main/java/com/dji/sample/manage/service/IDeviceDictionaryService.java
index 201f82c..97b901b 100644
--- a/src/main/java/com/dji/sample/manage/service/IDeviceDictionaryService.java
+++ b/src/main/java/com/dji/sample/manage/service/IDeviceDictionaryService.java
@@ -13,10 +13,12 @@ public interface IDeviceDictionaryService {
/**
* Query the type data of the device based on domain, device type and sub type.
+ *
+ * @param domain
* @param deviceType
* @param subType
* @return
*/
- Optional getOneDictionaryInfoByTypeSubType(Integer deviceType, Integer subType);
+ Optional getOneDictionaryInfoByTypeSubType(Integer domain, Integer deviceType, Integer subType);
}
diff --git a/src/main/java/com/dji/sample/manage/service/IDeviceService.java b/src/main/java/com/dji/sample/manage/service/IDeviceService.java
index 37e5a44..c048eb4 100644
--- a/src/main/java/com/dji/sample/manage/service/IDeviceService.java
+++ b/src/main/java/com/dji/sample/manage/service/IDeviceService.java
@@ -8,13 +8,17 @@ import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession;
import com.dji.sample.manage.model.dto.DeviceDTO;
import com.dji.sample.manage.model.dto.DeviceFirmwareUpgradeDTO;
import com.dji.sample.manage.model.dto.TopologyDeviceDTO;
+import com.dji.sample.manage.model.enums.DeviceSetPropertyEnum;
import com.dji.sample.manage.model.param.DeviceQueryParam;
import com.dji.sample.manage.model.receiver.FirmwareVersionReceiver;
import com.dji.sample.manage.model.receiver.StatusGatewayReceiver;
+import com.fasterxml.jackson.databind.JsonNode;
+import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
/**
@@ -133,10 +137,9 @@ public interface IDeviceService {
/**
* Handle messages from the osd topic.
- * @param topic osd
- * @param payload
+ * @param message osd
*/
- void handleOSD(String topic, byte[] payload);
+ void handleOSD(Message> message);
/**
* Update the device information.
@@ -205,4 +208,28 @@ public interface IDeviceService {
* @return
*/
ResponseResult createDeviceOtaJob(String workspaceId, List upgradeDTOS);
+
+ /**
+ * Set the property parameters of the drone.
+ * @param workspaceId
+ * @param dockSn
+ * @param propertyEnum
+ * @param param
+ */
+ void devicePropertySet(String workspaceId, String dockSn, DeviceSetPropertyEnum propertyEnum, JsonNode param);
+
+ /**
+ * Set one property parameters of the drone.
+ * @param topic
+ * @param propertyEnum
+ * @param value
+ */
+ void deviceOnePropertySet(String topic, DeviceSetPropertyEnum propertyEnum, Map.Entry value);
+
+ /**
+ * Determine if the device is online.
+ * @param sn
+ * @return
+ */
+ Boolean checkDeviceOnline(String sn);
}
\ No newline at end of file
diff --git a/src/main/java/com/dji/sample/manage/service/impl/CapacityCameraServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/CapacityCameraServiceImpl.java
index be5020d..13ddc9b 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/CapacityCameraServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/CapacityCameraServiceImpl.java
@@ -5,6 +5,7 @@ import com.dji.sample.component.redis.RedisConst;
import com.dji.sample.component.redis.RedisOpsUtils;
import com.dji.sample.manage.model.dto.CapacityCameraDTO;
import com.dji.sample.manage.model.dto.DeviceDictionaryDTO;
+import com.dji.sample.manage.model.enums.DeviceDomainEnum;
import com.dji.sample.manage.model.receiver.CapacityCameraReceiver;
import com.dji.sample.manage.service.ICameraVideoService;
import com.dji.sample.manage.service.ICapacityCameraService;
@@ -68,7 +69,7 @@ public class CapacityCameraServiceImpl implements ICapacityCameraService {
// type-subType-index
if (indexArr.length == 3) {
Optional dictionaryOpt = dictionaryService
- .getOneDictionaryInfoByTypeSubType(indexArr[0], indexArr[1]);
+ .getOneDictionaryInfoByTypeSubType(DeviceDomainEnum.PAYLOAD.getVal(), indexArr[0], indexArr[1]);
dictionaryOpt.ifPresent(dictionary ->
builder.name(dictionary.getDeviceName()));
}
diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceDictionaryServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceDictionaryServiceImpl.java
index f0dbad0..a4574b7 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DeviceDictionaryServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceDictionaryServiceImpl.java
@@ -25,16 +25,18 @@ public class DeviceDictionaryServiceImpl implements IDeviceDictionaryService {
private IDeviceDictionaryMapper mapper;
@Override
- public Optional getOneDictionaryInfoByTypeSubType(Integer deviceType, Integer subType) {
- if (deviceType == null || subType == null) {
+ public Optional getOneDictionaryInfoByTypeSubType(Integer domain, Integer deviceType, Integer subType) {
+ if (domain == null || deviceType == null || subType == null) {
return Optional.empty();
}
return Optional.ofNullable(
entityConvertToDTO(
mapper.selectOne(
new LambdaQueryWrapper()
+ .eq(DeviceDictionaryEntity::getDomain, domain)
.eq(DeviceDictionaryEntity::getDeviceType, deviceType)
- .eq(DeviceDictionaryEntity::getSubType, subType))));
+ .eq(DeviceDictionaryEntity::getSubType, subType)
+ .last(" limit 1 "))));
}
/**
diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java
index 61e2fff..7e8882c 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceFirmwareServiceImpl.java
@@ -18,6 +18,7 @@ import com.dji.sample.manage.model.entity.DeviceFirmwareEntity;
import com.dji.sample.manage.model.enums.UserTypeEnum;
import com.dji.sample.manage.model.param.DeviceOtaCreateParam;
import com.dji.sample.manage.service.IDeviceFirmwareService;
+import com.dji.sample.manage.service.IDeviceService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
@@ -61,6 +62,9 @@ public class DeviceFirmwareServiceImpl implements IDeviceFirmwareService {
@Autowired
private IWebSocketManageService webSocketManageService;
+ @Autowired
+ private IDeviceService deviceService;
+
@Override
public Optional getFirmware(String deviceName, String version) {
return Optional.ofNullable(entity2Dto(mapper.selectOne(
@@ -83,7 +87,7 @@ public class DeviceFirmwareServiceImpl implements IDeviceFirmwareService {
public List getDeviceOtaFirmware(List upgradeDTOS) {
List deviceOtaList = new ArrayList<>();
upgradeDTOS.forEach(upgradeDevice -> {
- boolean exist = redisOps.getExpire(RedisConst.DEVICE_ONLINE_PREFIX + upgradeDevice.getSn()) > 0;
+ boolean exist = deviceService.checkDeviceOnline(upgradeDevice.getSn());
if (!exist) {
throw new IllegalArgumentException("Device is offline.");
}
diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java
index 9e238cb..913e0f2 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceLogsServiceImpl.java
@@ -113,7 +113,7 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService {
}
String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + deviceSn + TopicConst.SERVICES_SUF;
- Optional serviceReplyOpt = messageSenderService.publishWithReply(
+ LogsFileUploadList data = messageSenderService.publishWithReply(
LogsFileUploadList.class,
topic,
CommonTopicResponse.builder()
@@ -123,10 +123,7 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService {
.timestamp(System.currentTimeMillis())
.data(Map.of(MapKeyConst.MODULE_LIST, domainList))
.build(), 1);
- if (serviceReplyOpt.isEmpty()) {
- return ResponseResult.error("No message reply received.");
- }
- LogsFileUploadList data = serviceReplyOpt.get();
+
for (LogsFileUpload file : data.getFiles()) {
if (file.getDeviceSn().isBlank()) {
file.setDeviceSn(deviceSn);
@@ -170,7 +167,7 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService {
credentialsDTO.setParams(LogsFileUploadList.builder().files(files).build());
String bid = UUID.randomUUID().toString();
- Optional serviceReply = messageSenderService.publishWithReply(
+ ServiceReply reply = messageSenderService.publishWithReply(
TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + deviceSn + TopicConst.SERVICES_SUF,
CommonTopicResponse.builder()
.tid(UUID.randomUUID().toString())
@@ -180,10 +177,6 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService {
.data(credentialsDTO)
.build());
- if (serviceReply.isEmpty()) {
- return ResponseResult.error("No message reply received.");
- }
- ServiceReply reply = serviceReply.get();
if (ResponseResult.CODE_SUCCESS != reply.getResult()) {
return ResponseResult.error(String.valueOf(reply.getResult()));
}
@@ -207,7 +200,7 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService {
}
String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + deviceSn + TopicConst.SERVICES_SUF;
String bid = UUID.randomUUID().toString();
- Optional serviceReply = messageSenderService.publishWithReply(topic,
+ ServiceReply reply = messageSenderService.publishWithReply(topic,
CommonTopicResponse.builder()
.tid(UUID.randomUUID().toString())
.bid(bid)
@@ -216,10 +209,6 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService {
.data(param)
.build());
- if (serviceReply.isEmpty()) {
- return ResponseResult.error("No message reply received.");
- }
- ServiceReply reply = serviceReply.get();
if (ResponseResult.CODE_SUCCESS != reply.getResult()) {
return ResponseResult.error("Error Code : " + reply.getResult());
}
@@ -284,7 +273,6 @@ public class DeviceLogsServiceImpl implements IDeviceLogsService {
List fileReceivers = output.getExt().getFiles();
if (CollectionUtils.isEmpty(fileReceivers)) {
redisOpsUtils.del(RedisConst.LOGS_FILE_PREFIX + sn);
- return;
}
// refresh cache.
diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java
index 9fc690d..16ed4be 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceOSDServiceImpl.java
@@ -1,6 +1,7 @@
package com.dji.sample.manage.service.impl;
import com.dji.sample.component.mqtt.model.CommonTopicReceiver;
+import com.dji.sample.component.redis.RedisConst;
import com.dji.sample.component.websocket.config.ConcurrentWebSocketSession;
import com.dji.sample.component.websocket.model.BizCodeEnum;
import com.dji.sample.component.websocket.model.CustomWebSocketMessage;
@@ -74,7 +75,7 @@ public class DeviceOSDServiceImpl extends AbstractTSAService {
log.warn("Please remount the payload, or restart the drone. Otherwise the data of the payload will not be received.");
}
-
+ redisOps.setWithExpire(RedisConst.OSD_PREFIX + device.getDeviceSn(), data, RedisConst.DEVICE_ALIVE_SECOND);
wsMessage.getData().setHost(data);
sendMessageService.sendBatch(webSessions, wsMessage);
diff --git a/src/main/java/com/dji/sample/manage/service/impl/DevicePayloadServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DevicePayloadServiceImpl.java
index 123660b..1e6f52b 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DevicePayloadServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DevicePayloadServiceImpl.java
@@ -9,6 +9,7 @@ import com.dji.sample.manage.model.dto.DeviceDTO;
import com.dji.sample.manage.model.dto.DeviceDictionaryDTO;
import com.dji.sample.manage.model.dto.DevicePayloadDTO;
import com.dji.sample.manage.model.entity.DevicePayloadEntity;
+import com.dji.sample.manage.model.enums.DeviceDomainEnum;
import com.dji.sample.manage.model.receiver.DevicePayloadReceiver;
import com.dji.sample.manage.model.receiver.FirmwareVersionReceiver;
import com.dji.sample.manage.service.ICapacityCameraService;
@@ -204,7 +205,7 @@ public class DevicePayloadServiceImpl implements IDevicePayloadService {
if (arr.length == 3) {
Optional dictionaryOpt = dictionaryService
- .getOneDictionaryInfoByTypeSubType(arr[0], arr[1]);
+ .getOneDictionaryInfoByTypeSubType(DeviceDomainEnum.PAYLOAD.getVal(), arr[0], arr[1]);
dictionaryOpt.ifPresent(dictionary ->
builder.payloadName(dictionary.getDeviceName())
.payloadDesc(dictionary.getDeviceDesc()));
diff --git a/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java b/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
index 1fecf85..52f012d 100644
--- a/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
+++ b/src/main/java/com/dji/sample/manage/service/impl/DeviceServiceImpl.java
@@ -20,21 +20,20 @@ import com.dji.sample.component.websocket.service.IWebSocketManageService;
import com.dji.sample.manage.dao.IDeviceMapper;
import com.dji.sample.manage.model.dto.*;
import com.dji.sample.manage.model.entity.DeviceEntity;
-import com.dji.sample.manage.model.enums.DeviceDomainEnum;
-import com.dji.sample.manage.model.enums.DeviceFirmwareStatusEnum;
-import com.dji.sample.manage.model.enums.IconUrlEnum;
-import com.dji.sample.manage.model.enums.UserTypeEnum;
+import com.dji.sample.manage.model.enums.*;
import com.dji.sample.manage.model.param.DeviceOtaCreateParam;
import com.dji.sample.manage.model.param.DeviceQueryParam;
import com.dji.sample.manage.model.receiver.*;
import com.dji.sample.manage.service.*;
import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.mqtt.support.MqttHeaders;
+import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -99,6 +98,9 @@ public class DeviceServiceImpl implements IDeviceService {
@Qualifier("gatewayOSDServiceImpl")
private ITSAService tsaService;
+ private static final List INIT_TOPICS_SUFFIX = List.of(
+ OSD_SUF, STATE_SUF, SERVICES_SUF + _REPLY_SUF, REQUESTS_SUF, EVENTS_SUF, PROPERTY_SUF + SET_SUF + _REPLY_SUF);
+
@Override
public Boolean deviceOffline(String gatewaySn) {
this.subscribeTopicOnline(gatewaySn);
@@ -111,26 +113,24 @@ public class DeviceServiceImpl implements IDeviceService {
Optional gatewayOpt = this.getDeviceBySn(gatewaySn);
if (gatewayOpt.isPresent()) {
DeviceDTO value = gatewayOpt.get();
- value.setChildDeviceSn(value.getDeviceSn());
value.setBoundTime(null);
value.setLoginTime(null);
redisOps.setWithExpire(key, value, RedisConst.DEVICE_ALIVE_SECOND);
this.pushDeviceOnlineTopo(value.getWorkspaceId(), gatewaySn, gatewaySn);
return true;
}
+ // When connecting for the first time
DeviceDTO gateway = DeviceDTO.builder()
.deviceSn(gatewaySn)
- .childDeviceSn(gatewaySn)
.domain(DeviceDomainEnum.GATEWAY.getDesc())
.build();
- gatewayOpt.map(DeviceDTO::getWorkspaceId).ifPresent(gateway::setWorkspaceId);
redisOps.setWithExpire(key, gateway, RedisConst.DEVICE_ALIVE_SECOND);
- this.pushDeviceOnlineTopo(gateway.getWorkspaceId(), gatewaySn, gatewaySn);
return true;
}
- String deviceSn = ((DeviceDTO)(redisOps.get(key))).getChildDeviceSn();
- if (deviceSn.equals(gatewaySn)) {
+ DeviceDTO deviceDTO = (DeviceDTO) (redisOps.get(key));
+ String deviceSn = deviceDTO.getChildDeviceSn();
+ if (!StringUtils.hasText(deviceSn)) {
return true;
}
@@ -139,21 +139,23 @@ public class DeviceServiceImpl implements IDeviceService {
@Override
public Boolean subDeviceOffline(String deviceSn) {
- // Cancel drone-related subscriptions.
- this.unsubscribeTopicOffline(deviceSn);
- payloadService.deletePayloadsByDeviceSn(new ArrayList<>(List.of(deviceSn)));
- // If no information about this gateway device exists in the database, the drone is considered to be offline.
+ // If no information about this device exists in the cache, the drone is considered to be offline.
String key = RedisConst.DEVICE_ONLINE_PREFIX + deviceSn;
if (!redisOps.checkExist(key) || redisOps.getExpire(key) <= 0) {
log.debug("The drone is already offline.");
return true;
}
DeviceDTO device = (DeviceDTO) redisOps.get(key);
+ // Cancel drone-related subscriptions.
+ this.unsubscribeTopicOffline(deviceSn);
+
+ payloadService.deletePayloadsByDeviceSn(new ArrayList<>(List.of(deviceSn)));
// Publish the latest device topology information in the current workspace.
this.pushDeviceOfflineTopo(device.getWorkspaceId(), deviceSn);
redisOps.del(key);
+ redisOps.del(RedisConst.OSD_PREFIX + device.getDeviceSn());
log.debug("{} offline.", deviceSn);
return true;
}
@@ -264,20 +266,14 @@ public class DeviceServiceImpl implements IDeviceService {
return;
}
}
- topicService.subscribe(THING_MODEL_PRE + PRODUCT + sn + OSD_SUF);
- topicService.subscribe(THING_MODEL_PRE + PRODUCT + sn + STATE_SUF);
- topicService.subscribe(THING_MODEL_PRE + PRODUCT + sn + SERVICES_SUF + _REPLY_SUF);
- topicService.subscribe(THING_MODEL_PRE + PRODUCT + sn + REQUESTS_SUF);
- topicService.subscribe(THING_MODEL_PRE + PRODUCT + sn + EVENTS_SUF);
+ String prefix = THING_MODEL_PRE + PRODUCT + sn;
+ INIT_TOPICS_SUFFIX.forEach(suffix -> topicService.subscribe(prefix + suffix));
}
@Override
public void unsubscribeTopicOffline(String sn) {
- topicService.unsubscribe(THING_MODEL_PRE + PRODUCT + sn + OSD_SUF);
- topicService.unsubscribe(THING_MODEL_PRE + PRODUCT + sn + STATE_SUF);
- topicService.unsubscribe(THING_MODEL_PRE + PRODUCT + sn + SERVICES_SUF + _REPLY_SUF);
- topicService.unsubscribe(THING_MODEL_PRE + PRODUCT + sn + REQUESTS_SUF);
- topicService.unsubscribe(THING_MODEL_PRE + PRODUCT + sn + EVENTS_SUF);
+ String prefix = THING_MODEL_PRE + PRODUCT + sn;
+ INIT_TOPICS_SUFFIX.forEach(suffix -> topicService.unsubscribe(prefix + suffix));
}
@Override
@@ -459,7 +455,10 @@ public class DeviceServiceImpl implements IDeviceService {
}
@Override
- public void handleOSD(String topic, byte[] payload) {
+ @ServiceActivator(inputChannel = ChannelName.INBOUND_OSD)
+ public void handleOSD(Message> message) {
+ String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC).toString();
+ byte[] payload = (byte[])message.getPayload();
CommonTopicReceiver receiver;
try {
String from = topic.substring((THING_MODEL_PRE + PRODUCT).length(),
@@ -568,7 +567,7 @@ public class DeviceServiceImpl implements IDeviceService {
// Query the model information of this gateway device.
Optional dictionaryOpt = dictionaryService
- .getOneDictionaryInfoByTypeSubType(gateway.getType(), gateway.getSubType());
+ .getOneDictionaryInfoByTypeSubType(DeviceDomainEnum.GATEWAY.getVal(), gateway.getType(), gateway.getSubType());
dictionaryOpt.ifPresent(entity ->
builder.deviceName(entity.getDeviceName())
@@ -598,7 +597,7 @@ public class DeviceServiceImpl implements IDeviceService {
// Query the model information of this drone device.
Optional dictionaryOpt = dictionaryService
- .getOneDictionaryInfoByTypeSubType(device.getType(), device.getSubType());
+ .getOneDictionaryInfoByTypeSubType(DeviceDomainEnum.SUB_DEVICE.getVal(), device.getType(), device.getSubType());
dictionaryOpt.ifPresent(dictionary ->
builder.deviceName(dictionary.getDeviceName())
@@ -767,8 +766,8 @@ public class DeviceServiceImpl implements IDeviceService {
assert dock != null;
- Optional dockEntityOpt = this.bindDevice2Entity(dock);
- Optional droneEntityOpt = this.bindDevice2Entity(drone);
+ Optional dockEntityOpt = this.bindDevice2Entity(DeviceDomainEnum.DOCK.getVal(), dock);
+ Optional droneEntityOpt = this.bindDevice2Entity(DeviceDomainEnum.SUB_DEVICE.getVal(), drone);
List bindResult = new ArrayList<>();
@@ -855,7 +854,13 @@ public class DeviceServiceImpl implements IDeviceService {
}
@Override
+ @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_FIRMWARE_VERSION)
public void updateFirmwareVersion(FirmwareVersionReceiver receiver) {
+ // If the reported version is empty, it will not be processed to prevent misleading page.
+ if (!StringUtils.hasText(receiver.getFirmwareVersion())) {
+ return;
+ }
+
if (receiver.getDomain() == DeviceDomainEnum.SUB_DEVICE) {
final DeviceDTO device = DeviceDTO.builder()
.deviceSn(receiver.getSn())
@@ -885,7 +890,7 @@ public class DeviceServiceImpl implements IDeviceService {
// The bids in the progress messages reported subsequently are the same.
String bid = UUID.randomUUID().toString();
- Optional serviceReplyOpt = messageSender.publishWithReply(
+ ServiceReply serviceReply = messageSender.publishWithReply(
topic, CommonTopicResponse.