Browse Source
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
726 changed files with 31400 additions and 8630 deletions
@ -1,78 +0,0 @@
@@ -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; |
||||
} |
||||
} |
@ -1,36 +0,0 @@
@@ -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(); |
||||
} |
||||
} |
@ -1,27 +0,0 @@
@@ -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; |
||||
} |
||||
} |
@ -1,69 +0,0 @@
@@ -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(); |
||||
} |
||||
} |
@ -0,0 +1,30 @@
@@ -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); |
||||
} |
||||
} |
@ -1,47 +0,0 @@
@@ -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; |
||||
} |
||||
} |
@ -1,39 +0,0 @@
@@ -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; |
||||
} |
@ -1,68 +0,0 @@
@@ -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()); |
||||
|
||||
} |
||||
|
||||
} |
@ -1,40 +0,0 @@
@@ -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); |
||||
} |
||||
} |
@ -1,45 +0,0 @@
@@ -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(); |
||||
} |
||||
} |
@ -1,53 +0,0 @@
@@ -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); |
||||
} |
||||
} |
@ -1,26 +0,0 @@
@@ -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; |
||||
} |
||||
} |
@ -1,38 +0,0 @@
@@ -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); |
||||
} |
||||
} |
@ -1,62 +0,0 @@
@@ -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); |
||||
} |
||||
} |
@ -1,39 +0,0 @@
@@ -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); |
||||
} |
||||
} |
@ -1,104 +0,0 @@
@@ -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; |
||||
} |
||||
|
||||
} |
@ -1,67 +0,0 @@
@@ -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; |
||||
} |
||||
|
||||
} |
@ -1,45 +0,0 @@
@@ -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<>(); |
||||
} |
||||
} |
@ -1,91 +0,0 @@
@@ -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"; |
||||
} |
@ -1,34 +0,0 @@
@@ -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; |
||||
|
||||
} |
@ -1,35 +0,0 @@
@@ -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; |
||||
} |
@ -1,32 +0,0 @@
@@ -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(); |
||||
} |
||||
} |
@ -1,23 +0,0 @@
@@ -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); |
||||
} |
||||
} |
@ -1,83 +0,0 @@
@@ -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); |
||||
} |
||||
} |
@ -1,18 +0,0 @@
@@ -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; |
||||
} |
@ -1,29 +1,64 @@
@@ -1,29 +1,64 @@
|
||||
package com.dji.sample.component.mqtt.model; |
||||
|
||||
import com.dji.sdk.mqtt.events.EventsDataRequest; |
||||
import com.dji.sdk.mqtt.events.EventsErrorCode; |
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
import lombok.*; |
||||
|
||||
/** |
||||
* @author sean |
||||
* @version 1.1 |
||||
* @date 2022/6/9 |
||||
*/ |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@Data |
||||
@JsonIgnoreProperties(ignoreUnknown = true) |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class EventsReceiver<T> { |
||||
|
||||
private Integer result; |
||||
|
||||
private T output; |
||||
public class EventsReceiver<T> extends EventsDataRequest<T> { |
||||
|
||||
private String bid; |
||||
|
||||
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; |
||||
} |
||||
} |
||||
|
@ -1,49 +0,0 @@
@@ -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); |
||||
} |
||||
} |
@ -1,18 +0,0 @@
@@ -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; |
||||
} |
@ -1,44 +0,0 @@
@@ -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); |
||||
} |
||||
} |
@ -1,44 +0,0 @@
@@ -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(); |
||||
} |
||||
} |
@ -1,20 +0,0 @@
@@ -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; |
||||
} |
@ -1,14 +0,0 @@
@@ -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; |
||||
} |
@ -1,30 +0,0 @@
@@ -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; |
||||
} |
||||
|
||||
} |
@ -1,26 +0,0 @@
@@ -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; |
||||
} |
||||
} |
@ -1,90 +0,0 @@
@@ -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); |
||||
} |
@ -1,116 +0,0 @@
@@ -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); |
||||
} |
||||
|
||||
} |
@ -1,44 +0,0 @@
@@ -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(); |
||||
} |
||||
} |
@ -0,0 +1,25 @@
@@ -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); |
||||
} |
||||
|
||||
} |
@ -1,30 +0,0 @@
@@ -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; |
||||
} |
@ -1,53 +0,0 @@
@@ -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(); |
||||
} |
||||
} |
@ -0,0 +1,22 @@
@@ -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; |
||||
} |
@ -1,32 +0,0 @@
@@ -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; |
||||
} |
@ -1,15 +0,0 @@
@@ -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; |
||||
} |
@ -1,18 +0,0 @@
@@ -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; |
||||
} |
@ -1,22 +0,0 @@
@@ -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; |
||||
} |
@ -1,31 +0,0 @@
@@ -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; |
||||
} |
@ -1,31 +0,0 @@
@@ -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; |
||||
} |
@ -0,0 +1,28 @@
@@ -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); |
||||
} |
||||
|
||||
} |
@ -1,25 +0,0 @@
@@ -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; |
||||
|
||||
} |
@ -1,29 +0,0 @@
@@ -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(); |
||||
} |
||||
} |
@ -1,26 +0,0 @@
@@ -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(); |
||||
} |
||||
} |
@ -1,29 +0,0 @@
@@ -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(); |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue