diff --git a/config/nacos/dk-gen.yml b/config/nacos/dk-gen.yml index f15a248..d49f3f6 100644 --- a/config/nacos/dk-gen.yml +++ b/config/nacos/dk-gen.yml @@ -3,7 +3,7 @@ spring: dynamic: # 设置默认的数据源或者数据源组,默认值即为 master primary: master - seata: false + seata: true datasource: # 主库数据源 master: diff --git a/config/nacos/dk-job.yml b/config/nacos/dk-job.yml index 2fa9a7e..6af577b 100644 --- a/config/nacos/dk-job.yml +++ b/config/nacos/dk-job.yml @@ -3,7 +3,7 @@ spring: dynamic: # 设置默认的数据源或者数据源组,默认值即为 master primary: master - seata: false + seata: true datasource: # 主库数据源 master: diff --git a/config/nacos/dk-monitor.yml b/config/nacos/dk-monitor.yml index 92ca041..2212d7e 100644 --- a/config/nacos/dk-monitor.yml +++ b/config/nacos/dk-monitor.yml @@ -10,4 +10,4 @@ spring: title: RuoYi-Cloud-Plus服务监控中心 discovery: # seata 不具有健康检查的能力 防止报错排除掉 - ignored-services: ruoyi-seata-server + ignored-services: dk-seata-server diff --git a/config/nacos/seata-server.properties b/config/nacos/seata-server.properties index 8ad7dad..6e5224c 100644 --- a/config/nacos/seata-server.properties +++ b/config/nacos/seata-server.properties @@ -1,7 +1,7 @@ -service.vgroupMapping.ruoyi-auth-group=default -service.vgroupMapping.ruoyi-system-group=default -service.vgroupMapping.ruoyi-resource-group=default -service.vgroupMapping.ruoyi-workflow-group=default +service.vgroupMapping.dk-auth-group=default +service.vgroupMapping.dk-system-group=default +service.vgroupMapping.dk-resource-group=default +service.vgroupMapping.dk-workflow-group=default service.enableDegrade=false service.disableGlobalTransaction=false diff --git a/config/nacos/sentinel-ruoyi-gateway.json b/config/nacos/sentinel-dk-gateway.json similarity index 78% rename from config/nacos/sentinel-ruoyi-gateway.json rename to config/nacos/sentinel-dk-gateway.json index 667faac..740eb0c 100644 --- a/config/nacos/sentinel-ruoyi-gateway.json +++ b/config/nacos/sentinel-dk-gateway.json @@ -1,6 +1,6 @@ [ { - "resource": "ruoyi-auth", + "resource": "dk-auth", "count": 500, "grade": 1, "limitApp": "default", @@ -8,7 +8,7 @@ "controlBehavior": 0 }, { - "resource": "ruoyi-system", + "resource": "dk-system", "count": 1000, "grade": 1, "limitApp": "default", @@ -16,7 +16,7 @@ "controlBehavior": 0 }, { - "resource": "ruoyi-resource", + "resource": "dk-resource", "count": 500, "grade": 1, "limitApp": "default", diff --git a/dk-common/common-cloudsdk/README.md b/dk-common/common-cloudsdk/README.md new file mode 100644 index 0000000..f0b8a5f --- /dev/null +++ b/dk-common/common-cloudsdk/README.md @@ -0,0 +1,48 @@ +# 如何接入CloudSDK +### 1. 在组件扫描中增加包名:org.dromara.common.sdk +### [2. 连接MQTT](#如何连接MQTT) +### [3. 实现SDK 的方法](#如何实现SDK的方法) +### [4. 调用SDK 的方法](#如何调用SDK的方法) + + +## 如何连接MQTT +- 在spring容器中注入MqttConnectOptions和MqttPahoClientFactory; + ![1](./image/6.png) + +- 在application.yml中配置cloud-sdk.mqtt.inbound-topic,未配置则不进行初始化订阅。 + + +## 如何实现SDK的方法 + - 定义一个类,继承org.dromara.common.sdk.cloudapi.*.api包中的抽象类; + - 重写具体的方法以实现功能; + - 将定义的类放入spring容器中,由spring管理bean的生命周期。 +### 【设备上线】示例: + - 定义一个类:SDKDeviceService 继承AbstractDeviceService; +![1](./image/1.png) + - 重写方法updateTopoOnline,实现设备上线功能。 +![1](./image/2.png) + +## 如何调用SDK的方法 + - 定义一个类,继承org.dromara.common.sdk.cloudapi.*.api包中的抽象类; + - 在需要调用的类中注入该类; + - 调用具体的方法。 +### 【航线预下发命令】示例: + - 定义一个类:SDKWaylineService 继承 AbstractWaylineService; +![1](./image/3.png) + - 在WaylineJobServiceImpl中注入该类; +![1](./image/4.png) + - 调用下发命令的方法: +![1](./image/5.png) + +## 如何实现CloudAPI 定义的http 接口 + - 定义一个类,实现org.dromara.common.sdk.cloudapi.*.api包中的http接口类; + - 重写具体的方法以实现接口,无需定义请求地址和方法等数据。 + ![1](./image/7.png) + +## 如何查看CloudAPI 定义的所有http 接口 + - 启动程序 + - 浏览器打开:http://localhost:6789/swagger-ui/index.html + +## 如何接入WebSocket + - CloudSDK 已经定义了WebSocket服务,但是没有实现WebSocket管理。默认地址为:http://localhost:6789/api/v1/ws + - 自定义接入参考:org.dromara.common.sample.component.websocket.config \ No newline at end of file diff --git a/dk-common/common-cloudsdk/image/1.png b/dk-common/common-cloudsdk/image/1.png new file mode 100644 index 0000000..8d57aa8 Binary files /dev/null and b/dk-common/common-cloudsdk/image/1.png differ diff --git a/dk-common/common-cloudsdk/image/2.png b/dk-common/common-cloudsdk/image/2.png new file mode 100644 index 0000000..7fc331a Binary files /dev/null and b/dk-common/common-cloudsdk/image/2.png differ diff --git a/dk-common/common-cloudsdk/image/3.png b/dk-common/common-cloudsdk/image/3.png new file mode 100644 index 0000000..c31bdb6 Binary files /dev/null and b/dk-common/common-cloudsdk/image/3.png differ diff --git a/dk-common/common-cloudsdk/image/4.png b/dk-common/common-cloudsdk/image/4.png new file mode 100644 index 0000000..23a277b Binary files /dev/null and b/dk-common/common-cloudsdk/image/4.png differ diff --git a/dk-common/common-cloudsdk/image/5.png b/dk-common/common-cloudsdk/image/5.png new file mode 100644 index 0000000..5e81513 Binary files /dev/null and b/dk-common/common-cloudsdk/image/5.png differ diff --git a/dk-common/common-cloudsdk/image/6.png b/dk-common/common-cloudsdk/image/6.png new file mode 100644 index 0000000..6a9169c Binary files /dev/null and b/dk-common/common-cloudsdk/image/6.png differ diff --git a/dk-common/common-cloudsdk/image/7.png b/dk-common/common-cloudsdk/image/7.png new file mode 100644 index 0000000..52ee49f Binary files /dev/null and b/dk-common/common-cloudsdk/image/7.png differ diff --git a/dk-common/common-cloudsdk/pom.xml b/dk-common/common-cloudsdk/pom.xml new file mode 100644 index 0000000..278a1d4 --- /dev/null +++ b/dk-common/common-cloudsdk/pom.xml @@ -0,0 +1,32 @@ + + + + org.dromara + dk-common + ${revision} + + 4.0.0 + + + common-cloudsdk + + + + org.springframework.integration + spring-integration-mqtt + ${spring-integration-mqtt.version} + + + org.springdoc + springdoc-openapi-ui + ${openapi-ui.version} + + + org.dromara + common-core + + + + diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/annotations/CloudSDKVersion.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/annotations/CloudSDKVersion.java new file mode 100644 index 0000000..11b67b5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/annotations/CloudSDKVersion.java @@ -0,0 +1,26 @@ +package org.dromara.common.sdk.annotations; + +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; + +import java.lang.annotation.*; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/22 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.METHOD}) +public @interface CloudSDKVersion { + + CloudSDKVersionEnum since() default CloudSDKVersionEnum.V0_0_1; + + CloudSDKVersionEnum deprecated() default CloudSDKVersionEnum.V99; + + GatewayTypeEnum[] include() default {}; + + GatewayTypeEnum[] exclude() default {}; + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/AirsenseWarning.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/AirsenseWarning.java new file mode 100644 index 0000000..38f51e8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/AirsenseWarning.java @@ -0,0 +1,178 @@ +package org.dromara.common.sdk.cloudapi.airsense; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public class AirsenseWarning { + + /** + * ICAO civil aviation aircraft address + */ + private String icao; + + /** + * The higher the danger level, the more dangerous it is. + * For levels greater than or equal to 3, it is recommended for aircraft to take evasive action. + */ + private WarningLevelEnum warningLevel; + + /** + * The latitude of aircraft location is angular values. + * Negative values for south latitude and positive values for north latitude. + * It is accurate to six decimal places. + */ + private Float latitude; + + /** + * The longitude of aircraft location is angular values. + * Negative values for west longitude and positive values for east longitude. + * It is accurate to six decimal places. + */ + private Float longitude; + + /** + * Absolute height of flight. + * Unit: meter + */ + private Integer altitude; + + /** + * Absolute height type + */ + private AltitudeTypeEnum altitudeType; + + /** + * The angle of heading is angular values. + * 0 is north. 90 is east. + * It is accurate to one decimal places. + */ + private Float heading; + + /** + * Relative height of flight to aircraft. + * Unit: meter + */ + private Integer relativeAltitude; + + /** + * Relative height change trend + */ + private VertTrendEnum vertTrend; + + /** + * Horizontal distance to aircraft. + * Unit: meter + */ + private Integer distance; + + public AirsenseWarning() { + } + + @Override + public String toString() { + return "AirsenseWarning{" + + "icao='" + icao + '\'' + + ", warningLevel=" + warningLevel + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", altitude=" + altitude + + ", altitudeType=" + altitudeType + + ", heading=" + heading + + ", relativeAltitude=" + relativeAltitude + + ", vertTrend=" + vertTrend + + ", distance=" + distance + + '}'; + } + + public String getIcao() { + return icao; + } + + public AirsenseWarning setIcao(String icao) { + this.icao = icao; + return this; + } + + public WarningLevelEnum getWarningLevel() { + return warningLevel; + } + + public AirsenseWarning setWarningLevel(WarningLevelEnum warningLevel) { + this.warningLevel = warningLevel; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public AirsenseWarning setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public AirsenseWarning setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Integer getAltitude() { + return altitude; + } + + public AirsenseWarning setAltitude(Integer altitude) { + this.altitude = altitude; + return this; + } + + public AltitudeTypeEnum getAltitudeType() { + return altitudeType; + } + + public AirsenseWarning setAltitudeType(AltitudeTypeEnum altitudeType) { + this.altitudeType = altitudeType; + return this; + } + + public Float getHeading() { + return heading; + } + + public AirsenseWarning setHeading(Float heading) { + this.heading = heading; + return this; + } + + public Integer getRelativeAltitude() { + return relativeAltitude; + } + + public AirsenseWarning setRelativeAltitude(Integer relativeAltitude) { + this.relativeAltitude = relativeAltitude; + return this; + } + + public VertTrendEnum getVertTrend() { + return vertTrend; + } + + public AirsenseWarning setVertTrend(VertTrendEnum vertTrend) { + this.vertTrend = vertTrend; + return this; + } + + public Integer getDistance() { + return distance; + } + + public AirsenseWarning setDistance(Integer distance) { + this.distance = distance; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/AltitudeTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/AltitudeTypeEnum.java new file mode 100644 index 0000000..93eb209 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/AltitudeTypeEnum.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.airsense; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public enum AltitudeTypeEnum { + + ELLIPSOID_HEIGHT(0), + + ABOVE_SEA_LEVEL(1), + + ; + + private final int type; + + AltitudeTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static AltitudeTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(AltitudeTypeEnum.class, type)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/VertTrendEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/VertTrendEnum.java new file mode 100644 index 0000000..0671c26 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/VertTrendEnum.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.airsense; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public enum VertTrendEnum { + + RELATIVE_HEIGHT_UNCHANGED(0), + + RELATIVE_HEIGHT_INCREASE(1), + + RELATIVE_HEIGHT_DECREASE(2), + + ; + + private final int trend; + + VertTrendEnum(int trend) { + this.trend = trend; + } + + @JsonValue + public int getTrend() { + return trend; + } + + @JsonCreator + public static VertTrendEnum find(int trend) { + return Arrays.stream(values()).filter(trendEnum -> trendEnum.trend == trend).findAny() + .orElseThrow(() -> new CloudSDKException(VertTrendEnum.class, trend)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/WarningLevelEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/WarningLevelEnum.java new file mode 100644 index 0000000..b92c145 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/WarningLevelEnum.java @@ -0,0 +1,45 @@ +package org.dromara.common.sdk.cloudapi.airsense; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public enum WarningLevelEnum { + + ZERO(0), + + ONE(1), + + TWO(2), + + THREE(3), + + FOUR(4), + + ; + + private final int level; + + WarningLevelEnum(int level) { + this.level = level; + } + + @JsonValue + public int getLevel() { + return level; + } + + @JsonCreator + public static WarningLevelEnum find(int level) { + return Arrays.stream(values()).filter(levelEnum -> levelEnum.level == level).findAny() + .orElseThrow(() -> new CloudSDKException(WarningLevelEnum.class, level)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/api/AbstractAirsenseService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/api/AbstractAirsenseService.java new file mode 100644 index 0000000..cf6012e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/airsense/api/AbstractAirsenseService.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.airsense.api; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.airsense.AirsenseWarning; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.events.TopicEventsRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsResponse; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public abstract class AbstractAirsenseService { + + + /** + * cloud-custom data transmit from psdk + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_AIRSENSE_WARNING, outputChannel = ChannelName.OUTBOUND_EVENTS) + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + public TopicEventsResponse airsenseWarning(TopicEventsRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("airsenseWarning not implemented"); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/ConfigScopeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/ConfigScopeEnum.java new file mode 100644 index 0000000..c95fb73 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/ConfigScopeEnum.java @@ -0,0 +1,34 @@ +package org.dromara.common.sdk.cloudapi.config; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +public enum ConfigScopeEnum { + + PRODUCT("product"); + + private final String scope; + + ConfigScopeEnum(String scope) { + this.scope = scope; + } + + @JsonValue + public String getScope() { + return scope; + } + + @JsonCreator + public static ConfigScopeEnum find(String scope) { + return Arrays.stream(values()).filter(scopeEnum -> scopeEnum.scope.equals(scope)).findAny() + .orElseThrow(() -> new CloudSDKException(ConfigScopeEnum.class, scope)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/ConfigTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/ConfigTypeEnum.java new file mode 100644 index 0000000..dd7f1da --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/ConfigTypeEnum.java @@ -0,0 +1,34 @@ +package org.dromara.common.sdk.cloudapi.config; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +public enum ConfigTypeEnum { + + JSON("json"); + + private final String type; + + ConfigTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static ConfigTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(ConfigTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/ProductConfigResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/ProductConfigResponse.java new file mode 100644 index 0000000..612cad2 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/ProductConfigResponse.java @@ -0,0 +1,73 @@ +package org.dromara.common.sdk.cloudapi.config; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +public class ProductConfigResponse extends BaseModel { + + private String ntpServerHost; + + @NotNull + private String appId; + + @NotNull + private String appKey; + + @NotNull + private String appLicense; + + public ProductConfigResponse() { + } + + @Override + public String toString() { + return "ProductConfigResponse{" + + "ntpServerHost='" + ntpServerHost + '\'' + + ", appId='" + appId + '\'' + + ", appKey='" + appKey + '\'' + + ", appLicense='" + appLicense + '\'' + + '}'; + } + + public String getNtpServerHost() { + return ntpServerHost; + } + + public ProductConfigResponse setNtpServerHost(String ntpServerHost) { + this.ntpServerHost = ntpServerHost; + return this; + } + + public String getAppId() { + return appId; + } + + public ProductConfigResponse setAppId(String appId) { + this.appId = appId; + return this; + } + + public String getAppKey() { + return appKey; + } + + public ProductConfigResponse setAppKey(String appKey) { + this.appKey = appKey; + return this; + } + + public String getAppLicense() { + return appLicense; + } + + public ProductConfigResponse setAppLicense(String appLicense) { + this.appLicense = appLicense; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/RequestsConfigRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/RequestsConfigRequest.java new file mode 100644 index 0000000..3c28394 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/RequestsConfigRequest.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.config; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +public class RequestsConfigRequest { + + private ConfigTypeEnum configType; + + private ConfigScopeEnum configScope; + + public RequestsConfigRequest() { + } + + @Override + public String toString() { + return "RequestsConfigRequest{" + + "configType=" + configType + + ", configScope=" + configScope + + '}'; + } + + public ConfigTypeEnum getConfigType() { + return configType; + } + + public RequestsConfigRequest setConfigType(ConfigTypeEnum configType) { + this.configType = configType; + return this; + } + + public ConfigScopeEnum getConfigScope() { + return configScope; + } + + public RequestsConfigRequest setConfigScope(ConfigScopeEnum configScope) { + this.configScope = configScope; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/api/AbstractConfigService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/api/AbstractConfigService.java new file mode 100644 index 0000000..966cc2f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/config/api/AbstractConfigService.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.config.api; + +import org.dromara.common.sdk.cloudapi.config.ProductConfigResponse; +import org.dromara.common.sdk.cloudapi.config.RequestsConfigRequest; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsRequest; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsResponse; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public abstract class AbstractConfigService { + + /** + * Inform of file uploading progress + * @param request data + * @param headers The headers for a {@link Message}. + * @return requests_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_CONFIG, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse requestsConfig(TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("requestsConfig not implemented"); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraAimRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraAimRequest.java new file mode 100644 index 0000000..607e3a6 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraAimRequest.java @@ -0,0 +1,99 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraAimRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private CameraTypeEnum cameraType; + + /** + * true: Lock the gimbal, the gimbal and the drone rotate together. + * false: Only the gimbal rotates, but the drone does not. + */ + @NotNull + private Boolean locked; + + /** + * upper left corner as center point + */ + @Min(0) + @Max(1) + private Float x; + + @Min(0) + @Max(1) + private Float y; + + public CameraAimRequest() { + } + + @Override + public String toString() { + return "CameraAimRequest{" + + "payloadIndex=" + payloadIndex + + ", cameraType=" + cameraType + + ", locked=" + locked + + ", x=" + x + + ", y=" + y + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraAimRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public CameraTypeEnum getCameraType() { + return cameraType; + } + + public CameraAimRequest setCameraType(CameraTypeEnum cameraType) { + this.cameraType = cameraType; + return this; + } + + public Boolean getLocked() { + return locked; + } + + public CameraAimRequest setLocked(Boolean locked) { + this.locked = locked; + return this; + } + + public Float getX() { + return x; + } + + public CameraAimRequest setX(Float x) { + this.x = x; + return this; + } + + public Float getY() { + return y; + } + + public CameraAimRequest setY(Float y) { + this.y = y; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraExposureModeSetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraExposureModeSetRequest.java new file mode 100644 index 0000000..2be894e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraExposureModeSetRequest.java @@ -0,0 +1,68 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class CameraExposureModeSetRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private ExposureCameraTypeEnum cameraType; + + @NotNull + private ExposureModeEnum exposureMode; + + public CameraExposureModeSetRequest() { + } + + @Override + public String toString() { + return "CameraExposureModeSetRequest{" + + "payloadIndex=" + payloadIndex + + ", cameraType=" + cameraType + + ", exposureMode=" + exposureMode + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraExposureModeSetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ExposureCameraTypeEnum getCameraType() { + return cameraType; + } + + public CameraExposureModeSetRequest setCameraType(ExposureCameraTypeEnum cameraType) { + this.cameraType = cameraType; + return this; + } + + public ExposureModeEnum getExposureMode() { + return exposureMode; + } + + public CameraExposureModeSetRequest setExposureMode(ExposureModeEnum exposureMode) { + this.exposureMode = exposureMode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraExposureSetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraExposureSetRequest.java new file mode 100644 index 0000000..6edc152 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraExposureSetRequest.java @@ -0,0 +1,68 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class CameraExposureSetRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private ExposureCameraTypeEnum cameraType; + + @NotNull + private ExposureValueEnum exposureValue; + + public CameraExposureSetRequest() { + } + + @Override + public String toString() { + return "CameraExposureSetRequest{" + + "payloadIndex=" + payloadIndex + + ", cameraType=" + cameraType + + ", exposureValue=" + exposureValue + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraExposureSetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ExposureCameraTypeEnum getCameraType() { + return cameraType; + } + + public CameraExposureSetRequest setCameraType(ExposureCameraTypeEnum cameraType) { + this.cameraType = cameraType; + return this; + } + + public ExposureValueEnum getExposureValue() { + return exposureValue; + } + + public CameraExposureSetRequest setExposureValue(ExposureValueEnum exposureValue) { + this.exposureValue = exposureValue; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraFocalLengthSetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraFocalLengthSetRequest.java new file mode 100644 index 0000000..9913774 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraFocalLengthSetRequest.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraFocalLengthSetRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private ZoomCameraTypeEnum cameraType; + + @Min(2) + @Max(200) + @NotNull + private Float zoomFactor; + + public CameraFocalLengthSetRequest() { + } + + @Override + public String toString() { + return "CameraFocalLengthSetRequest{" + + "payloadIndex=" + payloadIndex + + ", cameraType=" + cameraType + + ", zoomFactor=" + zoomFactor + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraFocalLengthSetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ZoomCameraTypeEnum getCameraType() { + return cameraType; + } + + public CameraFocalLengthSetRequest setCameraType(ZoomCameraTypeEnum cameraType) { + this.cameraType = cameraType; + return this; + } + + public Float getZoomFactor() { + return zoomFactor; + } + + public CameraFocalLengthSetRequest setZoomFactor(Float zoomFactor) { + this.zoomFactor = zoomFactor; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraFocusModeSetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraFocusModeSetRequest.java new file mode 100644 index 0000000..c7367f2 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraFocusModeSetRequest.java @@ -0,0 +1,68 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class CameraFocusModeSetRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private ExposureCameraTypeEnum cameraType; + + @NotNull + private FocusModeEnum focusMode; + + public CameraFocusModeSetRequest() { + } + + @Override + public String toString() { + return "CameraFocusModeSetRequest{" + + "payloadIndex=" + payloadIndex + + ", cameraType=" + cameraType + + ", focusMode=" + focusMode + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraFocusModeSetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ExposureCameraTypeEnum getCameraType() { + return cameraType; + } + + public CameraFocusModeSetRequest setCameraType(ExposureCameraTypeEnum cameraType) { + this.cameraType = cameraType; + return this; + } + + public FocusModeEnum getFocusMode() { + return focusMode; + } + + public CameraFocusModeSetRequest setFocusMode(FocusModeEnum focusMode) { + this.focusMode = focusMode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraFocusValueSetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraFocusValueSetRequest.java new file mode 100644 index 0000000..87024d0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraFocusValueSetRequest.java @@ -0,0 +1,68 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class CameraFocusValueSetRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private ExposureCameraTypeEnum cameraType; + + @NotNull + private Integer focusValue; + + public CameraFocusValueSetRequest() { + } + + @Override + public String toString() { + return "CameraFocusValueSetRequest{" + + "payloadIndex=" + payloadIndex + + ", cameraType=" + cameraType + + ", focusValue=" + focusValue + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraFocusValueSetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ExposureCameraTypeEnum getCameraType() { + return cameraType; + } + + public CameraFocusValueSetRequest setCameraType(ExposureCameraTypeEnum cameraType) { + this.cameraType = cameraType; + return this; + } + + public Integer getFocusValue() { + return focusValue; + } + + public CameraFocusValueSetRequest setFocusValue(Integer focusValue) { + this.focusValue = focusValue; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraLookAtRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraLookAtRequest.java new file mode 100644 index 0000000..c9f5b81 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraLookAtRequest.java @@ -0,0 +1,97 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/12 + */ +public class CameraLookAtRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + /** + * Whether the relative location of drone head and gimbal is locked + */ + @NotNull + private Boolean locked; + + /** + * The latitude of target point is angular values. + * Negative values for south latitude and positive values for north latitude. + * It is accurate to six decimal places. + */ + @Min(-90) + @Max(90) + @NotNull + private Float latitude; + + /** + * The latitude of target point is angular values. + * Negative values for west longitude and positive values for east longitude. + * It is accurate to six decimal places. + */ + @NotNull + @Min(-180) + @Max(180) + private Float longitude; + + /** + * Ellipsoid height + */ + @NotNull + @Min(2) + @Max(10000) + private Float height; + + public CameraLookAtRequest() { + } + + @Override + public String toString() { + return "CameraLookAtRequest{" + + "payloadIndex=" + payloadIndex + + ", locked=" + locked + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + '}'; + } + + public CameraLookAtRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public CameraLookAtRequest setLocked(Boolean locked) { + this.locked = locked; + return this; + } + + public CameraLookAtRequest setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public CameraLookAtRequest setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public CameraLookAtRequest setHeight(Float height) { + this.height = height; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraModeSwitchRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraModeSwitchRequest.java new file mode 100644 index 0000000..de724b8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraModeSwitchRequest.java @@ -0,0 +1,50 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.CameraModeEnum; +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraModeSwitchRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private CameraModeEnum cameraMode; + + public CameraModeSwitchRequest() { + } + + @Override + public String toString() { + return "CameraModeSwitchRequest{" + + "payloadIndex=" + payloadIndex + + ", cameraMode=" + cameraMode + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraModeSwitchRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public CameraModeEnum getCameraMode() { + return cameraMode; + } + + public CameraModeSwitchRequest setCameraMode(CameraModeEnum cameraMode) { + this.cameraMode = cameraMode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPhotoStopRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPhotoStopRequest.java new file mode 100644 index 0000000..40f69d9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPhotoStopRequest.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class CameraPhotoStopRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + public CameraPhotoStopRequest() { + } + + @Override + public String toString() { + return "CameraPhotoStopRequest{" + + "payloadIndex=" + payloadIndex + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraPhotoStopRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPhotoTakeProgress.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPhotoTakeProgress.java new file mode 100644 index 0000000..afc25eb --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPhotoTakeProgress.java @@ -0,0 +1,56 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.wayline.FlighttaskStatusEnum; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class CameraPhotoTakeProgress { + + private PhotoTakeProgressExt ext; + + private PhotoTakeProgressData progress; + + private FlighttaskStatusEnum status; + + public CameraPhotoTakeProgress() { + } + + @Override + public String toString() { + return "CameraPhotoTakeProgress{" + + "ext=" + ext + + ", progress=" + progress + + ", status=" + status + + '}'; + } + + public PhotoTakeProgressExt getExt() { + return ext; + } + + public CameraPhotoTakeProgress setExt(PhotoTakeProgressExt ext) { + this.ext = ext; + return this; + } + + public PhotoTakeProgressData getProgress() { + return progress; + } + + public CameraPhotoTakeProgress setProgress(PhotoTakeProgressData progress) { + this.progress = progress; + return this; + } + + public FlighttaskStatusEnum getStatus() { + return status; + } + + public CameraPhotoTakeProgress setStatus(FlighttaskStatusEnum status) { + this.status = status; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPhotoTakeRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPhotoTakeRequest.java new file mode 100644 index 0000000..0c7c771 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPhotoTakeRequest.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraPhotoTakeRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + public CameraPhotoTakeRequest() { + } + + @Override + public String toString() { + return "CameraPhotoTakeRequest{" + + "payloadIndex=" + payloadIndex + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraPhotoTakeRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPointFocusActionRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPointFocusActionRequest.java new file mode 100644 index 0000000..183d32b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraPointFocusActionRequest.java @@ -0,0 +1,93 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class CameraPointFocusActionRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private ExposureCameraTypeEnum cameraType; + + /** + * The coordinate x of the temperature measurement point is the upper left corner of the lens as the coordinate center point, and the horizontal direction is x. + */ + @NotNull + @Min(0) + @Max(1) + private Float x; + + /** + * The coordinate y of the temperature measurement point is the upper left corner of the lens as the coordinate center point, and the vertical direction is y. + */ + @NotNull + @Min(0) + @Max(1) + private Float y; + + public CameraPointFocusActionRequest() { + } + + @Override + public String toString() { + return "CameraPointFocusActionRequest{" + + "payloadIndex=" + payloadIndex + + ", cameraType=" + cameraType + + ", x=" + x + + ", y=" + y + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraPointFocusActionRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ExposureCameraTypeEnum getCameraType() { + return cameraType; + } + + public CameraPointFocusActionRequest setCameraType(ExposureCameraTypeEnum cameraType) { + this.cameraType = cameraType; + return this; + } + + public Float getX() { + return x; + } + + public CameraPointFocusActionRequest setX(Float x) { + this.x = x; + return this; + } + + public Float getY() { + return y; + } + + public CameraPointFocusActionRequest setY(Float y) { + this.y = y; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraRecordingStartRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraRecordingStartRequest.java new file mode 100644 index 0000000..5fbf2a4 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraRecordingStartRequest.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraRecordingStartRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + public CameraRecordingStartRequest() { + } + + @Override + public String toString() { + return "CameraRecordingStartRequest{" + + "payloadIndex=" + payloadIndex + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraRecordingStartRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraRecordingStopRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraRecordingStopRequest.java new file mode 100644 index 0000000..926dbae --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraRecordingStopRequest.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class CameraRecordingStopRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + public CameraRecordingStopRequest() { + } + + @Override + public String toString() { + return "CameraRecordingStopRequest{" + + "payloadIndex=" + payloadIndex + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraRecordingStopRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraScreenSplitRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraScreenSplitRequest.java new file mode 100644 index 0000000..4081ade --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraScreenSplitRequest.java @@ -0,0 +1,58 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/12 + */ +public class CameraScreenSplitRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + /** + * Whether enable the screen split + */ + @NotNull + private Boolean enable; + + public CameraScreenSplitRequest() { + } + + @Override + public String toString() { + return "CameraScreenSplitRequest{" + + "payloadIndex=" + payloadIndex + + ", enable=" + enable + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public CameraScreenSplitRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public Boolean getEnable() { + return enable; + } + + public CameraScreenSplitRequest setEnable(Boolean enable) { + this.enable = enable; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraTypeEnum.java new file mode 100644 index 0000000..37571ee --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CameraTypeEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public enum CameraTypeEnum { + + ZOOM("zoom"), + + WIDE("wide"), + + IR("ir"); + + private final String type; + + CameraTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static CameraTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(CameraTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CommanderFlightModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CommanderFlightModeEnum.java new file mode 100644 index 0000000..7d80e7e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CommanderFlightModeEnum.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/8/7 + */ +public enum CommanderFlightModeEnum { + + SMART_HEIGHT(0), + + SETTING_HEIGHT(1); + + private final int mode; + + CommanderFlightModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static CommanderFlightModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(CommanderFlightModeEnum.class, mode)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CommanderModeLostActionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CommanderModeLostActionEnum.java new file mode 100644 index 0000000..9492e48 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/CommanderModeLostActionEnum.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum CommanderModeLostActionEnum { + + CONTINUE(0), + + EXECUTE_RC_LOST_ACTION(1); + + private final int action; + + CommanderModeLostActionEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static CommanderModeLostActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(CommanderModeLostActionEnum.class, action)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ControlErrorCodeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ControlErrorCodeEnum.java new file mode 100644 index 0000000..9304aff --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ControlErrorCodeEnum.java @@ -0,0 +1,91 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.common.IErrorInfo; +import org.dromara.common.sdk.mqtt.events.IEventsErrorCode; +import org.dromara.common.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum ControlErrorCodeEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + SETTING_RTH_FAILED(327000, "Height of return to home setting failed."), + + SETTING_LOST_ACTION_FAILED(327001, "Signal lost action setting failed."), + + OBTAIN_CONTROL_FAILED(327002, "Failed to obtain control."), + + DEVICE_OFFLINE(327003, "Failed to obtain control. Device offline."), + + DRAG_LIVESTREAM_VIEW_FAILED(327004, "Failed to drag livestream view."), + + AIM_FAILED(327005, "Failed to double tab to be AIM."), + + TAKE_PHOTO_FAILED(327006, "Failed to take photo."), + + START_RECORDING_FAILED(327007, "Failed to start recording."), + + STOP_RECORDING_FAILED(327008, "Failed to stop recording."), + + SWITCH_CAMERA_MODE_FAILED(327009, "Failed to switch camera modes."), + + ZOOM_CAMERA_ZOOM_FAILED(327010, "Failed to zoom in/out with zoom camera."), + + IR_CAMERA_ZOOM_FAILED(327011, "Failed to zoom in/out with IR camera."), + + DEVICE_LOCK(327012, "Failed to obtain control. Device is locked."), + + SETTING_WAYLINE_LOST_ACTION_FAILED(327013, "Wayline signal lost action setting failed."), + + GIMBAL_REACH_LIMIT(327014, "Gimbal reached movement limit."), + + WRONG_LENS_TYPE(327015, "Invalid camera lens type."), + + + DRC_ABNORMAL(514300, "DRC abnormal."), + + DRC_HEARTBEAT_TIMED_OUT(514301, "DRC heartbeat timed out."), + + DRC_CERTIFICATE_ABNORMAL(514302, "DRC certificate is abnormal."), + + DRC_LINK_LOST(514303, "DRC link is lost."), + + DRC_LINK_REFUSED(514304, "DRC link is refused."), + + UNKNOWN(-1, "UNKNOWN"), + + ; + + + private final String msg; + + private final int code; + + ControlErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + /** + * @param code error code + * @return enumeration object + */ + public static ControlErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ControlMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ControlMethodEnum.java new file mode 100644 index 0000000..79ce196 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ControlMethodEnum.java @@ -0,0 +1,90 @@ +package org.dromara.common.sdk.cloudapi.control; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/2 + */ +public enum ControlMethodEnum { + + FLIGHT_AUTHORITY_GRAB("flight_authority_grab"), + + PAYLOAD_AUTHORITY_GRAB("payload_authority_grab"), + + DRC_MODE_ENTER("drc_mode_enter"), + + DRC_MODE_EXIT("drc_mode_exit"), + + FLY_TO_POINT("fly_to_point"), + + FLY_TO_POINT_STOP("fly_to_point_stop"), + + FLY_TO_POINT_UPDATE("fly_to_point_update"), + + TAKEOFF_TO_POINT("takeoff_to_point"), + + CAMERA_MODE_SWITCH("camera_mode_switch"), + + CAMERA_PHOTO_TAKE("camera_photo_take"), + + CAMERA_PHOTO_STOP("camera_photo_stop"), + + CAMERA_RECORDING_START("camera_recording_start"), + + CAMERA_RECORDING_STOP("camera_recording_stop"), + + CAMERA_AIM("camera_aim"), + + CAMERA_FOCAL_LENGTH_SET("camera_focal_length_set"), + + GIMBAL_RESET("gimbal_reset"), + + CAMERA_LOOK_AT("camera_look_at"), + + CAMERA_SCREEN_SPLIT("camera_screen_split"), + + PHOTO_STORAGE_SET("photo_storage_set"), + + VIDEO_STORAGE_SET("video_storage_set"), + + CAMERA_EXPOSURE_SET("camera_exposure_set"), + + CAMERA_EXPOSURE_MODE_SET("camera_exposure_mode_set"), + + CAMERA_FOCUS_MODE_SET("camera_focus_mode_set"), + + CAMERA_FOCUS_VALUE_SET("camera_focus_value_set"), + + IR_METERING_MODE_SET("ir_metering_mode_set"), + + IR_METERING_POINT_SET("ir_metering_point_set"), + + IR_METERING_AREA_SET("ir_metering_area_set"), + + CAMERA_POINT_FOCUS_ACTION("camera_point_focus_action"), + + DRONE_CONTROL("drone_control"), + + DRONE_EMERGENCY_STOP("drone_emergency_stop"), + + HEART_BEAT("heart_beat"), + + POI_MODE_ENTER("poi_mode_enter"), + + POI_MODE_EXIT("poi_mode_exit"), + + POI_CIRCLE_SPEED_SET("poi_circle_speed_set"), + + ; + + private final String method; + + ControlMethodEnum(String method) { + this.method = method; + } + + public String getMethod() { + return method; + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DelayInfoPush.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DelayInfoPush.java new file mode 100644 index 0000000..5d027e2 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DelayInfoPush.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.cloudapi.control; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class DelayInfoPush { + + private Integer sdrCmdDelay; + + private List liveviewDelayList; + + public DelayInfoPush() { + } + + @Override + public String toString() { + return "DelayInfoPush{" + + "sdrCmdDelay=" + sdrCmdDelay + + ", liveviewDelayList=" + liveviewDelayList + + '}'; + } + + public Integer getSdrCmdDelay() { + return sdrCmdDelay; + } + + public DelayInfoPush setSdrCmdDelay(Integer sdrCmdDelay) { + this.sdrCmdDelay = sdrCmdDelay; + return this; + } + + public List getLiveviewDelayList() { + return liveviewDelayList; + } + + public DelayInfoPush setLiveviewDelayList(List liveviewDelayList) { + this.liveviewDelayList = liveviewDelayList; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcModeEnterRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcModeEnterRequest.java new file mode 100644 index 0000000..e676c01 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcModeEnterRequest.java @@ -0,0 +1,75 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.3 + * @date 2023/1/12 + */ +public class DrcModeEnterRequest extends BaseModel { + + @NotNull + @Valid + private DrcModeMqttBroker mqttBroker; + + /** + * range: 1 - 30 + */ + @Min(1) + @Max(30) + @NotNull + private Integer osdFrequency; + + /** + * range: 1 - 30 + */ + @Min(1) + @Max(30) + @NotNull + private Integer hsiFrequency; + + public DrcModeEnterRequest() { + } + + @Override + public String toString() { + return "DrcModeEnterRequest{" + + "mqttBroker=" + mqttBroker + + ", osdFrequency=" + osdFrequency + + ", hsiFrequency=" + hsiFrequency + + '}'; + } + + public DrcModeMqttBroker getMqttBroker() { + return mqttBroker; + } + + public DrcModeEnterRequest setMqttBroker(DrcModeMqttBroker mqttBroker) { + this.mqttBroker = mqttBroker; + return this; + } + + public Integer getOsdFrequency() { + return osdFrequency; + } + + public DrcModeEnterRequest setOsdFrequency(Integer osdFrequency) { + this.osdFrequency = osdFrequency; + return this; + } + + public Integer getHsiFrequency() { + return hsiFrequency; + } + + public DrcModeEnterRequest setHsiFrequency(Integer hsiFrequency) { + this.hsiFrequency = hsiFrequency; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcModeMqttBroker.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcModeMqttBroker.java new file mode 100644 index 0000000..f36b9b5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcModeMqttBroker.java @@ -0,0 +1,102 @@ +package org.dromara.common.sdk.cloudapi.control; + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/11 + */ +public class DrcModeMqttBroker { + + @NotNull + private String address; + + @NotNull + private String username; + + @NotNull + private String password; + + @NotNull + private String clientId; + + @NotNull + @Min(1234567890) + @Max(9999999999L) + private Long expireTime; + + @NotNull + private Boolean enableTls; + + public DrcModeMqttBroker() { + } + + @Override + public String toString() { + return "DrcModeMqttBroker{" + + "address='" + address + '\'' + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", clientId='" + clientId + '\'' + + ", expireTime=" + expireTime + + ", enableTls=" + enableTls + + '}'; + } + + public String getAddress() { + return address; + } + + public DrcModeMqttBroker setAddress(String address) { + this.address = address; + return this; + } + + public String getUsername() { + return username; + } + + public DrcModeMqttBroker setUsername(String username) { + this.username = username; + return this; + } + + public String getPassword() { + return password; + } + + public DrcModeMqttBroker setPassword(String password) { + this.password = password; + return this; + } + + public String getClientId() { + return clientId; + } + + public DrcModeMqttBroker setClientId(String clientId) { + this.clientId = clientId; + return this; + } + + public Long getExpireTime() { + return expireTime; + } + + public DrcModeMqttBroker setExpireTime(Long expireTime) { + this.expireTime = expireTime; + return this; + } + + public Boolean getEnableTls() { + return enableTls; + } + + public DrcModeMqttBroker setEnableTls(Boolean enableTls) { + this.enableTls = enableTls; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcStatusErrorEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcStatusErrorEnum.java new file mode 100644 index 0000000..069d5c3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcStatusErrorEnum.java @@ -0,0 +1,52 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.common.IErrorInfo; +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/17 + */ +public enum DrcStatusErrorEnum implements IErrorInfo { + + SUCCESS(0, "success"), + + MQTT_ERR(514300, "mqtt连接错误。"), + + HEARTBEAT_TIMEOUT(514301, "心跳超时,底座断开连接。"), + + MQTT_CERTIFICATE_ERR(514302, "mqtt证书异常,连接失败。"), + + MQTT_LOST(514303, "dock网络异常,mqtt连接丢失。"), + + MQTT_REFUSE(514304, "与mqtt服务器的对接连接被拒绝。"); + + private final String msg; + + private final int code; + + DrcStatusErrorEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return msg; + } + + @Override + public Integer getCode() { + return code; + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static DrcStatusErrorEnum find(int code) { + return Arrays.stream(values()).filter(error -> error.code == code).findAny() + .orElseThrow(() -> new CloudSDKException(DrcStatusErrorEnum.class, code)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcStatusNotify.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcStatusNotify.java new file mode 100644 index 0000000..cd2e502 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DrcStatusNotify.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.DrcStateEnum; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/17 + */ +public class DrcStatusNotify { + + private DrcStatusErrorEnum result; + + private DrcStateEnum drcState; + + public DrcStatusNotify() { + } + + @Override + public String toString() { + return "DrcStatusNotify{" + + "result=" + result + + ", drcState=" + drcState + + '}'; + } + + public DrcStatusErrorEnum getResult() { + return result; + } + + public DrcStatusNotify setResult(DrcStatusErrorEnum result) { + this.result = result; + return this; + } + + public DrcStateEnum getDrcState() { + return drcState; + } + + public DrcStatusNotify setDrcState(DrcStateEnum drcState) { + this.drcState = drcState; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DroneControlRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DroneControlRequest.java new file mode 100644 index 0000000..766e747 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DroneControlRequest.java @@ -0,0 +1,121 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class DroneControlRequest extends BaseModel { + + @NotNull + private Long seq; + + @Min(-17) + @Max(17) + private Float x; + + @Min(-17) + @Max(17) + private Float y; + + @Min(-4) + @Max(5) + private Float h; + + @Min(-90) + @Max(90) + private Float w; + + @Min(2) + @Max(10) + private Integer freq; + + @Min(100) + @Max(1000) + private Integer delayTime; + + public DroneControlRequest() { + } + + @Override + public String toString() { + return "DroneControlRequest{" + + "seq=" + seq + + ", x=" + x + + ", y=" + y + + ", h=" + h + + ", w=" + w + + ", freq=" + freq + + ", delayTime=" + delayTime + + '}'; + } + + public Long getSeq() { + return seq; + } + + public DroneControlRequest setSeq(Long seq) { + this.seq = seq; + return this; + } + + public Float getX() { + return x; + } + + public DroneControlRequest setX(Float x) { + this.x = x; + return this; + } + + public Float getY() { + return y; + } + + public DroneControlRequest setY(Float y) { + this.y = y; + return this; + } + + public Float getH() { + return h; + } + + public DroneControlRequest setH(Float h) { + this.h = h; + return this; + } + + public Float getW() { + return w; + } + + public DroneControlRequest setW(Float w) { + this.w = w; + return this; + } + + public Integer getFreq() { + return freq; + } + + public DroneControlRequest setFreq(Integer freq) { + this.freq = freq; + return this; + } + + public Integer getDelayTime() { + return delayTime; + } + + public DroneControlRequest setDelayTime(Integer delayTime) { + this.delayTime = delayTime; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DroneControlResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DroneControlResponse.java new file mode 100644 index 0000000..dc2a2fc --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/DroneControlResponse.java @@ -0,0 +1,31 @@ +package org.dromara.common.sdk.cloudapi.control; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class DroneControlResponse { + + private Long seq; + + public DroneControlResponse() { + } + + @Override + public String toString() { + return "DroneControlResponse{" + + "seq=" + seq + + '}'; + } + + public Long getSeq() { + return seq; + } + + public DroneControlResponse setSeq(Long seq) { + this.seq = seq; + return this; + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ExposureCameraTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ExposureCameraTypeEnum.java new file mode 100644 index 0000000..26922ca --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ExposureCameraTypeEnum.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public enum ExposureCameraTypeEnum { + + ZOOM("zoom"), + + WIDE("wide"); + + private final String type; + + ExposureCameraTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static ExposureCameraTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(ExposureCameraTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ExposureModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ExposureModeEnum.java new file mode 100644 index 0000000..7acdc73 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ExposureModeEnum.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public enum ExposureModeEnum { + + AUTO(1), + + SHUTTER_PRIORITY(2), + + APERTURE_PRIORITY(3), + + MANUAL(4), + + ; + + + private final int mode; + + ExposureModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static ExposureModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(ExposureModeEnum.class, mode)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ExposureValueEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ExposureValueEnum.java new file mode 100644 index 0000000..b82ae57 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ExposureValueEnum.java @@ -0,0 +1,107 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public enum ExposureValueEnum { + + MINUS_5_DOT_0(1, "-5.0EV"), + + MINUS_4_DOT_7(2, "-4.7EV"), + + MINUS_4_DOT_3(3, "-4.3EV"), + + MINUS_4_DOT_0(4, "-4.0EV"), + + MINUS_3_DOT_7(5, "-3.7EV"), + + MINUS_3_DOT_3(6, "-3.3EV"), + + MINUS_3_DOT_0(7, "-3.0EV"), + + MINUS_2_DOT_7(8, "-2.7EV"), + + MINUS_2_DOT_3(9, "-2.3EV"), + + MINUS_2_DOT_0(10, "-2.0EV"), + + MINUS_1_DOT_7(11, "-1.7EV"), + + MINUS_1_DOT_3(12, "-1.3EV"), + + MINUS_1_DOT_0(13, "-1.0EV"), + + MINUS_0_DOT_7(14, "-0.7EV"), + + MINUS_0_DOT_3(15, "-0.3EV"), + + _0(16, "0EV"), + + _0_DOT_3(17, "0.3EV"), + + _0_DOT_7(18, "0.7EV"), + + _1_DOT_0(19, "1.0EV"), + + _1_DOT_3(20, "1.3EV"), + + _1_DOT_7(21, "1.7EV"), + + _2_DOT_0(22, "2.0EV"), + + _2_DOT_3(23, "2.3EV"), + + _2_DOT_7(24, "2.7EV"), + + _3_DOT_0(25, "3.0EV"), + + _3_DOT_3(26, "3.3EV"), + + _3_DOT_7(27, "3.7EV"), + + _4_DOT_0(28, "4.0EV"), + + _4_DOT_3(29, "4.3EV"), + + _4_DOT_7(30, "4.7EV"), + + _5_DOT_0(31, "5.0EV"), + + FIXED(255, "FIXED"), + + ; + + + private final int value; + + private final String desc; + + ExposureValueEnum(int value, String desc) { + this.value = value; + this.desc = desc; + } + + @JsonValue + public int getValue() { + return value; + } + + public String getDesc() { + return desc; + } + + @JsonCreator + public static ExposureValueEnum find(int value) { + return Arrays.stream(values()).filter(valueEnum -> valueEnum.value == value).findAny() + .orElseThrow(() -> new CloudSDKException(ExposureValueEnum.class, value)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToPointProgress.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToPointProgress.java new file mode 100644 index 0000000..a5fdd40 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToPointProgress.java @@ -0,0 +1,68 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.wayline.WaylineErrorCodeEnum; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/14 + */ +public class FlyToPointProgress { + + private WaylineErrorCodeEnum result; + + private FlyToStatusEnum status; + + private String flyToId; + + private Integer wayPointIndex; + + public FlyToPointProgress() { + } + + @Override + public String toString() { + return "FlyToPointProgress{" + + "result=" + result + + ", status=" + status + + ", flyToId='" + flyToId + '\'' + + ", wayPointIndex=" + wayPointIndex + + '}'; + } + + public WaylineErrorCodeEnum getResult() { + return result; + } + + public FlyToPointProgress setResult(WaylineErrorCodeEnum result) { + this.result = result; + return this; + } + + public FlyToStatusEnum getStatus() { + return status; + } + + public FlyToPointProgress setStatus(FlyToStatusEnum status) { + this.status = status; + return this; + } + + public String getFlyToId() { + return flyToId; + } + + public FlyToPointProgress setFlyToId(String flyToId) { + this.flyToId = flyToId; + return this; + } + + public Integer getWayPointIndex() { + return wayPointIndex; + } + + public FlyToPointProgress setWayPointIndex(Integer wayPointIndex) { + this.wayPointIndex = wayPointIndex; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToPointRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToPointRequest.java new file mode 100644 index 0000000..67feb04 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToPointRequest.java @@ -0,0 +1,70 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; + +import java.util.List; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/14 + */ +public class FlyToPointRequest extends BaseModel { + + @Pattern(regexp = "^[^<>:\"/|?*._\\\\]+$") + @NotNull + private String flyToId; + + @Min(1) + @Max(15) + @NotNull + private Integer maxSpeed; + + /** + * The M30 series only support one point. + */ + @Size(min = 1) + @NotNull + private List<@Valid Point> points; + + public FlyToPointRequest() { + } + + @Override + public String toString() { + return "FlyToPointRequest{" + + "flyToId='" + flyToId + '\'' + + ", maxSpeed=" + maxSpeed + + ", points=" + points + + '}'; + } + + public String getFlyToId() { + return flyToId; + } + + public FlyToPointRequest setFlyToId(String flyToId) { + this.flyToId = flyToId; + return this; + } + + public Integer getMaxSpeed() { + return maxSpeed; + } + + public FlyToPointRequest setMaxSpeed(Integer maxSpeed) { + this.maxSpeed = maxSpeed; + return this; + } + + public List getPoints() { + return points; + } + + public FlyToPointRequest setPoints(List points) { + this.points = points; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToPointUpdateRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToPointUpdateRequest.java new file mode 100644 index 0000000..ab09a25 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToPointUpdateRequest.java @@ -0,0 +1,60 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + + +import java.util.List; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class FlyToPointUpdateRequest extends BaseModel { + + @Min(1) + @Max(15) + @NotNull + private Integer maxSpeed; + + /** + * The M30 series only support one point. + */ + @Size(min = 1, max = 1) + @NotNull + private List<@Valid Point> points; + + public FlyToPointUpdateRequest() { + } + + @Override + public String toString() { + return "FlyToPointUpdateRequest{" + + "maxSpeed=" + maxSpeed + + ", points=" + points + + '}'; + } + + public Integer getMaxSpeed() { + return maxSpeed; + } + + public FlyToPointUpdateRequest setMaxSpeed(Integer maxSpeed) { + this.maxSpeed = maxSpeed; + return this; + } + + public List getPoints() { + return points; + } + + public FlyToPointUpdateRequest setPoints(List points) { + this.points = points; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToStatusEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToStatusEnum.java new file mode 100644 index 0000000..7569d2a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FlyToStatusEnum.java @@ -0,0 +1,47 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/14 + */ +public enum FlyToStatusEnum { + + WAYLINE_PROGRESS("wayline_progress", "FlyTo作业正在进行中。"), + + WAYLINE_FAILED("wayline_failed", "FlyTo作业执行失败。"), + + WAYLINE_OK("wayline_ok", "FlyTo作业已成功执行。"), + + WAYLINE_CANCEL("wayline_cancel", "FlyTo作业已关闭。"); + + private final String status; + + private final String message; + + FlyToStatusEnum(String status, String message) { + this.status = status; + this.message = message; + } + + public String getMessage() { + return message; + } + + @JsonValue + public String getStatus() { + return status; + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static FlyToStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(FlyToStatusEnum.class, status)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FocusModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FocusModeEnum.java new file mode 100644 index 0000000..f8bbe7a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/FocusModeEnum.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public enum FocusModeEnum { + + MF(0), + + AFS(1), + + AFC(2), + + ; + private final int mode; + + FocusModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static FocusModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(FocusModeEnum.class, mode)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/GimbalResetModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/GimbalResetModeEnum.java new file mode 100644 index 0000000..31ccfda --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/GimbalResetModeEnum.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/13 + */ +public enum GimbalResetModeEnum { + + RECENTER(0), + + DOWN(1), + + RECENTER_PAN(2), + + PITCH_DOWN(3); + + private final int mode; + + GimbalResetModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static GimbalResetModeEnum find(int mode) { + return Arrays.stream(values()).filter(resetModeEnum -> resetModeEnum.ordinal() == mode).findAny() + .orElseThrow(() -> new CloudSDKException(GimbalResetModeEnum.class, mode)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/GimbalResetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/GimbalResetRequest.java new file mode 100644 index 0000000..693eb0f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/GimbalResetRequest.java @@ -0,0 +1,49 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class GimbalResetRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private GimbalResetModeEnum resetMode; + + public GimbalResetRequest() { + } + + @Override + public String toString() { + return "GimbalResetRequest{" + + "payloadIndex=" + payloadIndex + + ", resetMode=" + resetMode + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public GimbalResetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public GimbalResetModeEnum getResetMode() { + return resetMode; + } + + public GimbalResetRequest setResetMode(GimbalResetModeEnum resetMode) { + this.resetMode = resetMode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/HeartBeatRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/HeartBeatRequest.java new file mode 100644 index 0000000..c2137b0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/HeartBeatRequest.java @@ -0,0 +1,50 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class HeartBeatRequest extends BaseModel { + + @NotNull + private Long seq; + + @NotNull + @Min(123456789012L) + private Long timestamp; + + public HeartBeatRequest() { + } + + @Override + public String toString() { + return "HeartBeatRequest{" + + "seq=" + seq + + ", timestamp=" + timestamp + + '}'; + } + + public Long getSeq() { + return seq; + } + + public HeartBeatRequest setSeq(Long seq) { + this.seq = seq; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public HeartBeatRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/HsiInfoPush.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/HsiInfoPush.java new file mode 100644 index 0000000..6e52b35 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/HsiInfoPush.java @@ -0,0 +1,248 @@ +package org.dromara.common.sdk.cloudapi.control; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class HsiInfoPush { + + private Integer upDistance; + + private Integer downDistance; + + private List aroundDistance; + + private Boolean upEnable; + + private Boolean upWork; + + private Boolean downEnable; + + private Boolean downWork; + + private Boolean leftEnable; + + private Boolean leftWork; + + private Boolean rightEnable; + + private Boolean rightWork; + + private Boolean frontEnable; + + private Boolean frontWork; + + private Boolean backEnable; + + private Boolean backWork; + + private Boolean verticalEnable; + + private Boolean verticalWork; + + private Boolean horizontalEnable; + + private Boolean horizontalWork; + + public HsiInfoPush() { + } + + @Override + public String toString() { + return "HsiInfoPush{" + + "upDistance=" + upDistance + + ", downDistance=" + downDistance + + ", aroundDistance=" + aroundDistance + + ", upEnable=" + upEnable + + ", upWork=" + upWork + + ", downEnable=" + downEnable + + ", downWork=" + downWork + + ", leftEnable=" + leftEnable + + ", leftWork=" + leftWork + + ", rightEnable=" + rightEnable + + ", rightWork=" + rightWork + + ", frontEnable=" + frontEnable + + ", frontWork=" + frontWork + + ", backEnable=" + backEnable + + ", backWork=" + backWork + + ", verticalEnable=" + verticalEnable + + ", verticalWork=" + verticalWork + + ", horizontalEnable=" + horizontalEnable + + ", horizontalWork=" + horizontalWork + + '}'; + } + + public Integer getUpDistance() { + return upDistance; + } + + public HsiInfoPush setUpDistance(Integer upDistance) { + this.upDistance = upDistance; + return this; + } + + public Integer getDownDistance() { + return downDistance; + } + + public HsiInfoPush setDownDistance(Integer downDistance) { + this.downDistance = downDistance; + return this; + } + + public List getAroundDistance() { + return aroundDistance; + } + + public HsiInfoPush setAroundDistance(List aroundDistance) { + this.aroundDistance = aroundDistance; + return this; + } + + public Boolean getUpEnable() { + return upEnable; + } + + public HsiInfoPush setUpEnable(Boolean upEnable) { + this.upEnable = upEnable; + return this; + } + + public Boolean getUpWork() { + return upWork; + } + + public HsiInfoPush setUpWork(Boolean upWork) { + this.upWork = upWork; + return this; + } + + public Boolean getDownEnable() { + return downEnable; + } + + public HsiInfoPush setDownEnable(Boolean downEnable) { + this.downEnable = downEnable; + return this; + } + + public Boolean getDownWork() { + return downWork; + } + + public HsiInfoPush setDownWork(Boolean downWork) { + this.downWork = downWork; + return this; + } + + public Boolean getLeftEnable() { + return leftEnable; + } + + public HsiInfoPush setLeftEnable(Boolean leftEnable) { + this.leftEnable = leftEnable; + return this; + } + + public Boolean getLeftWork() { + return leftWork; + } + + public HsiInfoPush setLeftWork(Boolean leftWork) { + this.leftWork = leftWork; + return this; + } + + public Boolean getRightEnable() { + return rightEnable; + } + + public HsiInfoPush setRightEnable(Boolean rightEnable) { + this.rightEnable = rightEnable; + return this; + } + + public Boolean getRightWork() { + return rightWork; + } + + public HsiInfoPush setRightWork(Boolean rightWork) { + this.rightWork = rightWork; + return this; + } + + public Boolean getFrontEnable() { + return frontEnable; + } + + public HsiInfoPush setFrontEnable(Boolean frontEnable) { + this.frontEnable = frontEnable; + return this; + } + + public Boolean getFrontWork() { + return frontWork; + } + + public HsiInfoPush setFrontWork(Boolean frontWork) { + this.frontWork = frontWork; + return this; + } + + public Boolean getBackEnable() { + return backEnable; + } + + public HsiInfoPush setBackEnable(Boolean backEnable) { + this.backEnable = backEnable; + return this; + } + + public Boolean getBackWork() { + return backWork; + } + + public HsiInfoPush setBackWork(Boolean backWork) { + this.backWork = backWork; + return this; + } + + public Boolean getVerticalEnable() { + return verticalEnable; + } + + public HsiInfoPush setVerticalEnable(Boolean verticalEnable) { + this.verticalEnable = verticalEnable; + return this; + } + + public Boolean getVerticalWork() { + return verticalWork; + } + + public HsiInfoPush setVerticalWork(Boolean verticalWork) { + this.verticalWork = verticalWork; + return this; + } + + public Boolean getHorizontalEnable() { + return horizontalEnable; + } + + public HsiInfoPush setHorizontalEnable(Boolean horizontalEnable) { + this.horizontalEnable = horizontalEnable; + return this; + } + + public Boolean getHorizontalWork() { + return horizontalWork; + } + + public HsiInfoPush setHorizontalWork(Boolean horizontalWork) { + this.horizontalWork = horizontalWork; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/IrMeteringAreaSetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/IrMeteringAreaSetRequest.java new file mode 100644 index 0000000..c72467f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/IrMeteringAreaSetRequest.java @@ -0,0 +1,116 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class IrMeteringAreaSetRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + /** + * The coordinate x of the temperature measurement point is the upper left corner of the lens as the coordinate center point, and the horizontal direction is x. + */ + @NotNull + @Min(0) + @Max(1) + private Float x; + + /** + * The coordinate y of the temperature measurement point is the upper left corner of the lens as the coordinate center point, and the vertical direction is y. + */ + @NotNull + @Min(0) + @Max(1) + private Float y; + + /** + * Temperature measurement area width + */ + @NotNull + @Min(0) + @Max(1) + private Float width; + + /** + * Temperature measurement area height + */ + @NotNull + @Min(0) + @Max(1) + private Float height; + + public IrMeteringAreaSetRequest() { + } + + @Override + public String toString() { + return "IrMeteringAreaSetRequest{" + + "payloadIndex=" + payloadIndex + + ", x=" + x + + ", y=" + y + + ", width=" + width + + ", height=" + height + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public IrMeteringAreaSetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public Float getX() { + return x; + } + + public IrMeteringAreaSetRequest setX(Float x) { + this.x = x; + return this; + } + + public Float getY() { + return y; + } + + public IrMeteringAreaSetRequest setY(Float y) { + this.y = y; + return this; + } + + public Float getWidth() { + return width; + } + + public IrMeteringAreaSetRequest setWidth(Float width) { + this.width = width; + return this; + } + + public Float getHeight() { + return height; + } + + public IrMeteringAreaSetRequest setHeight(Float height) { + this.height = height; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/IrMeteringModeSetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/IrMeteringModeSetRequest.java new file mode 100644 index 0000000..c0934ab --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/IrMeteringModeSetRequest.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class IrMeteringModeSetRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private MeteringModeEnum mode; + + public IrMeteringModeSetRequest() { + } + + @Override + public String toString() { + return "IrMeteringModeSetRequest{" + + "payloadIndex=" + payloadIndex + + ", mode=" + mode + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public IrMeteringModeSetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public MeteringModeEnum getMode() { + return mode; + } + + public IrMeteringModeSetRequest setMode(MeteringModeEnum mode) { + this.mode = mode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/IrMeteringPointSetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/IrMeteringPointSetRequest.java new file mode 100644 index 0000000..b89c675 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/IrMeteringPointSetRequest.java @@ -0,0 +1,80 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class IrMeteringPointSetRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + /** + * The coordinate x of the temperature measurement point is the upper left corner of the lens as the coordinate center point, and the horizontal direction is x. + */ + @NotNull + @Min(0) + @Max(1) + private Float x; + + /** + * The coordinate y of the temperature measurement point is the upper left corner of the lens as the coordinate center point, and the vertical direction is y. + */ + @NotNull + @Min(0) + @Max(1) + private Float y; + + public IrMeteringPointSetRequest() { + } + + @Override + public String toString() { + return "IrMeteringPointSetRequest{" + + "payloadIndex=" + payloadIndex + + ", x=" + x + + ", y=" + y + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public IrMeteringPointSetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public Float getX() { + return x; + } + + public IrMeteringPointSetRequest setX(Float x) { + this.x = x; + return this; + } + + public Float getY() { + return y; + } + + public IrMeteringPointSetRequest setY(Float y) { + this.y = y; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/JoystickInvalidNotify.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/JoystickInvalidNotify.java new file mode 100644 index 0000000..46e209e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/JoystickInvalidNotify.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.control; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/14 + */ +public class JoystickInvalidNotify { + + private JoystickInvalidReasonEnum reason; + + public JoystickInvalidNotify() { + } + + @Override + public String toString() { + return "JoystickInvalidNotify{" + + "reason=" + reason + + '}'; + } + + public JoystickInvalidReasonEnum getReason() { + return reason; + } + + public JoystickInvalidNotify setReason(JoystickInvalidReasonEnum reason) { + this.reason = reason; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/JoystickInvalidReasonEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/JoystickInvalidReasonEnum.java new file mode 100644 index 0000000..419cb26 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/JoystickInvalidReasonEnum.java @@ -0,0 +1,49 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/14 + */ +public enum JoystickInvalidReasonEnum { + + RC_LOST(0, "遥控器丢失。"), + + BATTERY_LOW_GO_HOME(1, "由于电池电量不足,无人机自动返回家园。"), + + BATTERY_SUPER_LOW_LANDING(2, "由于电池电量严重不足,无人机自动降落。"), + + NEAR_BOUNDARY(3, "无人机在禁飞区附近。"), + + RC_AUTHORITY(4, "遥控器获取控制权限。"); + + private final int reason; + + private final String message; + + JoystickInvalidReasonEnum(int reason, String message) { + this.reason = reason; + this.message = message; + } + + @JsonValue + public int getVal() { + return reason; + } + + public String getMessage() { + return message; + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static JoystickInvalidReasonEnum find(int reason) { + return Arrays.stream(values()).filter(reasonEnum -> reasonEnum.reason == reason).findAny() + .orElseThrow(() -> new CloudSDKException(JoystickInvalidReasonEnum.class, reason)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/LensStorageSettingsEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/LensStorageSettingsEnum.java new file mode 100644 index 0000000..171a2db --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/LensStorageSettingsEnum.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/12 + */ +public enum LensStorageSettingsEnum { + + CURRENT("current"), + + ZOOM("zoom"), + + WIDE("wide"), + + VISION("vision"), + + INFRARED("ir"); + + private final String lens; + + LensStorageSettingsEnum(String lens) { + this.lens = lens; + } + + @JsonValue + public String getLens() { + return lens; + } + + @JsonCreator + public static LensStorageSettingsEnum find(String lens) { + return Arrays.stream(values()).filter(lensEnum -> lensEnum.lens.equals(lens)).findAny() + .orElseThrow(() -> new CloudSDKException(LensStorageSettingsEnum.class, lens)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/LiveviewDelay.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/LiveviewDelay.java new file mode 100644 index 0000000..6011fb0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/LiveviewDelay.java @@ -0,0 +1,35 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.VideoId; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class LiveviewDelay { + + private Integer liveviewDelayTime; + + private VideoId videoId; + + public LiveviewDelay() { + } + + @Override + public String toString() { + return "LiveviewDelay{" + + "liveviewDelayTime=" + liveviewDelayTime + + ", videoId=" + videoId + + '}'; + } + + public Integer getLiveviewDelayTime() { + return liveviewDelayTime; + } + + public LiveviewDelay setLiveviewDelayTime(Integer liveviewDelayTime) { + this.liveviewDelayTime = liveviewDelayTime; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/MeteringModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/MeteringModeEnum.java new file mode 100644 index 0000000..ccafecd --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/MeteringModeEnum.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public enum MeteringModeEnum { + + DISABLE(0), + + SPOT(1), + + AREA(2), + + ; + + private final int mode; + + MeteringModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static MeteringModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(MeteringModeEnum.class, mode)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/OsdInfoPush.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/OsdInfoPush.java new file mode 100644 index 0000000..989cacb --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/OsdInfoPush.java @@ -0,0 +1,138 @@ +package org.dromara.common.sdk.cloudapi.control; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class OsdInfoPush { + + private Float attitudeHead; + + private Float latitude; + + private Float longitude; + + private Float height; + + private Float speedX; + + private Float speedY; + + private Float speedZ; + + private Float gimbalPitch; + + private Float gimbalRoll; + + private Float gimbalYaw; + + public OsdInfoPush() { + } + + @Override + public String toString() { + return "OsdInfoPush{" + + "attitudeHead=" + attitudeHead + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + ", speedX=" + speedX + + ", speedY=" + speedY + + ", speedZ=" + speedZ + + ", gimbalPitch=" + gimbalPitch + + ", gimbalRoll=" + gimbalRoll + + ", gimbalYaw=" + gimbalYaw + + '}'; + } + + public Float getAttitudeHead() { + return attitudeHead; + } + + public OsdInfoPush setAttitudeHead(Float attitudeHead) { + this.attitudeHead = attitudeHead; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public OsdInfoPush setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public OsdInfoPush setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public OsdInfoPush setHeight(Float height) { + this.height = height; + return this; + } + + public Float getSpeedX() { + return speedX; + } + + public OsdInfoPush setSpeedX(Float speedX) { + this.speedX = speedX; + return this; + } + + public Float getSpeedY() { + return speedY; + } + + public OsdInfoPush setSpeedY(Float speedY) { + this.speedY = speedY; + return this; + } + + public Float getSpeedZ() { + return speedZ; + } + + public OsdInfoPush setSpeedZ(Float speedZ) { + this.speedZ = speedZ; + return this; + } + + public Float getGimbalPitch() { + return gimbalPitch; + } + + public OsdInfoPush setGimbalPitch(Float gimbalPitch) { + this.gimbalPitch = gimbalPitch; + return this; + } + + public Float getGimbalRoll() { + return gimbalRoll; + } + + public OsdInfoPush setGimbalRoll(Float gimbalRoll) { + this.gimbalRoll = gimbalRoll; + return this; + } + + public Float getGimbalYaw() { + return gimbalYaw; + } + + public OsdInfoPush setGimbalYaw(Float gimbalYaw) { + this.gimbalYaw = gimbalYaw; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PayloadAuthorityGrabRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PayloadAuthorityGrabRequest.java new file mode 100644 index 0000000..842b337 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PayloadAuthorityGrabRequest.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class PayloadAuthorityGrabRequest extends BaseModel { + + @NotNull + private PayloadIndex payloadIndex; + + public PayloadAuthorityGrabRequest() { + } + + @Override + public String toString() { + return "PayloadAuthorityGrabRequest{" + + "payloadIndex=" + payloadIndex + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public PayloadAuthorityGrabRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PayloadControlMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PayloadControlMethodEnum.java new file mode 100644 index 0000000..cd4e426 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PayloadControlMethodEnum.java @@ -0,0 +1,78 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.common.BaseModel; +import org.dromara.common.sdk.exception.CloudSDKException; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/2 + */ +public enum PayloadControlMethodEnum { + + CAMERA_MODE_SWITCH(ControlMethodEnum.CAMERA_MODE_SWITCH, CameraModeSwitchRequest.class), + + CAMERA_PHOTO_TAKE(ControlMethodEnum.CAMERA_PHOTO_TAKE, CameraPhotoTakeRequest.class), + + CAMERA_PHOTO_STOP(ControlMethodEnum.CAMERA_PHOTO_STOP, CameraPhotoStopRequest.class), + + CAMERA_RECORDING_START(ControlMethodEnum.CAMERA_RECORDING_START, CameraRecordingStartRequest.class), + + CAMERA_RECORDING_STOP(ControlMethodEnum.CAMERA_RECORDING_STOP, CameraRecordingStopRequest.class), + + CAMERA_AIM(ControlMethodEnum.CAMERA_AIM, CameraAimRequest.class), + + CAMERA_FOCAL_LENGTH_SET(ControlMethodEnum.CAMERA_FOCAL_LENGTH_SET, CameraFocalLengthSetRequest.class), + + GIMBAL_RESET(ControlMethodEnum.GIMBAL_RESET, GimbalResetRequest.class), + + CAMERA_LOOK_AT(ControlMethodEnum.CAMERA_LOOK_AT, CameraLookAtRequest.class), + + CAMERA_SCREEN_SPLIT(ControlMethodEnum.CAMERA_SCREEN_SPLIT, CameraScreenSplitRequest.class), + + PHOTO_STORAGE_SET(ControlMethodEnum.PHOTO_STORAGE_SET, PhotoStorageSetRequest.class), + + VIDEO_STORAGE_SET(ControlMethodEnum.VIDEO_STORAGE_SET, VideoStorageSetRequest.class), + + CAMERA_EXPOSURE_SET(ControlMethodEnum.CAMERA_EXPOSURE_SET, CameraExposureSetRequest.class), + + CAMERA_EXPOSURE_MODE_SET(ControlMethodEnum.CAMERA_EXPOSURE_MODE_SET, CameraExposureModeSetRequest.class), + + CAMERA_FOCUS_MODE_SET(ControlMethodEnum.CAMERA_FOCUS_MODE_SET, CameraFocusModeSetRequest.class), + + CAMERA_FOCUS_VALUE_SET(ControlMethodEnum.CAMERA_FOCUS_VALUE_SET, CameraFocusValueSetRequest.class), + + IR_METERING_MODE_SET(ControlMethodEnum.IR_METERING_MODE_SET, IrMeteringModeSetRequest.class), + + IR_METERING_POINT_SET(ControlMethodEnum.IR_METERING_POINT_SET, IrMeteringPointSetRequest.class), + + IR_METERING_AREA_SET(ControlMethodEnum.IR_METERING_AREA_SET, IrMeteringAreaSetRequest.class), + + CAMERA_POINT_FOCUS_ACTION(ControlMethodEnum.CAMERA_POINT_FOCUS_ACTION, CameraPointFocusActionRequest.class), + + ; + + private final ControlMethodEnum payloadMethod; + + private final Class clazz; + + PayloadControlMethodEnum(ControlMethodEnum payloadMethod, Class clazz) { + this.payloadMethod = payloadMethod; + this.clazz = clazz; + } + + public ControlMethodEnum getPayloadMethod() { + return payloadMethod; + } + + public Class getClazz() { + return clazz; + } + + public static PayloadControlMethodEnum find(String method) { + return Arrays.stream(values()).filter(methodEnum -> methodEnum.payloadMethod.getMethod().equals(method)).findAny() + .orElseThrow(() -> new CloudSDKException(PayloadControlMethodEnum.class, method)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoStorageSetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoStorageSetRequest.java new file mode 100644 index 0000000..52c16fa --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoStorageSetRequest.java @@ -0,0 +1,61 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/12 + */ +public class PhotoStorageSetRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + /** + * Photo storage type. Multi-selection. + */ + @NotNull + @Size(min = 1) + private List photoStorageSettings; + + public PhotoStorageSetRequest() { + } + + @Override + public String toString() { + return "PhotoStorageSetRequest{" + + "payloadIndex=" + payloadIndex + + ", photoStorageSettings=" + photoStorageSettings + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public PhotoStorageSetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public List getPhotoStorageSettings() { + return photoStorageSettings; + } + + public PhotoStorageSetRequest setPhotoStorageSettings(List photoStorageSettings) { + this.photoStorageSettings = photoStorageSettings; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoTakeProgressData.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoTakeProgressData.java new file mode 100644 index 0000000..e9e9495 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoTakeProgressData.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.control; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class PhotoTakeProgressData { + + private PhotoTakeProgressStepEnum currentStep; + + private Integer percent; + + public PhotoTakeProgressData() { + } + + @Override + public String toString() { + return "PhotoTakeProgressData{" + + "currentStep=" + currentStep + + ", percent=" + percent + + '}'; + } + + public PhotoTakeProgressStepEnum getCurrentStep() { + return currentStep; + } + + public PhotoTakeProgressData setCurrentStep(PhotoTakeProgressStepEnum currentStep) { + this.currentStep = currentStep; + return this; + } + + public Integer getPercent() { + return percent; + } + + public PhotoTakeProgressData setPercent(Integer percent) { + this.percent = percent; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoTakeProgressExt.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoTakeProgressExt.java new file mode 100644 index 0000000..29aef16 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoTakeProgressExt.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.CameraModeEnum; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class PhotoTakeProgressExt { + + private CameraModeEnum cameraMode; + + public PhotoTakeProgressExt() { + } + + @Override + public String toString() { + return "PhotoTakeProgressExt{" + + "cameraMode=" + cameraMode + + '}'; + } + + public CameraModeEnum getCameraMode() { + return cameraMode; + } + + public PhotoTakeProgressExt setCameraMode(CameraModeEnum cameraMode) { + this.cameraMode = cameraMode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoTakeProgressStepEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoTakeProgressStepEnum.java new file mode 100644 index 0000000..5309128 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PhotoTakeProgressStepEnum.java @@ -0,0 +1,43 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public enum PhotoTakeProgressStepEnum { + + NORMAL(0), + + PANORAMA_NOT_STARTED_OR_ENDED(3000), + + PANORAMA_TAKING(3002), + + PANORAMA_COMPOSITING(3005), + + ; + + private final int step; + + PhotoTakeProgressStepEnum(int step) { + this.step = step; + } + + @JsonValue + public int getStep() { + return step; + } + + @JsonCreator + public static PhotoTakeProgressStepEnum find(int step) { + return Arrays.stream(values()).filter(stepEnum -> stepEnum.step == step).findAny() + .orElseThrow(() -> new CloudSDKException(PhotoTakeProgressStepEnum.class, step)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiCircleSpeedSetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiCircleSpeedSetRequest.java new file mode 100644 index 0000000..dc07198 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiCircleSpeedSetRequest.java @@ -0,0 +1,35 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class PoiCircleSpeedSetRequest extends BaseModel { + + @NotNull + private Float circleSpeed; + + public PoiCircleSpeedSetRequest() { + } + + @Override + public String toString() { + return "PoiCircleSpeedSetRequest{" + + "circleSpeed=" + circleSpeed + + '}'; + } + + public Float getCircleSpeed() { + return circleSpeed; + } + + public PoiCircleSpeedSetRequest setCircleSpeed(Float circleSpeed) { + this.circleSpeed = circleSpeed; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiModeEnterRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiModeEnterRequest.java new file mode 100644 index 0000000..2d5cb4b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiModeEnterRequest.java @@ -0,0 +1,69 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class PoiModeEnterRequest extends BaseModel { + + @Min(-90) + @Max(90) + @NotNull + private Float latitude; + + @NotNull + @Min(-180) + @Max(180) + private Float longitude; + + @NotNull + @Min(2) + @Max(10000) + private Float height; + + public PoiModeEnterRequest() { + } + + @Override + public String toString() { + return "PoiModeEnterRequest{" + + "latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + '}'; + } + + public Float getLatitude() { + return latitude; + } + + public PoiModeEnterRequest setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public PoiModeEnterRequest setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public PoiModeEnterRequest setHeight(Float height) { + this.height = height; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiStatusNotify.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiStatusNotify.java new file mode 100644 index 0000000..a1bc841 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiStatusNotify.java @@ -0,0 +1,80 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.wayline.FlighttaskStatusEnum; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class PoiStatusNotify { + + private FlighttaskStatusEnum status; + + private PoiStatusReasonEnum reason; + + private Float circleRadius; + + private Float circleSpeed; + + private Float maxCircleSpeed; + + public PoiStatusNotify() { + } + + @Override + public String toString() { + return "PoiStatusNotify{" + + "status=" + status + + ", reason=" + reason + + ", circleRadius=" + circleRadius + + ", circleSpeed=" + circleSpeed + + ", maxCircleSpeed=" + maxCircleSpeed + + '}'; + } + + public FlighttaskStatusEnum getStatus() { + return status; + } + + public PoiStatusNotify setStatus(FlighttaskStatusEnum status) { + this.status = status; + return this; + } + + public PoiStatusReasonEnum getReason() { + return reason; + } + + public PoiStatusNotify setReason(PoiStatusReasonEnum reason) { + this.reason = reason; + return this; + } + + public Float getCircleRadius() { + return circleRadius; + } + + public PoiStatusNotify setCircleRadius(Float circleRadius) { + this.circleRadius = circleRadius; + return this; + } + + public Float getCircleSpeed() { + return circleSpeed; + } + + public PoiStatusNotify setCircleSpeed(Float circleSpeed) { + this.circleSpeed = circleSpeed; + return this; + } + + public Float getMaxCircleSpeed() { + return maxCircleSpeed; + } + + public PoiStatusNotify setMaxCircleSpeed(Float maxCircleSpeed) { + this.maxCircleSpeed = maxCircleSpeed; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiStatusReasonEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiStatusReasonEnum.java new file mode 100644 index 0000000..e248671 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/PoiStatusReasonEnum.java @@ -0,0 +1,53 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public enum PoiStatusReasonEnum { + + NORMAL(0), + + UNADAPTED_PAYLOAD(1), + + CAMERA_MODE_NOT_SUPPORTED(2), + + ILLEGAL_CMD(3), + + POSITIONING_FAILED(4), + + ON_THE_GROUND(5), + + DRONE_MODE_ERROR(6), + + NOT_AVAILABLE_MODE(7), + + RC_DISCONNECTED(8), + + ; + + private final int reason; + + PoiStatusReasonEnum(int reason) { + this.reason = reason; + } + + @JsonValue + public int getReason() { + return reason; + } + + @JsonCreator + public static PoiStatusReasonEnum find(int reason) { + return Arrays.stream(values()).filter(reasonEnum -> reasonEnum.reason == reason).findAny() + .orElseThrow(() -> new CloudSDKException(PoiStatusReasonEnum.class, reason)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/Point.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/Point.java new file mode 100644 index 0000000..1dfae05 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/Point.java @@ -0,0 +1,72 @@ +package org.dromara.common.sdk.cloudapi.control; + + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/14 + */ +public class Point { + + @Min(-90) + @Max(90) + @NotNull + private Float latitude; + + @NotNull + @Min(-180) + @Max(180) + private Float longitude; + + /** + * WGS84 + * The M30 series are ellipsoidal heights. + */ + @NotNull + @Min(2) + @Max(10000) + private Float height; + + public Point() { + } + + @Override + public String toString() { + return "Point{" + + "latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + '}'; + } + + public Float getLatitude() { + return latitude; + } + + public Point setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public Point setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public Point setHeight(Float height) { + this.height = height; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/TakeoffStatusEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/TakeoffStatusEnum.java new file mode 100644 index 0000000..7f6ac64 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/TakeoffStatusEnum.java @@ -0,0 +1,51 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/17 + */ +public enum TakeoffStatusEnum { + + TASK_READY("task_ready", "无人机正准备起飞。"), + + WAYLINE_PROGRESS("wayline_progress", "无人机正在起飞。"), + + WAYLINE_FAILED("wayline_failed", "无人机正在起飞。"), + + WAYLINE_OK("wayline_ok", "无人机成功起飞。"), + + WAYLINE_CANCEL("wayline_cancel", "无人机起飞作业已被取消。"), + + TASK_FINISH("task_finish", "无人机起飞任务完成。"); + + private final String status; + + private final String message; + + TakeoffStatusEnum(String status, String message) { + this.status = status; + this.message = message; + } + + @JsonValue + public String getStatus() { + return status; + } + + public String getMessage() { + return message; + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static TakeoffStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(TakeoffStatusEnum.class, status)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/TakeoffToPointProgress.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/TakeoffToPointProgress.java new file mode 100644 index 0000000..ea2951d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/TakeoffToPointProgress.java @@ -0,0 +1,135 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.wayline.WaylineErrorCodeEnum; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; + +import java.util.List; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/14 + */ +public class TakeoffToPointProgress { + + private WaylineErrorCodeEnum result; + + private TakeoffStatusEnum status; + + private String flightId; + + private String trackId; + + private Integer wayPointIndex; + + /** + * Remaining mission distance + * unit: m + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private Float remainingDistance; + + /** + * Remaining mission time + * unit: s + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private Integer remainingTime; + + /** + * Planned trajectory point list + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private List plannedPathPoints; + + + public TakeoffToPointProgress() { + } + + @Override + public String toString() { + return "TakeoffToPointProgress{" + + "result=" + result + + ", status=" + status + + ", flightId='" + flightId + '\'' + + ", trackId='" + trackId + '\'' + + ", wayPointIndex=" + wayPointIndex + + ", remainingDistance=" + remainingDistance + + ", remainingTime=" + remainingTime + + ", plannedPathPoints=" + plannedPathPoints + + '}'; + } + + public WaylineErrorCodeEnum getResult() { + return result; + } + + public TakeoffToPointProgress setResult(WaylineErrorCodeEnum result) { + this.result = result; + return this; + } + + public TakeoffStatusEnum getStatus() { + return status; + } + + public TakeoffToPointProgress setStatus(TakeoffStatusEnum status) { + this.status = status; + return this; + } + + public String getFlightId() { + return flightId; + } + + public TakeoffToPointProgress setFlightId(String flightId) { + this.flightId = flightId; + return this; + } + + public String getTrackId() { + return trackId; + } + + public TakeoffToPointProgress setTrackId(String trackId) { + this.trackId = trackId; + return this; + } + + public Integer getWayPointIndex() { + return wayPointIndex; + } + + public TakeoffToPointProgress setWayPointIndex(Integer wayPointIndex) { + this.wayPointIndex = wayPointIndex; + return this; + } + + public Float getRemainingDistance() { + return remainingDistance; + } + + public TakeoffToPointProgress setRemainingDistance(Float remainingDistance) { + this.remainingDistance = remainingDistance; + return this; + } + + public Integer getRemainingTime() { + return remainingTime; + } + + public TakeoffToPointProgress setRemainingTime(Integer remainingTime) { + this.remainingTime = remainingTime; + return this; + } + + public List getPlannedPathPoints() { + return plannedPathPoints; + } + + public TakeoffToPointProgress setPlannedPathPoints(List plannedPathPoints) { + this.plannedPathPoints = plannedPathPoints; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/TakeoffToPointRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/TakeoffToPointRequest.java new file mode 100644 index 0000000..ffea5e7 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/TakeoffToPointRequest.java @@ -0,0 +1,235 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum; +import org.dromara.common.sdk.cloudapi.device.RcLostActionEnum; +import org.dromara.common.sdk.cloudapi.wayline.RthModeEnum; +import org.dromara.common.sdk.cloudapi.wayline.SimulateMission; +import org.dromara.common.sdk.common.BaseModel; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public class TakeoffToPointRequest extends BaseModel { + + @Pattern(regexp = "^[^<>:\"/|?*._\\\\]+$") + @NotNull + private String flightId; + + @Min(-180) + @Max(180) + @NotNull + private Float targetLongitude; + + @Min(-90) + @Max(90) + @NotNull + private Float targetLatitude; + + @Min(2) + @Max(10000) + @NotNull + private Float targetHeight; + + @Min(20) + @Max(1500) + @NotNull + private Float securityTakeoffHeight; + + @Min(2) + @Max(1500) + @NotNull + private Float rthAltitude; + + @NotNull + private RcLostActionEnum rcLostAction; + + @NotNull + @CloudSDKVersion(deprecated = CloudSDKVersionEnum.V1_0_0) + private ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost; + + @Min(1) + @Max(15) + @NotNull + private Integer maxSpeed; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @NotNull + private RthModeEnum rthMode; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @NotNull + private CommanderModeLostActionEnum commanderModeLostAction; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @NotNull + private CommanderFlightModeEnum commanderFlightMode; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @NotNull + @Min(2) + @Max(3000) + private Float commanderFlightHeight; + + @Valid + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private SimulateMission simulateMission; + + public TakeoffToPointRequest() { + } + + @Override + public String toString() { + return "TakeoffToPointRequest{" + + "flightId='" + flightId + '\'' + + ", targetLongitude=" + targetLongitude + + ", targetLatitude=" + targetLatitude + + ", targetHeight=" + targetHeight + + ", securityTakeoffHeight=" + securityTakeoffHeight + + ", rthAltitude=" + rthAltitude + + ", rcLostAction=" + rcLostAction + + ", exitWaylineWhenRcLost=" + exitWaylineWhenRcLost + + ", maxSpeed=" + maxSpeed + + ", rthMode=" + rthMode + + ", commanderModeLostAction=" + commanderModeLostAction + + ", commanderFlightMode=" + commanderFlightMode + + ", commanderFlightHeight=" + commanderFlightHeight + + ", simulateMission=" + simulateMission + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public TakeoffToPointRequest setFlightId(String flightId) { + this.flightId = flightId; + return this; + } + + public Float getTargetLongitude() { + return targetLongitude; + } + + public TakeoffToPointRequest setTargetLongitude(Float targetLongitude) { + this.targetLongitude = targetLongitude; + return this; + } + + public Float getTargetLatitude() { + return targetLatitude; + } + + public TakeoffToPointRequest setTargetLatitude(Float targetLatitude) { + this.targetLatitude = targetLatitude; + return this; + } + + public Float getTargetHeight() { + return targetHeight; + } + + public TakeoffToPointRequest setTargetHeight(Float targetHeight) { + this.targetHeight = targetHeight; + return this; + } + + public Float getSecurityTakeoffHeight() { + return securityTakeoffHeight; + } + + public TakeoffToPointRequest setSecurityTakeoffHeight(Float securityTakeoffHeight) { + this.securityTakeoffHeight = securityTakeoffHeight; + return this; + } + + public Float getRthAltitude() { + return rthAltitude; + } + + public TakeoffToPointRequest setRthAltitude(Float rthAltitude) { + this.rthAltitude = rthAltitude; + return this; + } + + public RcLostActionEnum getRcLostAction() { + return rcLostAction; + } + + public TakeoffToPointRequest setRcLostAction(RcLostActionEnum rcLostAction) { + this.rcLostAction = rcLostAction; + return this; + } + + public ExitWaylineWhenRcLostEnum getExitWaylineWhenRcLost() { + return exitWaylineWhenRcLost; + } + + public TakeoffToPointRequest setExitWaylineWhenRcLost(ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost) { + this.exitWaylineWhenRcLost = exitWaylineWhenRcLost; + return this; + } + + public Integer getMaxSpeed() { + return maxSpeed; + } + + public RthModeEnum getRthMode() { + return rthMode; + } + + public TakeoffToPointRequest setRthMode(RthModeEnum rthMode) { + this.rthMode = rthMode; + return this; + } + + public CommanderModeLostActionEnum getCommanderModeLostAction() { + return commanderModeLostAction; + } + + public TakeoffToPointRequest setCommanderModeLostAction(CommanderModeLostActionEnum commanderModeLostAction) { + this.commanderModeLostAction = commanderModeLostAction; + return this; + } + + public CommanderFlightModeEnum getCommanderFlightMode() { + return commanderFlightMode; + } + + public TakeoffToPointRequest setCommanderFlightMode(CommanderFlightModeEnum commanderFlightMode) { + this.commanderFlightMode = commanderFlightMode; + return this; + } + + public Float getCommanderFlightHeight() { + return commanderFlightHeight; + } + + public TakeoffToPointRequest setCommanderFlightHeight(Float commanderFlightHeight) { + this.commanderFlightHeight = commanderFlightHeight; + return this; + } + + public TakeoffToPointRequest setMaxSpeed(Integer maxSpeed) { + this.maxSpeed = maxSpeed; + return this; + } + + public SimulateMission getSimulateMission() { + return simulateMission; + } + + public TakeoffToPointRequest setSimulateMission(SimulateMission simulateMission) { + this.simulateMission = simulateMission; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/VideoStorageSetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/VideoStorageSetRequest.java new file mode 100644 index 0000000..08c0054 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/VideoStorageSetRequest.java @@ -0,0 +1,61 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/12 + */ +public class VideoStorageSetRequest extends BaseModel { + + /** + * Camera enumeration. + * It is unofficial device_mode_key. + * The format is *{type-subtype-gimbalindex}*. + * Please read [Product Supported](https://developer.dji.com/doc/cloud-api-tutorial/en/overview/product-support.html) + */ + @NotNull + private PayloadIndex payloadIndex; + + /** + * Video storage type. Multi-selection. + */ + @NotNull + @Size(min = 1) + private List videoStorageSettings; + + public VideoStorageSetRequest() { + } + + @Override + public String toString() { + return "VideoStorageSetRequest{" + + "payloadIndex=" + payloadIndex + + ", videoStorageSettings=" + videoStorageSettings + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public VideoStorageSetRequest setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public List getVideoStorageSettings() { + return videoStorageSettings; + } + + public VideoStorageSetRequest setVideoStorageSettings(List videoStorageSettings) { + this.videoStorageSettings = videoStorageSettings; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ZoomCameraTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ZoomCameraTypeEnum.java new file mode 100644 index 0000000..9970ac3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/ZoomCameraTypeEnum.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.control; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public enum ZoomCameraTypeEnum { + + ZOOM("zoom"), + + IR("ir"); + + private final String type; + + ZoomCameraTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static ZoomCameraTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(ZoomCameraTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/api/AbstractControlService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/api/AbstractControlService.java new file mode 100644 index 0000000..b6cbce4 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/control/api/AbstractControlService.java @@ -0,0 +1,665 @@ +package org.dromara.common.sdk.cloudapi.control.api; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.control.*; +import org.dromara.common.sdk.common.BaseModel; +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.common.SpringBeanUtils; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.drc.DrcDownPublish; +import org.dromara.common.sdk.mqtt.drc.DrcUpData; +import org.dromara.common.sdk.mqtt.drc.TopicDrcRequest; +import org.dromara.common.sdk.mqtt.events.EventsDataRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsResponse; +import org.dromara.common.sdk.mqtt.services.ServicesPublish; +import org.dromara.common.sdk.mqtt.services.ServicesReplyData; +import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; +import jakarta.annotation.Resource; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public abstract class AbstractControlService { + + @Resource + private ServicesPublish servicesPublish; + + @Resource + private DrcDownPublish drcDownPublish; + + /** + * Event notification of flyto result + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLY_TO_POINT_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse flyToPointProgress(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("flyToPointProgress not implemented"); + } + + /** + * Event notification of one-key taking off result + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_TAKEOFF_TO_POINT_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse takeoffToPointProgress(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("takeoffToPointProgress not implemented"); + } + + /** + * Notification of DRC link state + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_DRC_STATUS_NOTIFY, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse drcStatusNotify(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("drcStatusNotify not implemented"); + } + + /** + * Reason notification of invalid Joystick control + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_JOYSTICK_INVALID_NOTIFY, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse joystickInvalidNotify(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("joystickInvalidNotify not implemented"); + } + + /** + * Flight control authority grabbing + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flightAuthorityGrab(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.FLIGHT_AUTHORITY_GRAB.getMethod()); + } + + /** + * Payload control authority grabbing + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse payloadAuthorityGrab(GatewayManager gateway, PayloadAuthorityGrabRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.PAYLOAD_AUTHORITY_GRAB.getMethod(), + request); + } + + /** + * Enter the live flight controls mode + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse drcModeEnter(GatewayManager gateway, DrcModeEnterRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.DRC_MODE_ENTER.getMethod(), + request); + } + + /** + * Exit the live flight controls mode + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse drcModeExit(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.DRC_MODE_EXIT.getMethod()); + } + + /** + * One-key taking off + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse takeoffToPoint(GatewayManager gateway, TakeoffToPointRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.TAKEOFF_TO_POINT.getMethod(), + request); + } + + /** + * flyto target point + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flyToPoint(GatewayManager gateway, FlyToPointRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.FLY_TO_POINT.getMethod(), + request); + } + + /** + * Quickly update target points + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, exclude = GatewayTypeEnum.RC, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse flyToPointUpdate(GatewayManager gateway, FlyToPointUpdateRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.FLY_TO_POINT_UPDATE.getMethod(), + request); + } + + /** + * End the task of flying to target point + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flyToPointStop(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.FLY_TO_POINT_STOP.getMethod()); + } + + /** + * Payload control - switch the camera mode + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraModeSwitch(GatewayManager gateway, CameraModeSwitchRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_MODE_SWITCH.getMethod(), + request); + } + + /** + * Payload control - take single photo + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraPhotoTake(GatewayManager gateway, CameraPhotoTakeRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_PHOTO_TAKE.getMethod(), + request); + } + + /** + * Payload control - stop taking photo + * Currently only panoramic photo mode is supported. + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, exclude = GatewayTypeEnum.RC, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse cameraPhotoStop(GatewayManager gateway, CameraPhotoStopRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_PHOTO_STOP.getMethod(), + request); + } + + /** + * Event notification of camera photo progress information + * Currently only panoramic photo mode is supported. + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_CAMERA_PHOTO_TAKE_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse cameraPhotoTakeProgress(TopicEventsRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("cameraPhotoTakeProgress not implemented"); + } + + /** + * Payload control - start recording + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraRecordingStart(GatewayManager gateway, CameraRecordingStartRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_RECORDING_START.getMethod(), + request); + } + + /** + * Payload control - stop recording + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraRecordingStop(GatewayManager gateway, CameraRecordingStopRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_RECORDING_STOP.getMethod(), + request); + } + + /** + * Payload control - double tab to become AIM + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraAim(GatewayManager gateway, CameraAimRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_AIM.getMethod(), + request); + } + + /** + * Payload control - zoom + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraFocalLengthSet(GatewayManager gateway, CameraFocalLengthSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_FOCAL_LENGTH_SET.getMethod(), + request); + } + + /** + * Payload control - reset the gimbal + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse gimbalReset(GatewayManager gateway, GimbalResetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.GIMBAL_RESET.getMethod(), + request); + } + + /** + * The `lookat` function refers to the aircraft turning itself from its current heading to point at a specified location of actual latitude, longitude, and altitude. + * For M30/M30T models, it is recommended to use a method that locks the gimbal when using the `lookat` function. + * When the gimbal reaches its limits, the `lookat` function may behave abnormally. + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0, exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraLookAt(GatewayManager gateway, CameraLookAtRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_LOOK_AT.getMethod(), + request); + } + + /** + * Payload control - screen split + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0, exclude = GatewayTypeEnum.RC) + public TopicServicesResponse cameraScreenSplit(GatewayManager gateway, CameraScreenSplitRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_SCREEN_SPLIT.getMethod(), + request); + } + + /** + * Payload control - photo storage setting + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0, exclude = GatewayTypeEnum.RC) + public TopicServicesResponse photoStorageSet(GatewayManager gateway, PhotoStorageSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.PHOTO_STORAGE_SET.getMethod(), + request); + } + + /** + * Payload control - video storage setting + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0, exclude = GatewayTypeEnum.RC) + public TopicServicesResponse videoStorageSet(GatewayManager gateway, VideoStorageSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.VIDEO_STORAGE_SET.getMethod(), + request); + } + + /** + * Payload control - camera exposure setting + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse cameraExposureSet(GatewayManager gateway, CameraExposureSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_EXPOSURE_SET.getMethod(), + request); + } + + /** + * Payload control - camera exposure mode setting + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse cameraExposureModeSet(GatewayManager gateway, CameraExposureModeSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_EXPOSURE_MODE_SET.getMethod(), + request); + } + + /** + * Payload control - camera focus mode setting + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse cameraFocusModeSet(GatewayManager gateway, CameraFocusModeSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_FOCUS_MODE_SET.getMethod(), + request); + } + + /** + * Payload control - camera focus value setting + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse cameraFocusValueSet(GatewayManager gateway, CameraFocusValueSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_FOCUS_VALUE_SET.getMethod(), + request); + } + + /** + * Payload control - ir metering mode setting + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse irMeteringModeSet(GatewayManager gateway, IrMeteringModeSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.IR_METERING_MODE_SET.getMethod(), + request); + } + + /** + * Payload control - ir metering point setting + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse irMeteringPointSet(GatewayManager gateway, IrMeteringPointSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.IR_METERING_POINT_SET.getMethod(), + request); + } + + /** + * Payload control - ir metering area setting + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse irMeteringAreaSet(GatewayManager gateway, IrMeteringAreaSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.IR_METERING_AREA_SET.getMethod(), + request); + } + + /** + * Payload control - camera point focus + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse cameraPointFocusAction(GatewayManager gateway, CameraPointFocusActionRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.CAMERA_POINT_FOCUS_ACTION.getMethod(), + request); + } + + /** + * Payload control + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse payloadControl(GatewayManager gateway, PayloadControlMethodEnum methodEnum, BaseModel request) { + try { + AbstractControlService abstractControlService = SpringBeanUtils.getBean(this.getClass()); + Method method = abstractControlService.getClass().getDeclaredMethod( + Common.convertSnake(methodEnum.getPayloadMethod().getMethod()),GatewayManager.class, methodEnum.getClazz()); + return (TopicServicesResponse) method.invoke(abstractControlService, gateway, request); + } catch (NoSuchMethodException | IllegalAccessException e) { + throw new CloudSDKException(e); + } catch (InvocationTargetException e) { + throw new CloudSDKException(e.getTargetException()); + } + } + + /** + * Event notification of poi surround information + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_POI_STATUS_NOTIFY, outputChannel = ChannelName.OUTBOUND_EVENTS) + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, include = GatewayTypeEnum.DOCK) + public TopicEventsResponse poiStatusNotify(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("poiStatusNotify not implemented"); + } + + /** + * Enter the poi surround mode + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, exclude = GatewayTypeEnum.RC, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse poiModeEnter(GatewayManager gateway, PoiModeEnterRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.POI_MODE_ENTER.getMethod(), + request); + } + + /** + * Exit the poi surround mode + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, exclude = GatewayTypeEnum.RC, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse poiModeExit(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.POI_MODE_EXIT.getMethod()); + } + + /** + * poi speed setting + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, exclude = GatewayTypeEnum.RC, include = GatewayTypeEnum.DOCK) + public TopicServicesResponse poiCircleSpeedSet(GatewayManager gateway, PoiCircleSpeedSetRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.POI_CIRCLE_SPEED_SET.getMethod(), + request); + } + + /** + * DRC-flight control + * @param gateway + * @param request data + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + protected void droneControlDown(GatewayManager gateway, DroneControlRequest request) { + drcDownPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.DRONE_CONTROL.getMethod(), + request); + } + + /** + * Drc up notification of drone control result + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_DRONE_CONTROL) + public void droneControlUp(TopicDrcRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("droneControlUp not implemented"); + } + + /** + * DRC-drone emergency stop + * @param gateway + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public void droneEmergencyStopDown(GatewayManager gateway) { + drcDownPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.DRONE_EMERGENCY_STOP.getMethod()); + } + + /** + * Drc up notification of drone emergency stop result + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_DRONE_EMERGENCY_STOP) + public void droneEmergencyStopUp(TopicDrcRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("droneEmergencyStopUp not implemented"); + } + + + /** + * DRC-heart beat + * @param gateway + * @param request data + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public void heartBeatDown(GatewayManager gateway, HeartBeatRequest request) { + drcDownPublish.publish( + gateway.getGatewaySn(), + ControlMethodEnum.HEART_BEAT.getMethod(), + request); + } + + /** + * Drc up notification of heart beat result + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_HEART_BEAT) + public void heartBeatUp(TopicDrcRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("heartBeatUp not implemented"); + } + + /** + * DRC-obstacle avoidance information pushing + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_HSI_INFO_PUSH) + public void hsiInfoPush(TopicDrcRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("hsiInfoPush not implemented"); + } + + /** + * DRC-delay information pushing of image transmission link + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_DELAY_INFO_PUSH) + public void delayInfoPush(TopicDrcRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("delayInfoPush not implemented"); + } + + /** + * DRC-high frequency osd information pushing + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_DRC_UP_OSD_INFO_PUSH) + public void osdInfoPush(TopicDrcRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("osdInfoPush not implemented"); + } + + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/AirConditionerModeSwitchActionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/AirConditionerModeSwitchActionEnum.java new file mode 100644 index 0000000..4a3a837 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/AirConditionerModeSwitchActionEnum.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/28 + */ +public enum AirConditionerModeSwitchActionEnum { + + IDLE_MODE(0), + + COOLING_MODE(1), + + heating_mode(2), + + DEHUMIDIFICATION_MODE(3); + + private final int action; + + AirConditionerModeSwitchActionEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static AirConditionerModeSwitchActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(AirConditionerModeSwitchActionEnum.class, action)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/AirConditionerModeSwitchRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/AirConditionerModeSwitchRequest.java new file mode 100644 index 0000000..f0f215a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/AirConditionerModeSwitchRequest.java @@ -0,0 +1,35 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class AirConditionerModeSwitchRequest extends BaseModel { + + @NotNull + private AirConditionerModeSwitchActionEnum action; + + public AirConditionerModeSwitchRequest() { + } + + @Override + public String toString() { + return "AirConditionerModeSwitchRequest{" + + "action=" + action + + '}'; + } + + public AirConditionerModeSwitchActionEnum getAction() { + return action; + } + + public AirConditionerModeSwitchRequest setAction(AirConditionerModeSwitchActionEnum action) { + this.action = action; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/AlarmStateSwitchRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/AlarmStateSwitchRequest.java new file mode 100644 index 0000000..efca0bf --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/AlarmStateSwitchRequest.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.cloudapi.device.SwitchActionEnum; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class AlarmStateSwitchRequest extends BaseModel { + + @NotNull + private SwitchActionEnum action; + + public AlarmStateSwitchRequest() { + } + + @Override + public String toString() { + return "AlarmStateSwitchRequest{" + + "action=" + action + + '}'; + } + + public SwitchActionEnum getAction() { + return action; + } + + public AlarmStateSwitchRequest setAction(SwitchActionEnum action) { + this.action = action; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/BatteryMaintenanceSwitchRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/BatteryMaintenanceSwitchRequest.java new file mode 100644 index 0000000..e40ea49 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/BatteryMaintenanceSwitchRequest.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.cloudapi.device.SwitchActionEnum; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class BatteryMaintenanceSwitchRequest extends BaseModel { + + @NotNull + private SwitchActionEnum action; + + public BatteryMaintenanceSwitchRequest() { + } + + @Override + public String toString() { + return "BatteryMaintenanceSwitchRequest{" + + "action=" + action + + '}'; + } + + public SwitchActionEnum getAction() { + return action; + } + + public BatteryMaintenanceSwitchRequest setAction(SwitchActionEnum action) { + this.action = action; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/BatteryStoreModeSwitchRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/BatteryStoreModeSwitchRequest.java new file mode 100644 index 0000000..f161eed --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/BatteryStoreModeSwitchRequest.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.cloudapi.device.BatteryStoreModeEnum; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class BatteryStoreModeSwitchRequest extends BaseModel { + + @NotNull + private BatteryStoreModeEnum action; + + public BatteryStoreModeSwitchRequest() { + } + + @Override + public String toString() { + return "BatteryStoreModeSwitchRequest{" + + "action=" + action + + '}'; + } + + public BatteryStoreModeEnum getAction() { + return action; + } + + public BatteryStoreModeSwitchRequest setAction(BatteryStoreModeEnum action) { + this.action = action; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/DebugErrorCodeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/DebugErrorCodeEnum.java new file mode 100644 index 0000000..98255ed --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/DebugErrorCodeEnum.java @@ -0,0 +1,168 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.common.IErrorInfo; +import org.dromara.common.sdk.mqtt.events.IEventsErrorCode; +import org.dromara.common.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum DebugErrorCodeEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + AIRCRAFT_NO_DONGLE(326002, "DJI蜂窝模块未安装在飞机上"), + + AIRCRAFT_DONGLE_NO_SIM(326003, "飞机的DJI蜂窝模块中没有安装SIM卡。"), + + AIRCRAFT_DONGLE_NEED_UPGRADE(326004, "飞机的DJI蜂窝模块需要升级,否则无法使用。"), + + ESTABLISH_CONNECTION_FAILED(326005, "飞机的4G传输无法启用,4G传输无法建立连接。请检查4G信号强度,或咨询运营商检查套餐流量和APN设置。"), + + SDR_SWITCH_FAILED(326006, "4G传输开关出现故障,请稍后再试。"), + + WRONG_COMMAND_FORMAT(326007, "命令格式错误。"), + + DOCK_NO_DONGLE(326008, "DJI蜂窝模块未安装在底座上。"), + + DOCK_DONGLE_NO_SIM(326009, "底座的DJI蜂窝模块中没有安装SIM卡。"), + + DOCK_DONGLE_NEED_UPGRADE(326010, "码头的DJI蜂窝模块需要升级,否则无法使用。"), + + COMMAND_NOT_SUPPORTED(514100, "码头错误。重新启动码头,然后重试。"), + + PUSH_DRIVING_RODS_FAILED(514101, "未能将传动杆推入到位。"), + + PULL_DRIVING_RODS_FAILED(514102, "未能将驱动杆拉回。"), + + LOW_POWER_1(514103, "飞机电池电量低。无法执行任务。等待飞机充电至50%,然后重试。"), + + CHARGE_FAILED(514104, "电池充电失败。"), + + STOP_CHARGING_FAILED(514105, "无法停止对电池充电"), + + REBOOT_DRONE_FAILED(514106, "无法重新启动无人机。"), + + OPEN_DOCK_COVER_FAILED(514107, "无法打开坞盖。"), + + CLOSE_DOCK_COVER_FAILED(514108, "无法关闭坞盖。"), + + POWER_ON_AIRCRAFT_FAILED(514109, "未能接通飞机电源。"), + + POWER_OFF_AIRCRAFT_FAILED(514110, "未能关闭飞机电源。"), + + OPEN_SLOW_MOTION_FAILED(514111, "打开慢动作模式时螺旋桨错误"), + + CLOSE_SLOW_MOTION_FAILED(514112, "关闭慢动作模式时螺旋桨错误"), + + AIRCRAFT_NOT_FOUND_1(514113, "驱动杆和飞机之间的连接错误。检查飞机是否在坞内,驱动杆是否卡住,充电连接器是否脏污或损坏。"), + + OBTAIN_BATTERY_FAILED(514114, "无法获取飞机电池状态。重新启动dock,然后重试。"), + + DOCK_BUSY(514116, "无法执行操作。Dock正在执行其他命令。请稍后再试。"), + + OBTAIN_DOCK_COVER_FAILED(514117, "坞盖打开或未完全关闭。重新启动dock并重试"), + + OBTAIN_DRIVING_RODS_FAILED(514118, "驱动杆向后拉或未推入到位。重新启动dock,然后重试。"), + + TRANSMISSION_ERROR(514120, "码头和飞机断开连接。重新启动码头并重试,或者重新连接码头和飞机。"), + + EMERGENCY_BUTTON_PRESSED_DOWN(514121, "紧急停止按钮按下。松开按钮。"), + + OBTAIN_CHARGING_STATUS_FAILED(514122, "无法获取飞机充电状态。重新启动dock,然后重试。"), + + LOW_POWER_2(514123, "飞机电池电量过低。无法接通飞机电源。"), + + OBTAIN_BATTERY_STATUS_FAILED(514124, "无法获取飞机电池信息。"), + + BATTERY_FULL(514125, "飞机电池电量几乎已满。无法开始充电。当电池电量低于95%时给电池充电。"), + + HEAVY_RAINFALL(514134, "强降雨。无法执行任务。请稍后再试。"), + + HIGH_WIND(514135, "风速过高(≥12 m/s)。无法执行任务。请稍后再试。"), + + POWER_SUPPLY_ERROR(514136, "对接电源错误。无法执行任务。请恢复供电,然后重试。"), + + LOW_ENVIRONMENT_TEMPERATURE(514137, "环境温度过低(低于-20°C)。无法执行任务。请稍后再试。"), + + BATTERY_MAINTAINING(514138, "维护飞机电池。无法执行任务。等待维护完成。"), + + MAINTAIN_BATTERY_FAILED(514139, "未能维护飞机电池。无需维护。"), + + SETTING_BATTERY_STORAGE_FAILED(514140, "无法设置电池存储模式。"), + + DOCK_SYSTEM_ERROR(514141, "Dock系统错误。重新启动dock,然后重试。"), + + AIRCRAFT_NOT_FOUND_2(514142, "起飞前驱动杆与飞机的连接错误。检查飞机是否在坞内,驱动杆是否卡住,充电连接器是否脏污或损坏。"), + + DRIVING_RODS_ERROR(514143, "驱动杆向后拉或未推入到位。请稍后再试,或者重新启动dock然后再试。"), + + DOCK_COVER_ERROR(514144, "坞盖打开或未完全关闭。"), + + ONSITE_DEBUGGING_MODE(514145, "以现场调试模式对接。无法执行当前操作或任务。"), + + REMOTE_DEBUGGING_MODE(514146, "在远程调试模式下停靠。无法执行任务。"), + + FIRMWARE_UPDATING(514147, "正在更新设备固件。无法执行任务。"), + + WORKING(514148, "任务正在进行中。Dock无法进入远程调试模式或再次执行任务。"), + + WRONG_STATUS(514149, "机场未处于运行模式,但已发出与运行模式相关的命令。"), + + RESTARTING(514150, "正在重新启动设备。"), + + UPDATING(514151, "正在更新设备固件。"), + + NOT_REMOTE_DEBUGGING_MODE(514153, "Dock已退出远程调试模式。无法执行当前操作。"), + + INITIALIZING(514170, "正在初始化dock。无法执行操作。等待初始化完成。"), + + WRONG_PARAMETER(514171, "Cloud命令参数错误。Dock无法执行命令。"), + + DISABLE_AC_FAILED(514180, "无法禁用空调冷却或加热。"), + + ENABLE_AC_COOLING_FAILED(514181, "无法启用空调冷却。"), + + ENABLE_AC_HEATING_FAILED(514182, "无法启用交流加热。"), + + ENABLE_AC_DEHUMIDIFYING_FAILED(514183, "无法启用空调除湿。"), + + LOW_TEMPERATURE(514184, "环境温度低于0°C。无法启用交流冷却。"), + + HIGH_TEMPERATURE(514185, "环境温度高于45°C。无法启用交流加热"), + + UNKNOWN(-1, "UNKNOWN"), + + ; + + + private final String msg; + + private final int code; + + DebugErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + /** + * @param code error code + * @return enumeration object + */ + public static DebugErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/DebugMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/DebugMethodEnum.java new file mode 100644 index 0000000..cd13728 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/DebugMethodEnum.java @@ -0,0 +1,84 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.common.BaseModel; +import org.dromara.common.sdk.exception.CloudSDKException; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum DebugMethodEnum { + + DEBUG_MODE_OPEN("debug_mode_open", null), + + DEBUG_MODE_CLOSE("debug_mode_close", null), + + SUPPLEMENT_LIGHT_OPEN("supplement_light_open", null), + + SUPPLEMENT_LIGHT_CLOSE("supplement_light_close", null), + + DEVICE_REBOOT("device_reboot", null), + + DRONE_OPEN("drone_open", null), + + DRONE_CLOSE("drone_close", null), + + DRONE_FORMAT("drone_format", null), + + DEVICE_FORMAT("device_format", null), + + COVER_OPEN("cover_open", null), + + COVER_CLOSE("cover_close", null), + + PUTTER_OPEN("putter_open", null), + + PUTTER_CLOSE("putter_close", null), + + CHARGE_OPEN("charge_open", null), + + CHARGE_CLOSE("charge_close", null), + + BATTERY_MAINTENANCE_SWITCH("battery_maintenance_switch", BatteryMaintenanceSwitchRequest.class), + + ALARM_STATE_SWITCH("alarm_state_switch", AlarmStateSwitchRequest.class), + + BATTERY_STORE_MODE_SWITCH("battery_store_mode_switch", BatteryStoreModeSwitchRequest.class), + + SDR_WORKMODE_SWITCH("sdr_workmode_switch", SdrWorkmodeSwitchRequest.class), + + AIR_CONDITIONER_MODE_SWITCH("air_conditioner_mode_switch", AirConditionerModeSwitchRequest.class), + + ESIM_ACTIVATE("esim_activate", EsimActivateRequest.class), + + SIM_SLOT_SWITCH("sim_slot_switch", SimSlotSwitchRequest.class), + + ESIM_OPERATOR_SWITCH("esim_operator_switch", EsimOperatorSwitchRequest.class), + + ; + + private final String method; + + private final Class clazz; + + DebugMethodEnum(String method, Class clazz) { + this.method = method; + this.clazz = clazz; + } + + public String getMethod() { + return method; + } + + public Class getClazz() { + return clazz; + } + + public static DebugMethodEnum find(String method) { + return Arrays.stream(values()).filter(methodEnum -> methodEnum.method.equals(method)).findAny() + .orElseThrow(() -> new CloudSDKException(DebugMethodEnum.class, method)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/DongleDeviceTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/DongleDeviceTypeEnum.java new file mode 100644 index 0000000..2901162 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/DongleDeviceTypeEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public enum DongleDeviceTypeEnum { + + DOCK("dock"), + + DRONE("drone"), + + ; + + private final String type; + + DongleDeviceTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static DongleDeviceTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(DongleDeviceTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/EsimActivateRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/EsimActivateRequest.java new file mode 100644 index 0000000..23fdb91 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/EsimActivateRequest.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class EsimActivateRequest extends BaseModel { + + /** + * Identifies the dongle to be operated on. + */ + @NotNull + private String imei; + + /** + * Identifies the target device to operate on. + */ + @NotNull + private DongleDeviceTypeEnum deviceType; + + public EsimActivateRequest() { + } + + @Override + public String toString() { + return "EsimActivateRequest{" + + "imei='" + imei + '\'' + + ", deviceType=" + deviceType + + '}'; + } + + public String getImei() { + return imei; + } + + public EsimActivateRequest setImei(String imei) { + this.imei = imei; + return this; + } + + public DongleDeviceTypeEnum getDeviceType() { + return deviceType; + } + + public EsimActivateRequest setDeviceType(DongleDeviceTypeEnum deviceType) { + this.deviceType = deviceType; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/EsimOperatorSwitchRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/EsimOperatorSwitchRequest.java new file mode 100644 index 0000000..aaa1cf3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/EsimOperatorSwitchRequest.java @@ -0,0 +1,71 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.cloudapi.device.TelecomOperatorEnum; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class EsimOperatorSwitchRequest extends BaseModel { + + /** + * Identifies the dongle to be operated on. + */ + @NotNull + private String imei; + + /** + * Identifies the target device to operate on. + */ + @NotNull + private DongleDeviceTypeEnum deviceType; + + /** + * Target carrier for switching. + */ + @NotNull + private TelecomOperatorEnum telecomOperator; + + public EsimOperatorSwitchRequest() { + } + + @Override + public String toString() { + return "EsimOperatorSwitchRequest{" + + "imei='" + imei + '\'' + + ", deviceType=" + deviceType + + ", telecomOperator=" + telecomOperator + + '}'; + } + + public String getImei() { + return imei; + } + + public EsimOperatorSwitchRequest setImei(String imei) { + this.imei = imei; + return this; + } + + public DongleDeviceTypeEnum getDeviceType() { + return deviceType; + } + + public EsimOperatorSwitchRequest setDeviceType(DongleDeviceTypeEnum deviceType) { + this.deviceType = deviceType; + return this; + } + + public TelecomOperatorEnum getTelecomOperator() { + return telecomOperator; + } + + public EsimOperatorSwitchRequest setTelecomOperator(TelecomOperatorEnum telecomOperator) { + this.telecomOperator = telecomOperator; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugProgress.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugProgress.java new file mode 100644 index 0000000..f0cd0af --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugProgress.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.debug; + +/** + * @author sean + * @version 1.2 + * @date 2022/7/29 + */ +public class RemoteDebugProgress { + + private RemoteDebugStatusEnum status; + + private RemoteDebugProgressData progress; + + public RemoteDebugProgress() { + } + + @Override + public String toString() { + return "RemoteDebugProgress{" + + "status=" + status + + ", progress=" + progress + + '}'; + } + + public RemoteDebugStatusEnum getStatus() { + return status; + } + + public RemoteDebugProgress setStatus(RemoteDebugStatusEnum status) { + this.status = status; + return this; + } + + public RemoteDebugProgressData getProgress() { + return progress; + } + + public RemoteDebugProgress setProgress(RemoteDebugProgressData progress) { + this.progress = progress; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugProgressData.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugProgressData.java new file mode 100644 index 0000000..7b2c4c0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugProgressData.java @@ -0,0 +1,78 @@ +package org.dromara.common.sdk.cloudapi.debug; + +/** + * @author sean + * @version 1.2 + * @date 2022/7/29 + */ +public class RemoteDebugProgressData { + + private Integer percent; + + private Integer currentStep; + + private Integer totalSteps; + + private RemoteDebugStepKeyEnum stepKey; + + private Integer stepResult; + + public RemoteDebugProgressData() { + } + + @Override + public String toString() { + return "RemoteDebugProgressData{" + + "percent=" + percent + + ", currentStep=" + currentStep + + ", totalSteps=" + totalSteps + + ", stepKey='" + stepKey + '\'' + + ", stepResult=" + stepResult + + '}'; + } + + public Integer getPercent() { + return percent; + } + + public RemoteDebugProgressData setPercent(Integer percent) { + this.percent = percent; + return this; + } + + public Integer getCurrentStep() { + return currentStep; + } + + public RemoteDebugProgressData setCurrentStep(Integer currentStep) { + this.currentStep = currentStep; + return this; + } + + public Integer getTotalSteps() { + return totalSteps; + } + + public RemoteDebugProgressData setTotalSteps(Integer totalSteps) { + this.totalSteps = totalSteps; + return this; + } + + public RemoteDebugStepKeyEnum getStepKey() { + return stepKey; + } + + public RemoteDebugProgressData setStepKey(RemoteDebugStepKeyEnum stepKey) { + this.stepKey = stepKey; + return this; + } + + public Integer getStepResult() { + return stepResult; + } + + public RemoteDebugProgressData setStepResult(Integer stepResult) { + this.stepResult = stepResult; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugResponse.java new file mode 100644 index 0000000..c5d1dd9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugResponse.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.debug; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class RemoteDebugResponse { + + private RemoteDebugStatusEnum status; + + public RemoteDebugResponse() { + } + + @Override + public String toString() { + return "RemoteDebugResponse{" + + "status=" + status + + '}'; + } + + public RemoteDebugStatusEnum getStatus() { + return status; + } + + public RemoteDebugResponse setStatus(RemoteDebugStatusEnum status) { + this.status = status; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugStatusEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugStatusEnum.java new file mode 100644 index 0000000..0121802 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugStatusEnum.java @@ -0,0 +1,57 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/17 + */ +public enum RemoteDebugStatusEnum { + + SENT("sent", false), + + IN_PROGRESS("in_progress", false), + + OK("ok", true), + + PAUSED("paused", false), + + REJECTED("rejected", true), + + FAILED("failed", true), + + CANCELED("canceled", true), + + TIMEOUT("timeout", true); + + private final String status; + + private final boolean end; + + RemoteDebugStatusEnum(String status, boolean end) { + this.status = status; + this.end = end; + } + + @JsonValue + public String getStatus() { + return status; + } + + public boolean isEnd() { + return end; + } + + @JsonCreator + public static RemoteDebugStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(RemoteDebugStatusEnum.class, status)); + } +} + + diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugStepKeyEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugStepKeyEnum.java new file mode 100644 index 0000000..b2c7b51 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/RemoteDebugStepKeyEnum.java @@ -0,0 +1,88 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public enum RemoteDebugStepKeyEnum { + + GET_BID("get_bid", "获取 bid"), + + UPGRADING_PREVENT_REBOOT("upgrading_prevent_reboot", "检查设备是否正在更新"), + + CHECK_WORK_MODE("check_work_mode", "检查是否进入远程调试模式"), + + CHECK_TASK_STATE("check_task_state", "检查DJI Dock是否空闲"), + + LAND_MCU_REBOOT("land_mcu_reboot", "着陆MCU重新启动"), + + RAIN_MCU_REBOOT("rain_mcu_reboot", "气象站MCU重启"), + + CORE_MCU_REBOOT("core_mcu_reboot", "中控MCU重启"), + + SDR_REBOOT("sdr_reboot", "SDR重启"), + + WRITE_REBOOT_PARAM_FILE("write_reboot_param_file", "写入重新启动标志"), + + GET_DRONE_POWER_STATE("get_drone_power_state", "获取电池充电状态"), + + CLOSE_PUTTER("close_putter", "关闭推杆"), + + CHECK_WIRED_CONNECT_STATE("check_wired_connect_state", "获取飞机状态"), + + OPEN_DRONE("open_drone", "打开平面"), + + OPEN_ALARM("open_alarm", "打开声光报警器"), + + CHECK_SCRAM_STATE("check_scram_state", "检查紧急停止开关是否按下"), + + OPEN_COVER("open_cover", "打开舱门"), + + CHECK_DRONE_SDR_CONNECT_STATE("check_drone_sdr_connect_state", "建立SDR无线连接"), + + TURN_ON_DRONE("turn_on_drone", "打开飞机"), + + DRONE_PADDLE_FORWARD("drone_paddle_forward", "打开前挡板"), + + CLOSE_COVER("close_cover", "关闭舱门"), + + DRONE_PADDLE_REVERSE("drone_paddle_reverse", "打开倒车拨杆"), + + DRONE_PADDLE_STOP("drone_paddle_stop", "停止桨叶旋转"), + + FREE_PUTTER("free_putter", "释放推杆"), + + STOP_CHARGE("stop_charge", "停止充电"); + + private final String stepKey; + + private final String message; + + RemoteDebugStepKeyEnum(String stepKey, String message) { + this.stepKey = stepKey; + this.message = message; + } + + @JsonValue + public String getStepKey() { + return stepKey; + } + + public String getMessage() { + return message; + } + + @JsonCreator + public static RemoteDebugStepKeyEnum find(String stepKey) { + return Arrays.stream(values()).filter(stepKeyEnum -> stepKeyEnum.stepKey.equals(stepKey)).findAny() + .orElseThrow(() -> new CloudSDKException(RemoteDebugStepKeyEnum.class,stepKey)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/SdrWorkmodeSwitchRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/SdrWorkmodeSwitchRequest.java new file mode 100644 index 0000000..d459bd8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/SdrWorkmodeSwitchRequest.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.cloudapi.device.LinkWorkModeEnum; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class SdrWorkmodeSwitchRequest extends BaseModel { + + @NotNull + private LinkWorkModeEnum linkWorkmode; + + public SdrWorkmodeSwitchRequest() { + } + + @Override + public String toString() { + return "SdrWorkmodeSwitchRequest{" + + "linkWorkmode=" + linkWorkmode + + '}'; + } + + public LinkWorkModeEnum getLinkWorkmode() { + return linkWorkmode; + } + + public SdrWorkmodeSwitchRequest setLinkWorkmode(LinkWorkModeEnum linkWorkmode) { + this.linkWorkmode = linkWorkmode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/SimSlotSwitchRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/SimSlotSwitchRequest.java new file mode 100644 index 0000000..d61a96e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/SimSlotSwitchRequest.java @@ -0,0 +1,71 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.cloudapi.device.SimSlotEnum; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class SimSlotSwitchRequest extends BaseModel { + + /** + * Identifies the dongle to be operated on. + */ + @NotNull + private String imei; + + /** + * Identifies the target device to operate on. + */ + @NotNull + private DongleDeviceTypeEnum deviceType; + + /** + * Switch between using physical sim card and using esim. + */ + @NotNull + private SimSlotEnum simSlot; + + public SimSlotSwitchRequest() { + } + + @Override + public String toString() { + return "SimSlotSwitchRequest{" + + "imei='" + imei + '\'' + + ", deviceType=" + deviceType + + ", simSlot=" + simSlot + + '}'; + } + + public String getImei() { + return imei; + } + + public SimSlotSwitchRequest setImei(String imei) { + this.imei = imei; + return this; + } + + public DongleDeviceTypeEnum getDeviceType() { + return deviceType; + } + + public SimSlotSwitchRequest setDeviceType(DongleDeviceTypeEnum deviceType) { + this.deviceType = deviceType; + return this; + } + + public SimSlotEnum getSimSlot() { + return simSlot; + } + + public SimSlotSwitchRequest setSimSlot(SimSlotEnum simSlot) { + this.simSlot = simSlot; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/api/AbstractDebugService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/api/AbstractDebugService.java new file mode 100644 index 0000000..670ebef --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/api/AbstractDebugService.java @@ -0,0 +1,396 @@ +package org.dromara.common.sdk.cloudapi.debug.api; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.debug.*; +import org.dromara.common.sdk.common.BaseModel; +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.common.SpringBeanUtils; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.events.EventsDataRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsResponse; +import org.dromara.common.sdk.mqtt.services.ServicesPublish; +import org.dromara.common.sdk.mqtt.services.ServicesReplyData; +import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; +import com.fasterxml.jackson.core.type.TypeReference; +import jakarta.annotation.Resource; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public abstract class AbstractDebugService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Open the debug mode + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> debugModeOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DEBUG_MODE_OPEN.getMethod()); + } + + /** + * Close the debug mode + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> debugModeClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DEBUG_MODE_CLOSE.getMethod()); + } + + /** + * Open the supplement light + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> supplementLightOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.SUPPLEMENT_LIGHT_OPEN.getMethod()); + } + + /** + * Close the supplement light + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> supplementLightClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.SUPPLEMENT_LIGHT_CLOSE.getMethod()); + } + + /** + * Maintenance state switch of battery + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> batteryMaintenanceSwitch(GatewayManager gateway, BatteryMaintenanceSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.BATTERY_MAINTENANCE_SWITCH.getMethod(), + request); + } + + /** + * Air conditioner working mode switch of dock + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> airConditionerModeSwitch(GatewayManager gateway, AirConditionerModeSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.AIR_CONDITIONER_MODE_SWITCH.getMethod(), + request); + } + + /** + * Sound and light alarm switch of dock + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> alarmStateSwitch(GatewayManager gateway, AlarmStateSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.ALARM_STATE_SWITCH.getMethod(), + request); + } + + /** + * Battery storage mode switch of dock + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> batteryStoreModeSwitch(GatewayManager gateway, BatteryStoreModeSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.BATTERY_STORE_MODE_SWITCH.getMethod(), + request); + } + + /** + * Reboot the dock + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> deviceReboot(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DEVICE_REBOOT.getMethod()); + } + + /** + * Power on the aircraft + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> droneOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DRONE_OPEN.getMethod()); + } + + /** + * Power off the aircraft + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> droneClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DRONE_CLOSE.getMethod()); + } + + /** + * Format the dock data + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> deviceFormat(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DEVICE_FORMAT.getMethod()); + } + + /** + * Format the aircraft data + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> droneFormat(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.DRONE_FORMAT.getMethod()); + } + + /** + * Open the dock cover + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> coverOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.COVER_OPEN.getMethod()); + } + + /** + * Close the dock cover + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> coverClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.COVER_CLOSE.getMethod()); + } + + /** + * Open the putter + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = {GatewayTypeEnum.RC, GatewayTypeEnum.DOCK2}) + public TopicServicesResponse> putterOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.PUTTER_OPEN.getMethod()); + } + + /** + * Close the putter + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = {GatewayTypeEnum.RC, GatewayTypeEnum.DOCK2}) + public TopicServicesResponse> putterClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.PUTTER_CLOSE.getMethod()); + } + + /** + * Turn on charging + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> chargeOpen(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.CHARGE_OPEN.getMethod()); + } + + /** + * Turn off charging + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> chargeClose(GatewayManager gateway) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.CHARGE_CLOSE.getMethod()); + } + + /** + * Switch of 4G enhancement mode + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse> sdrWorkmodeSwitch(GatewayManager gateway, SdrWorkmodeSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.SDR_WORKMODE_SWITCH.getMethod(), + request); + } + + /** + * Common interface for remote debugging + * @param gateway + * @param methodEnum + * @param request data + * @return services_reply + */ + public TopicServicesResponse> remoteDebug(GatewayManager gateway, DebugMethodEnum methodEnum, BaseModel request) { + try { + List clazz = new ArrayList<>(); + List args = new ArrayList<>(); + clazz.add(GatewayManager.class); + args.add(gateway); + if (Objects.nonNull(request)) { + clazz.add(request.getClass()); + args.add(request); + } + AbstractDebugService abstractDebugService = SpringBeanUtils.getBean(this.getClass()); + Method method = abstractDebugService.getClass().getDeclaredMethod(Common.convertSnake(methodEnum.getMethod()), clazz.toArray(Class[]::new)); + return (TopicServicesResponse>) method.invoke(abstractDebugService, args.toArray()); + } catch (NoSuchMethodException | IllegalAccessException e) { + throw new CloudSDKException(e); + } catch (InvocationTargetException e) { + throw new CloudSDKException(e.getTargetException()); + } + } + + /** + * Inform of remote debug progress + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse remoteDebugProgress(TopicEventsRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("remoteDebugProgress not implemented"); + } + + /** + * esim activation + * @param gateway gateway device + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_1, include = GatewayTypeEnum.DOCK2) + public TopicServicesResponse> esimActivate(GatewayManager gateway, EsimActivateRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.ESIM_ACTIVATE.getMethod(), + request); + } + + /** + * esim and sim switching + * @param gateway gateway device + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_1, include = GatewayTypeEnum.DOCK2) + public TopicServicesResponse> simSlotSwitch(GatewayManager gateway, SimSlotSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.SIM_SLOT_SWITCH.getMethod(), + request); + } + + /** + * esim operator switching + * @param gateway gateway device + * @param request data + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_1, include = GatewayTypeEnum.DOCK2) + public TopicServicesResponse> esimOperatorSwitch(GatewayManager gateway, EsimOperatorSwitchRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + DebugMethodEnum.ESIM_OPERATOR_SWITCH.getMethod(), + request); + } + + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/AirConditioner.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/AirConditioner.java new file mode 100644 index 0000000..a24b10d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/AirConditioner.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AirConditioner { + + private AirConditionerStateEnum airConditionerState; + + private Integer switchTime; + + public AirConditioner() { + } + + @Override + public String toString() { + return "AirConditioner{" + + "airConditionerState=" + airConditionerState + + ", switchTime=" + switchTime + + '}'; + } + + public AirConditionerStateEnum getAirConditionerState() { + return airConditionerState; + } + + public AirConditioner setAirConditionerState(AirConditionerStateEnum airConditionerState) { + this.airConditionerState = airConditionerState; + return this; + } + + public Integer getSwitchTime() { + return switchTime; + } + + public AirConditioner setSwitchTime(Integer switchTime) { + this.switchTime = switchTime; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/AirConditionerStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/AirConditionerStateEnum.java new file mode 100644 index 0000000..0ea9558 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/AirConditionerStateEnum.java @@ -0,0 +1,56 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum AirConditionerStateEnum { + + IDLE(0), + + COOL(1), + + HEAT(2), + + DEHUMIDIFICATION(3), + + COOLING_EXIT(4), + + HEATING_EXIT(5), + + DEHUMIDIFICATION_EXIT(6), + + COOLING_PREPARATION(7), + + HEATING_PREPARATION(8), + + DEHUMIDIFICATION_PREPARATION(9), + + DISCONNECTED(32767), + ; + + private final int state; + + AirConditionerStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static AirConditionerStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(AirConditionerStateEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/AlternateLandPoint.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/AlternateLandPoint.java new file mode 100644 index 0000000..6996f1b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/AlternateLandPoint.java @@ -0,0 +1,69 @@ +package org.dromara.common.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/11 + */ +public class AlternateLandPoint { + + private Float latitude; + + private Float longitude; + + private Float safeLandHeight; + + @JsonProperty("is_configured") + private Boolean configured; + + public AlternateLandPoint() { + } + + @Override + public String toString() { + return "AlternateLandPoint{" + + "latitude=" + latitude + + ", longitude=" + longitude + + ", safeLandHeight=" + safeLandHeight + + ", configured=" + configured + + '}'; + } + + public Float getLatitude() { + return latitude; + } + + public AlternateLandPoint setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public AlternateLandPoint setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getSafeLandHeight() { + return safeLandHeight; + } + + public AlternateLandPoint setSafeLandHeight(Float safeLandHeight) { + this.safeLandHeight = safeLandHeight; + return this; + } + + public Boolean getConfigured() { + return configured; + } + + public AlternateLandPoint setConfigured(Boolean configured) { + this.configured = configured; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/BackupBattery.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/BackupBattery.java new file mode 100644 index 0000000..31d2d82 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/BackupBattery.java @@ -0,0 +1,57 @@ +package org.dromara.common.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/3 + */ +public class BackupBattery { + + private Integer voltage; + + private Float temperature; + + @JsonProperty("switch") + private Boolean batterySwitch; + + public BackupBattery() { + } + + @Override + public String toString() { + return "BackupBattery{" + + "voltage=" + voltage + + ", temperature=" + temperature + + ", batterySwitch=" + batterySwitch + + '}'; + } + + public Integer getVoltage() { + return voltage; + } + + public BackupBattery setVoltage(Integer voltage) { + this.voltage = voltage; + return this; + } + + public Float getTemperature() { + return temperature; + } + + public BackupBattery setTemperature(Float temperature) { + this.temperature = temperature; + return this; + } + + public Boolean getBatterySwitch() { + return batterySwitch; + } + + public BackupBattery setBatterySwitch(Boolean batterySwitch) { + this.batterySwitch = batterySwitch; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/Battery.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/Battery.java new file mode 100644 index 0000000..5f83c18 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/Battery.java @@ -0,0 +1,138 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/24 + */ +public class Battery { + + private String firmwareVersion; + + private BatteryIndexEnum index; + + private Integer loopTimes; + + private Integer capacityPercent; + + private String sn; + + private Integer subType; + + private Float temperature; + + private Integer type; + + private Integer voltage; + + private Integer highVoltageStorageDays; + + public Battery() { + } + + @Override + public String toString() { + return "Battery{" + + "firmwareVersion='" + firmwareVersion + '\'' + + ", index=" + index + + ", loopTimes=" + loopTimes + + ", capacityPercent=" + capacityPercent + + ", sn='" + sn + '\'' + + ", subType=" + subType + + ", temperature=" + temperature + + ", type=" + type + + ", voltage=" + voltage + + ", highVoltageStorageDays=" + highVoltageStorageDays + + '}'; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public Battery setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } + + public BatteryIndexEnum getIndex() { + return index; + } + + public Battery setIndex(BatteryIndexEnum index) { + this.index = index; + return this; + } + + public Integer getLoopTimes() { + return loopTimes; + } + + public Battery setLoopTimes(Integer loopTimes) { + this.loopTimes = loopTimes; + return this; + } + + public Integer getCapacityPercent() { + return capacityPercent; + } + + public Battery setCapacityPercent(Integer capacityPercent) { + this.capacityPercent = capacityPercent; + return this; + } + + public String getSn() { + return sn; + } + + public Battery setSn(String sn) { + this.sn = sn; + return this; + } + + public Integer getSubType() { + return subType; + } + + public Battery setSubType(Integer subType) { + this.subType = subType; + return this; + } + + public Float getTemperature() { + return temperature; + } + + public Battery setTemperature(Float temperature) { + this.temperature = temperature; + return this; + } + + public Integer getType() { + return type; + } + + public Battery setType(Integer type) { + this.type = type; + return this; + } + + public Integer getVoltage() { + return voltage; + } + + public Battery setVoltage(Integer voltage) { + this.voltage = voltage; + return this; + } + + public Integer getHighVoltageStorageDays() { + return highVoltageStorageDays; + } + + public Battery setHighVoltageStorageDays(Integer highVoltageStorageDays) { + this.highVoltageStorageDays = highVoltageStorageDays; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/BatteryIndexEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/BatteryIndexEnum.java new file mode 100644 index 0000000..d028f9b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/BatteryIndexEnum.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum BatteryIndexEnum { + + LEFT(0), + + RIGHT(1); + + private final int index; + + BatteryIndexEnum(int index) { + this.index = index; + } + + @JsonValue + public int getIndex() { + return index; + } + + @JsonCreator + public static BatteryIndexEnum find(int index) { + return Arrays.stream(values()).filter(indexEnum -> indexEnum.index == index).findAny() + .orElseThrow(() -> new CloudSDKException(BatteryIndexEnum.class, index)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/BatteryStoreModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/BatteryStoreModeEnum.java new file mode 100644 index 0000000..d11a91b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/BatteryStoreModeEnum.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum BatteryStoreModeEnum { + + PLAN(1), + + EMERGENCY(2); + + private final int mode; + + BatteryStoreModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static BatteryStoreModeEnum find(int mode) { + return Arrays.stream(BatteryStoreModeEnum.values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(BatteryStoreModeEnum.class, mode)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CameraIsoEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CameraIsoEnum.java new file mode 100644 index 0000000..3d4840e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CameraIsoEnum.java @@ -0,0 +1,61 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public enum CameraIsoEnum { + + AUTO(0), + + AUTO_HIGH_SENSE(1), + + _50(2), + + _100(3), + + _200(4), + + _400(5), + + _800(6), + + _1600(7), + + _3200(8), + + _6400(9), + + _12800(10), + + _25600(11), + + FIXED(255), + + ; + + private final int iso; + + CameraIsoEnum(int iso) { + this.iso = iso; + } + + @JsonValue + public int getIso() { + return iso; + } + + @JsonCreator + public static CameraIsoEnum find(int iso) { + return Arrays.stream(values()).filter(isoEnum -> isoEnum.iso == iso).findAny() + .orElseThrow(() -> new CloudSDKException(CameraIsoEnum.class, iso)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CameraModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CameraModeEnum.java new file mode 100644 index 0000000..df438f8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CameraModeEnum.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public enum CameraModeEnum { + + PHOTO(0), + + VIDEO(1), + + LOW_LIGHT_INTELLIGENCE(2), + + PANORAMA(3), + + UNSUPPORTED(-1), + + ; + + private final int mode; + + CameraModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static CameraModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(CameraModeEnum.class, mode)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CameraStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CameraStateEnum.java new file mode 100644 index 0000000..ed7abd3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CameraStateEnum.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/23 + */ +public enum CameraStateEnum { + + IDLE(0), + + WORKING(1), + ; + + private final int state; + + CameraStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static CameraStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(CameraStateEnum.class, state)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ControlSourceEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ControlSourceEnum.java new file mode 100644 index 0000000..4b03cf1 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ControlSourceEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/16 + */ +public enum ControlSourceEnum { + + A("A"), + + B("B"), + + UNKNOWN(""); + + private final String controlSource; + + ControlSourceEnum(String controlSource) { + this.controlSource = controlSource; + } + + @JsonValue + public String getControlSource() { + return controlSource; + } + + @JsonCreator + public static ControlSourceEnum find(String controlSource) { + return Arrays.stream(values()).filter(controlSourceEnum -> controlSourceEnum.controlSource.equals(controlSource)).findAny() + .orElseThrow(() -> new CloudSDKException(ControlSourceEnum.class, controlSource)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CoverStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CoverStateEnum.java new file mode 100644 index 0000000..1111e9a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/CoverStateEnum.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum CoverStateEnum { + + CLOSED(0), + + OPENED(1), + + HALF_OPEN(2), + + ABNORMAL(3), + ; + + private final int state; + + CoverStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static CoverStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(CoverStateEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceDomainEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceDomainEnum.java new file mode 100644 index 0000000..be9d5da --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceDomainEnum.java @@ -0,0 +1,45 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +@Schema(description = "device domain", enumAsRef = true) +public enum DeviceDomainEnum { + + DRONE(0), + + PAYLOAD(1), + + REMOTER_CONTROL(2), + + DOCK (3), + + ; + + private final int domain; + + DeviceDomainEnum(int domain) { + this.domain = domain; + } + + @JsonCreator + public static DeviceDomainEnum find(int domain) { + return Arrays.stream(values()).filter(domainEnum -> domainEnum.domain == domain).findAny() + .orElseThrow(() -> new CloudSDKException(DeviceDomainEnum.class, domain)); + } + + @JsonValue + public int getDomain() { + return domain; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceEnum.java new file mode 100644 index 0000000..c56f4cd --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceEnum.java @@ -0,0 +1,129 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +@Schema(description = "device model key.", format = "domain-type-subType", enumAsRef = true, example = "0-89-0") +public enum DeviceEnum { + + M350(DeviceDomainEnum.DRONE, DeviceTypeEnum.M350, DeviceSubTypeEnum.ZERO), + + M300(DeviceDomainEnum.DRONE, DeviceTypeEnum.M300, DeviceSubTypeEnum.ZERO), + + M30(DeviceDomainEnum.DRONE, DeviceTypeEnum.M30_OR_M3T_CAMERA, DeviceSubTypeEnum.ZERO), + + M30T(DeviceDomainEnum.DRONE, DeviceTypeEnum.M30_OR_M3T_CAMERA, DeviceSubTypeEnum.ONE), + + M3E(DeviceDomainEnum.DRONE, DeviceTypeEnum.M3E, DeviceSubTypeEnum.ZERO), + + M3T(DeviceDomainEnum.DRONE, DeviceTypeEnum.M3E, DeviceSubTypeEnum.ONE), + + M3M(DeviceDomainEnum.DRONE, DeviceTypeEnum.M3E, DeviceSubTypeEnum.TWO), + + Z30(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.Z30, DeviceSubTypeEnum.ZERO), + + XT2(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.XT2, DeviceSubTypeEnum.ZERO), + + FPV(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.FPV, DeviceSubTypeEnum.ZERO), + + XTS(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.XTS, DeviceSubTypeEnum.ZERO), + + H20(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.H20, DeviceSubTypeEnum.ZERO), + + H20T(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.H20T, DeviceSubTypeEnum.ZERO), + + P1(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.P1, DeviceSubTypeEnum._65535), + + M30_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M30_CAMERA, DeviceSubTypeEnum.ZERO), + + M30T_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M30T_CAMERA, DeviceSubTypeEnum.ZERO), + + H20N(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.H20N, DeviceSubTypeEnum.ZERO), + + DOCK_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.DOCK_CAMERA, DeviceSubTypeEnum.ZERO), + + L1(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.L1, DeviceSubTypeEnum.ZERO), + + M3E_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M3E_CAMERA, DeviceSubTypeEnum.ZERO), + + M3T_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M30_OR_M3T_CAMERA, DeviceSubTypeEnum.ZERO), + + M3M_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M3M_CAMERA, DeviceSubTypeEnum.ZERO), + + RC(DeviceDomainEnum.REMOTER_CONTROL, DeviceTypeEnum.RC, DeviceSubTypeEnum.ZERO), + + RC_PLUS(DeviceDomainEnum.REMOTER_CONTROL, DeviceTypeEnum.RC_PLUS, DeviceSubTypeEnum.ZERO), + + RC_PRO(DeviceDomainEnum.REMOTER_CONTROL, DeviceTypeEnum.RC_PRO, DeviceSubTypeEnum.ZERO), + + DOCK(DeviceDomainEnum.DOCK, DeviceTypeEnum.DOCK, DeviceSubTypeEnum.ZERO), + + DOCK2(DeviceDomainEnum.DOCK, DeviceTypeEnum.DOCK2, DeviceSubTypeEnum.ZERO), + + M3D(DeviceDomainEnum.DRONE, DeviceTypeEnum.M3D, DeviceSubTypeEnum.ZERO), + + M3TD(DeviceDomainEnum.DRONE, DeviceTypeEnum.M3D, DeviceSubTypeEnum.ONE), + + M3D_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M3D_CAMERA, DeviceSubTypeEnum.ZERO), + + M3TD_CAMERA(DeviceDomainEnum.PAYLOAD, DeviceTypeEnum.M3TD_CAMERA, DeviceSubTypeEnum.ZERO), + ; + + @Schema(enumAsRef = true) + private final DeviceDomainEnum domain; + + @Schema(enumAsRef = true) + private final DeviceTypeEnum type; + + @Schema(enumAsRef = true) + private final DeviceSubTypeEnum subType; + + DeviceEnum(DeviceDomainEnum domain, DeviceTypeEnum type, DeviceSubTypeEnum subType) { + this.domain = domain; + this.type = type; + this.subType = subType; + } + + public DeviceDomainEnum getDomain() { + return domain; + } + + public DeviceTypeEnum getType() { + return type; + } + + public DeviceSubTypeEnum getSubType() { + return subType; + } + + @JsonValue + public String getDevice() { + return String.format("%s-%s-%s", domain.getDomain(), type.getType(), subType.getSubType()); + } + + public static DeviceEnum find(DeviceDomainEnum domain, DeviceTypeEnum type, DeviceSubTypeEnum subType) { + return DeviceEnum.find(domain.getDomain(), type.getType(), subType.getSubType()); + } + + public static DeviceEnum find(int domain, int type, int subType) { + return Arrays.stream(values()).filter(device -> device.domain.getDomain() == domain && + device.type.getType() == type && device.subType.getSubType() == subType) + .findAny().orElseThrow(() -> new CloudSDKException(DeviceEnum.class, + String.format("%s-%s-%s", domain, type, subType))); + } + + @JsonCreator + public static DeviceEnum find(String key) { + return Arrays.stream(values()).filter(device -> device.getDevice().equals(key)) + .findAny().orElseThrow(() -> new CloudSDKException(DeviceEnum.class, key)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceModelEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceModelEnum.java new file mode 100644 index 0000000..8b0fc50 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceModelEnum.java @@ -0,0 +1,11 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/29 + */ +public enum DeviceModelEnum { + + RC, DOCK, DRONE; +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceOsdHost.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceOsdHost.java new file mode 100644 index 0000000..7139d44 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceOsdHost.java @@ -0,0 +1,124 @@ +package org.dromara.common.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +public class DeviceOsdHost { + + @Schema(description = "device latitude") + @NotNull + private Float latitude; + + @Schema(description = "device longitude") + @NotNull + private Float longitude; + + @Schema(description = "device ellipsoid height") + @NotNull + private Float height; + + @Schema(description = "device head facing angle") + @NotNull + @JsonProperty("attitude_head") + private Float attitudeHead; + + @Schema(description = "height relative to the takeoff point") + @NotNull + private Float elevation; + + @Schema(description = "horizontal speed") + @NotNull + @JsonProperty("horizontal_speed") + private Float horizontalSpeed; + + @Schema(description = "vertical speed") + @NotNull + @JsonProperty("vertical_speed") + private Float verticalSpeed; + + public DeviceOsdHost() { + } + + @Override + public String toString() { + return "DeviceOsdHost{" + + "latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + ", attitudeHead=" + attitudeHead + + ", elevation=" + elevation + + ", horizontalSpeed=" + horizontalSpeed + + ", verticalSpeed=" + verticalSpeed + + '}'; + } + + public Float getLatitude() { + return latitude; + } + + public DeviceOsdHost setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public DeviceOsdHost setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public DeviceOsdHost setHeight(Float height) { + this.height = height; + return this; + } + + public Float getAttitudeHead() { + return attitudeHead; + } + + public DeviceOsdHost setAttitudeHead(Float attitudeHead) { + this.attitudeHead = attitudeHead; + return this; + } + + public Float getElevation() { + return elevation; + } + + public DeviceOsdHost setElevation(Float elevation) { + this.elevation = elevation; + return this; + } + + public Float getHorizontalSpeed() { + return horizontalSpeed; + } + + public DeviceOsdHost setHorizontalSpeed(Float horizontalSpeed) { + this.horizontalSpeed = horizontalSpeed; + return this; + } + + public Float getVerticalSpeed() { + return verticalSpeed; + } + + public DeviceOsdHost setVerticalSpeed(Float verticalSpeed) { + this.verticalSpeed = verticalSpeed; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceOsdWsResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceOsdWsResponse.java new file mode 100644 index 0000000..1abf20d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceOsdWsResponse.java @@ -0,0 +1,53 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.common.BaseModel; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Schema(name = "DeviceOsdWsResponse", description = "BizCode: device_osd.

Websocket response data when device topology changes.

") +public class DeviceOsdWsResponse extends BaseModel { + + @NotNull + @Schema(description = "drone sn", example = "1AD3CA2VL3LAD6") + private String sn; + + @NotNull + @Valid + private DeviceOsdHost host; + + public DeviceOsdWsResponse() { + } + + @Override + public String toString() { + return "DeviceOsdWsResponse{" + + "sn='" + sn + '\'' + + ", host=" + host + + '}'; + } + + public String getSn() { + return sn; + } + + public DeviceOsdWsResponse setSn(String sn) { + this.sn = sn; + return this; + } + + public DeviceOsdHost getHost() { + return host; + } + + public DeviceOsdWsResponse setHost(DeviceOsdHost host) { + this.host = host; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceSubTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceSubTypeEnum.java new file mode 100644 index 0000000..cd798f3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceSubTypeEnum.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/26 + */ +@Schema(description = "device subType", enumAsRef = true) +public enum DeviceSubTypeEnum { + + ZERO(0), + + ONE(1), + + TWO(2), + + _65535(65535); + + private final int subType; + + DeviceSubTypeEnum(int subType) { + this.subType = subType; + } + + @JsonValue + public int getSubType() { + return subType; + } + + @JsonCreator + public static DeviceSubTypeEnum find(int subType) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.subType == subType).findAny() + .orElseThrow(() -> new CloudSDKException(DeviceSubTypeEnum.class, subType)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceTypeEnum.java new file mode 100644 index 0000000..49bd0db --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DeviceTypeEnum.java @@ -0,0 +1,87 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/26 + */ +@Schema(description = "device type", enumAsRef = true) +public enum DeviceTypeEnum { + + M350(89), + + M300(60), + + M30_OR_M3T_CAMERA(67), + + M3E(77), + + Z30(20), + + XT2(26), + + FPV(39), + + XTS(41), + + H20(42), + + H20T(43), + + P1(50), + + M30_CAMERA(52), + + M30T_CAMERA(53), + + H20N(61), + + DOCK_CAMERA(165), + + L1(90742), + + M3E_CAMERA(66), + + M3M_CAMERA(68), + + RC(56), + + RC_PLUS(119), + + RC_PRO(144), + + DOCK(1), + + DOCK2(2), + + M3D(91), + + M3D_CAMERA(80), + + M3TD_CAMERA(81), + ; + + private final int type; + + DeviceTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static DeviceTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(DeviceTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDistanceLimitStatus.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDistanceLimitStatus.java new file mode 100644 index 0000000..4804177 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDistanceLimitStatus.java @@ -0,0 +1,58 @@ +package org.dromara.common.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * The state of the drone's limited distance + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class DockDistanceLimitStatus { + + private SwitchActionEnum state; + + private Integer distanceLimit; + + @JsonProperty("is_near_distance_limit") + private Boolean nearDistanceLimit; + + public DockDistanceLimitStatus() { + } + + @Override + public String toString() { + return "DockDistanceLimitStatusSet{" + + "state=" + state + + ", distanceLimit=" + distanceLimit + + ", nearDistanceLimit=" + nearDistanceLimit + + '}'; + } + + public SwitchActionEnum getState() { + return state; + } + + public DockDistanceLimitStatus setState(SwitchActionEnum state) { + this.state = state; + return this; + } + + public Integer getDistanceLimit() { + return distanceLimit; + } + + public DockDistanceLimitStatus setDistanceLimit(Integer distanceLimit) { + this.distanceLimit = distanceLimit; + return this; + } + + public Boolean getNearDistanceLimit() { + return nearDistanceLimit; + } + + public DockDistanceLimitStatus setNearDistanceLimit(Boolean nearDistanceLimit) { + this.nearDistanceLimit = nearDistanceLimit; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneControlSource.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneControlSource.java new file mode 100644 index 0000000..a4c647e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneControlSource.java @@ -0,0 +1,116 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class DockDroneControlSource { + + private ControlSourceEnum controlSource; + + private Float homeLatitude; + + private Float homeLongitude; + + private Integer lowBatteryWarningThreshold; + + private Integer seriousLowBatteryWarningThreshold; + + private List payloads; + + private Boolean locked; + + private ModeCodeReasonEnum modeCodeReason; + + public DockDroneControlSource() { + } + + @Override + public String toString() { + return "DockDroneControlSource{" + + "controlSource=" + controlSource + + ", homeLatitude=" + homeLatitude + + ", homeLongitude=" + homeLongitude + + ", lowBatteryWarningThreshold=" + lowBatteryWarningThreshold + + ", seriousLowBatteryWarningThreshold=" + seriousLowBatteryWarningThreshold + + ", payloads=" + payloads + + ", locked=" + locked + + ", modeCodeReason=" + modeCodeReason + + '}'; + } + + public ControlSourceEnum getControlSource() { + return controlSource; + } + + public DockDroneControlSource setControlSource(ControlSourceEnum controlSource) { + this.controlSource = controlSource; + return this; + } + + public Float getHomeLatitude() { + return homeLatitude; + } + + public DockDroneControlSource setHomeLatitude(Float homeLatitude) { + this.homeLatitude = homeLatitude; + return this; + } + + public Float getHomeLongitude() { + return homeLongitude; + } + + public DockDroneControlSource setHomeLongitude(Float homeLongitude) { + this.homeLongitude = homeLongitude; + return this; + } + + public Integer getLowBatteryWarningThreshold() { + return lowBatteryWarningThreshold; + } + + public DockDroneControlSource setLowBatteryWarningThreshold(Integer lowBatteryWarningThreshold) { + this.lowBatteryWarningThreshold = lowBatteryWarningThreshold; + return this; + } + + public Integer getSeriousLowBatteryWarningThreshold() { + return seriousLowBatteryWarningThreshold; + } + + public DockDroneControlSource setSeriousLowBatteryWarningThreshold(Integer seriousLowBatteryWarningThreshold) { + this.seriousLowBatteryWarningThreshold = seriousLowBatteryWarningThreshold; + return this; + } + + public List getPayloads() { + return payloads; + } + + public DockDroneControlSource setPayloads(List payloads) { + this.payloads = payloads; + return this; + } + + public Boolean getLocked() { + return locked; + } + + public DockDroneControlSource setLocked(Boolean locked) { + this.locked = locked; + return this; + } + + public ModeCodeReasonEnum getModeCodeReason() { + return modeCodeReason; + } + + public DockDroneControlSource setModeCodeReason(ModeCodeReasonEnum modeCodeReason) { + this.modeCodeReason = modeCodeReason; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneCurrentCommanderFlightMode.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneCurrentCommanderFlightMode.java new file mode 100644 index 0000000..619f63b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneCurrentCommanderFlightMode.java @@ -0,0 +1,34 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.cloudapi.control.CommanderFlightModeEnum; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class DockDroneCurrentCommanderFlightMode { + + @JsonProperty("current_commander_flight_mode") + private CommanderFlightModeEnum currentCommanderFlightMode; + + public DockDroneCurrentCommanderFlightMode() { + } + + @Override + public String toString() { + return "DockDroneCurrentCommanderFlightMode{" + + "currentCommanderFlightMode=" + currentCommanderFlightMode + + '}'; + } + + public CommanderFlightModeEnum getCurrentCommanderFlightMode() { + return currentCommanderFlightMode; + } + + public DockDroneCurrentCommanderFlightMode setCurrentCommanderFlightMode(CommanderFlightModeEnum currentCommanderFlightMode) { + this.currentCommanderFlightMode = currentCommanderFlightMode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneCurrentRthMode.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneCurrentRthMode.java new file mode 100644 index 0000000..095a483 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneCurrentRthMode.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.cloudapi.wayline.RthModeEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/11 + */ +public class DockDroneCurrentRthMode { + + /** + * Current RTH height mode + */ + @JsonProperty("current_rth_mode") + @NotNull + private RthModeEnum currentRthMode; + + public DockDroneCurrentRthMode() { + } + + @Override + public String toString() { + return "DockDroneCurrentRthMode{" + + "currentRthMode=" + currentRthMode + + '}'; + } + + public RthModeEnum getCurrentRthMode() { + return currentRthMode; + } + + public DockDroneCurrentRthMode setCurrentRthMode(RthModeEnum currentRthMode) { + this.currentRthMode = currentRthMode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneModeCodeReason.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneModeCodeReason.java new file mode 100644 index 0000000..5bdbd98 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneModeCodeReason.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class DockDroneModeCodeReason { + + private ModeCodeReasonEnum modeCodeReason; + + public DockDroneModeCodeReason() { + } + + @Override + public String toString() { + return "DockDroneModeCodeReason{" + + "modeCodeReason=" + modeCodeReason + + '}'; + } + + public ModeCodeReasonEnum getModeCodeReason() { + return modeCodeReason; + } + + public DockDroneModeCodeReason setModeCodeReason(ModeCodeReasonEnum modeCodeReason) { + this.modeCodeReason = modeCodeReason; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDronePayload.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDronePayload.java new file mode 100644 index 0000000..a61de89 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDronePayload.java @@ -0,0 +1,252 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; + +import java.util.List; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/6 + */ +public class DockDronePayload { + + private PayloadIndex payloadIndex; + + private Float gimbalPitch; + + private Float gimbalRoll; + + private Float gimbalYaw; + + private Float measureTargetAltitude; + + private Float measureTargetDistance; + + private Float measureTargetLatitude; + + private Float measureTargetLongitude; + + private MeasureTargetStateEnum measureTargetErrorState; + + private Integer version; + + private ThermalPaletteStyleEnum thermalCurrentPaletteStyle; + + private ThermalGainModeEnum thermalGainMode; + + private Float thermalGlobalTemperatureMax; + + private Float thermalGlobalTemperatureMin; + + private Integer thermalIsothermLowerLimit; + + private SwitchActionEnum thermalIsothermState; + + private Integer thermalIsothermUpperLimit; + + private List smartTrackPoint; + + @CloudSDKVersion(include = GatewayTypeEnum.DOCK2) + private Float zoomFactor; + + public DockDronePayload() { + } + + @Override + public String toString() { + return "DockDronePayload{" + + "payloadIndex=" + payloadIndex + + ", gimbalPitch=" + gimbalPitch + + ", gimbalRoll=" + gimbalRoll + + ", gimbalYaw=" + gimbalYaw + + ", measureTargetAltitude=" + measureTargetAltitude + + ", measureTargetDistance=" + measureTargetDistance + + ", measureTargetLatitude=" + measureTargetLatitude + + ", measureTargetLongitude=" + measureTargetLongitude + + ", measureTargetErrorState=" + measureTargetErrorState + + ", version=" + version + + ", thermalCurrentPaletteStyle=" + thermalCurrentPaletteStyle + + ", thermalGainMode=" + thermalGainMode + + ", thermalGlobalTemperatureMax=" + thermalGlobalTemperatureMax + + ", thermalGlobalTemperatureMin=" + thermalGlobalTemperatureMin + + ", thermalIsothermLowerLimit=" + thermalIsothermLowerLimit + + ", thermalIsothermState=" + thermalIsothermState + + ", thermalIsothermUpperLimit=" + thermalIsothermUpperLimit + + ", smartTrackPoint=" + smartTrackPoint + + ", zoomFactor=" + zoomFactor + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public DockDronePayload setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public Float getGimbalPitch() { + return gimbalPitch; + } + + public DockDronePayload setGimbalPitch(Float gimbalPitch) { + this.gimbalPitch = gimbalPitch; + return this; + } + + public Float getGimbalRoll() { + return gimbalRoll; + } + + public DockDronePayload setGimbalRoll(Float gimbalRoll) { + this.gimbalRoll = gimbalRoll; + return this; + } + + public Float getGimbalYaw() { + return gimbalYaw; + } + + public DockDronePayload setGimbalYaw(Float gimbalYaw) { + this.gimbalYaw = gimbalYaw; + return this; + } + + public Float getMeasureTargetAltitude() { + return measureTargetAltitude; + } + + public DockDronePayload setMeasureTargetAltitude(Float measureTargetAltitude) { + this.measureTargetAltitude = measureTargetAltitude; + return this; + } + + public Float getMeasureTargetDistance() { + return measureTargetDistance; + } + + public DockDronePayload setMeasureTargetDistance(Float measureTargetDistance) { + this.measureTargetDistance = measureTargetDistance; + return this; + } + + public Float getMeasureTargetLatitude() { + return measureTargetLatitude; + } + + public DockDronePayload setMeasureTargetLatitude(Float measureTargetLatitude) { + this.measureTargetLatitude = measureTargetLatitude; + return this; + } + + public Float getMeasureTargetLongitude() { + return measureTargetLongitude; + } + + public DockDronePayload setMeasureTargetLongitude(Float measureTargetLongitude) { + this.measureTargetLongitude = measureTargetLongitude; + return this; + } + + public MeasureTargetStateEnum getMeasureTargetErrorState() { + return measureTargetErrorState; + } + + public DockDronePayload setMeasureTargetErrorState(MeasureTargetStateEnum measureTargetErrorState) { + this.measureTargetErrorState = measureTargetErrorState; + return this; + } + + public Integer getVersion() { + return version; + } + + public DockDronePayload setVersion(Integer version) { + this.version = version; + return this; + } + + public ThermalPaletteStyleEnum getThermalCurrentPaletteStyle() { + return thermalCurrentPaletteStyle; + } + + public DockDronePayload setThermalCurrentPaletteStyle(ThermalPaletteStyleEnum thermalCurrentPaletteStyle) { + this.thermalCurrentPaletteStyle = thermalCurrentPaletteStyle; + return this; + } + + public ThermalGainModeEnum getThermalGainMode() { + return thermalGainMode; + } + + public DockDronePayload setThermalGainMode(ThermalGainModeEnum thermalGainMode) { + this.thermalGainMode = thermalGainMode; + return this; + } + + public Float getThermalGlobalTemperatureMax() { + return thermalGlobalTemperatureMax; + } + + public DockDronePayload setThermalGlobalTemperatureMax(Float thermalGlobalTemperatureMax) { + this.thermalGlobalTemperatureMax = thermalGlobalTemperatureMax; + return this; + } + + public Float getThermalGlobalTemperatureMin() { + return thermalGlobalTemperatureMin; + } + + public DockDronePayload setThermalGlobalTemperatureMin(Float thermalGlobalTemperatureMin) { + this.thermalGlobalTemperatureMin = thermalGlobalTemperatureMin; + return this; + } + + public Integer getThermalIsothermLowerLimit() { + return thermalIsothermLowerLimit; + } + + public DockDronePayload setThermalIsothermLowerLimit(Integer thermalIsothermLowerLimit) { + this.thermalIsothermLowerLimit = thermalIsothermLowerLimit; + return this; + } + + public SwitchActionEnum getThermalIsothermState() { + return thermalIsothermState; + } + + public DockDronePayload setThermalIsothermState(SwitchActionEnum thermalIsothermState) { + this.thermalIsothermState = thermalIsothermState; + return this; + } + + public Integer getThermalIsothermUpperLimit() { + return thermalIsothermUpperLimit; + } + + public DockDronePayload setThermalIsothermUpperLimit(Integer thermalIsothermUpperLimit) { + this.thermalIsothermUpperLimit = thermalIsothermUpperLimit; + return this; + } + + public List getSmartTrackPoint() { + return smartTrackPoint; + } + + public DockDronePayload setSmartTrackPoint(List smartTrackPoint) { + this.smartTrackPoint = smartTrackPoint; + return this; + } + + public Float getZoomFactor() { + return zoomFactor; + } + + public DockDronePayload setZoomFactor(Float zoomFactor) { + this.zoomFactor = zoomFactor; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneThermalSupportedPaletteStyle.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneThermalSupportedPaletteStyle.java new file mode 100644 index 0000000..e1f1fef --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneThermalSupportedPaletteStyle.java @@ -0,0 +1,56 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class DockDroneThermalSupportedPaletteStyle { + + private PayloadIndex payloadIndex; + + private ThermalPaletteStyleEnum[] thermalSupportedPaletteStyles; + + private Integer version; + + public DockDroneThermalSupportedPaletteStyle() { + } + + @Override + public String toString() { + return "DockDroneThermalSupportedPaletteStyle{" + + "payloadIndex=" + payloadIndex + + ", thermalSupportedPaletteStyles=" + Arrays.toString(thermalSupportedPaletteStyles) + + ", version=" + version + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public DockDroneThermalSupportedPaletteStyle setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ThermalPaletteStyleEnum[] getThermalSupportedPaletteStyles() { + return thermalSupportedPaletteStyles; + } + + public DockDroneThermalSupportedPaletteStyle setThermalSupportedPaletteStyles(ThermalPaletteStyleEnum[] thermalSupportedPaletteStyles) { + this.thermalSupportedPaletteStyles = thermalSupportedPaletteStyles; + return this; + } + + public Integer getVersion() { + return version; + } + + public DockDroneThermalSupportedPaletteStyle setVersion(Integer version) { + this.version = version; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneWpmzVersion.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneWpmzVersion.java new file mode 100644 index 0000000..e3b9e41 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockDroneWpmzVersion.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class DockDroneWpmzVersion { + + private String wpmzVersion; + + public DockDroneWpmzVersion() { + } + + @Override + public String toString() { + return "DockDroneWpmzVersion{" + + "wpmzVersion='" + wpmzVersion + '\'' + + '}'; + } + + public String getWpmzVersion() { + return wpmzVersion; + } + + public DockDroneWpmzVersion setWpmzVersion(String wpmzVersion) { + this.wpmzVersion = wpmzVersion; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockFirmwareVersion.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockFirmwareVersion.java new file mode 100644 index 0000000..d51a8ab --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockFirmwareVersion.java @@ -0,0 +1,57 @@ +package org.dromara.common.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/28 + */ +public class DockFirmwareVersion { + + private String firmwareVersion; + + @JsonProperty("compatible_status") + private Boolean needCompatibleStatus; + + private Boolean firmwareUpgradeStatus; + + public DockFirmwareVersion() { + } + + @Override + public String toString() { + return "DockFirmwareVersion{" + + "firmwareVersion='" + firmwareVersion + '\'' + + ", compatibleStatus=" + needCompatibleStatus + + ", firmwareUpgradeStatus=" + firmwareUpgradeStatus + + '}'; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public DockFirmwareVersion setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } + + public Boolean getNeedCompatibleStatus() { + return needCompatibleStatus; + } + + public DockFirmwareVersion setNeedCompatibleStatus(Boolean needCompatibleStatus) { + this.needCompatibleStatus = needCompatibleStatus; + return this; + } + + public Boolean getFirmwareUpgradeStatus() { + return firmwareUpgradeStatus; + } + + public DockFirmwareVersion setFirmwareUpgradeStatus(Boolean firmwareUpgradeStatus) { + this.firmwareUpgradeStatus = firmwareUpgradeStatus; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockLiveErrorStatus.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockLiveErrorStatus.java new file mode 100644 index 0000000..dbf757b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockLiveErrorStatus.java @@ -0,0 +1,51 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.cloudapi.livestream.LiveErrorCodeEnum; +import org.dromara.common.sdk.common.ErrorCodeSourceEnum; +import org.dromara.common.sdk.mqtt.MqttReply; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class DockLiveErrorStatus { + + private static final int MOD = 100_000; + + private ErrorCodeSourceEnum source = ErrorCodeSourceEnum.DOCK; + + private LiveErrorCodeEnum errorCode; + + private boolean success; + + @Override + public String toString() { + return "{" + + "errorCode=" + getCode() + + ", errorMsg=" + getMessage() + + '}'; + } + + @JsonCreator + public DockLiveErrorStatus(int code) { + this.success = MqttReply.CODE_SUCCESS == code; + this.source = ErrorCodeSourceEnum.find(code / MOD); + this.errorCode = LiveErrorCodeEnum.find(code % MOD); + } + + public String getMessage() { + return errorCode.getMessage(); + } + + @JsonValue + public Integer getCode() { + return source.getSource() * MOD + errorCode.getCode(); + } + + public boolean isSuccess() { + return success; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockLiveStatus.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockLiveStatus.java new file mode 100644 index 0000000..c3372cf --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockLiveStatus.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class DockLiveStatus { + + private List liveStatus; + + public DockLiveStatus() { + } + + @Override + public String toString() { + return "DockLiveStatus{" + + "liveStatus=" + liveStatus + + '}'; + } + + public List getLiveStatus() { + return liveStatus; + } + + public DockLiveStatus setLiveStatus(List liveStatus) { + this.liveStatus = liveStatus; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockLiveStatusData.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockLiveStatusData.java new file mode 100644 index 0000000..5e8e151 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockLiveStatusData.java @@ -0,0 +1,81 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.cloudapi.livestream.VideoQualityEnum; +import org.dromara.common.sdk.cloudapi.livestream.VideoTypeEnum; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class DockLiveStatusData { + + private Boolean status; + + private VideoId videoId; + + private VideoQualityEnum videoQuality; + + private VideoTypeEnum videoType; + + private DockLiveErrorStatus errorStatus; + + public DockLiveStatusData() { + } + + @Override + public String toString() { + return "DockLiveStatusData{" + + "status=" + status + + ", videoId=" + videoId + + ", videoQuality=" + videoQuality + + ", videoType=" + videoType + + ", errorStatus=" + errorStatus + + '}'; + } + + public Boolean getStatus() { + return status; + } + + public DockLiveStatusData setStatus(Boolean status) { + this.status = status; + return this; + } + + public VideoId getVideoId() { + return videoId; + } + + public DockLiveStatusData setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } + + public VideoQualityEnum getVideoQuality() { + return videoQuality; + } + + public DockLiveStatusData setVideoQuality(VideoQualityEnum videoQuality) { + this.videoQuality = videoQuality; + return this; + } + + public VideoTypeEnum getVideoType() { + return videoType; + } + + public DockLiveStatusData setVideoType(VideoTypeEnum videoType) { + this.videoType = videoType; + return this; + } + + public DockLiveErrorStatus getErrorStatus() { + return errorStatus; + } + + public DockLiveStatusData setErrorStatus(DockLiveErrorStatus errorStatus) { + this.errorStatus = errorStatus; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockMaintainStatus.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockMaintainStatus.java new file mode 100644 index 0000000..9a4ec40 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockMaintainStatus.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class DockMaintainStatus { + + private Integer lastMaintainFlightSorties; + + private Long lastMaintainTime; + + private MaintainTypeEnum lastMaintainType; + + private Boolean state; + + public DockMaintainStatus() { + } + + @Override + public String toString() { + return "DroneMaintainStatus{" + + "lastMaintainFlightSorties=" + lastMaintainFlightSorties + + ", lastMaintainTime=" + lastMaintainTime + + ", lastMaintainType=" + lastMaintainType + + ", state=" + state + + '}'; + } + + public Integer getLastMaintainFlightSorties() { + return lastMaintainFlightSorties; + } + + public DockMaintainStatus setLastMaintainFlightSorties(Integer lastMaintainFlightSorties) { + this.lastMaintainFlightSorties = lastMaintainFlightSorties; + return this; + } + + public Long getLastMaintainTime() { + return lastMaintainTime; + } + + public DockMaintainStatus setLastMaintainTime(Long lastMaintainTime) { + this.lastMaintainTime = lastMaintainTime; + return this; + } + + public MaintainTypeEnum getLastMaintainType() { + return lastMaintainType; + } + + public DockMaintainStatus setLastMaintainType(MaintainTypeEnum lastMaintainType) { + this.lastMaintainType = lastMaintainType; + return this; + } + + public Boolean getState() { + return state; + } + + public DockMaintainStatus setState(Boolean state) { + this.state = state; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockModeCodeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockModeCodeEnum.java new file mode 100644 index 0000000..a85a279 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockModeCodeEnum.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/2/28 + */ +public enum DockModeCodeEnum { + + IDLE(0), + + DEBUGGING(1), + + REMOTE_DEBUGGING(2), + + UPGRADING(3), + + WORKING(4); + + private final int code; + + DockModeCodeEnum(int code) { + this.code = code; + } + + @JsonValue + public int getCode() { + return code; + } + + @JsonCreator + public static DockModeCodeEnum find(int code) { + return Arrays.stream(values()).filter(modeCode -> modeCode.code == code).findAny() + .orElseThrow(() -> new CloudSDKException(DockModeCodeEnum.class, code)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockPayloadControlSource.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockPayloadControlSource.java new file mode 100644 index 0000000..d23d42c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockPayloadControlSource.java @@ -0,0 +1,55 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class DockPayloadControlSource { + + private ControlSourceEnum controlSource; + + private PayloadIndex payloadIndex; + + private String sn; + + public DockPayloadControlSource() { + } + + @Override + public String toString() { + return "RcPayloadControlSource{" + + "controlSource=" + controlSource + + ", payloadIndex=" + payloadIndex + + ", sn='" + sn + '\'' + + '}'; + } + + public ControlSourceEnum getControlSource() { + return controlSource; + } + + public DockPayloadControlSource setControlSource(ControlSourceEnum controlSource) { + this.controlSource = controlSource; + return this; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public DockPayloadControlSource setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public String getSn() { + return sn; + } + + public DockPayloadControlSource setSn(String sn) { + this.sn = sn; + return this; + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockPositionState.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockPositionState.java new file mode 100644 index 0000000..75f13ab --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockPositionState.java @@ -0,0 +1,81 @@ +package org.dromara.common.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 0.3 + * @date 2022/1/27 + */ +public class DockPositionState { + + @JsonProperty("is_calibration") + private Boolean calibration; + + private Integer gpsNumber; + + private PositionFixedEnum isFixed; + + private Integer quality; + + private Integer rtkNumber; + + public DockPositionState() { + } + + @Override + public String toString() { + return "DockPositionState{" + + "Calibration=" + calibration + + ", gpsNumber=" + gpsNumber + + ", isFixed=" + isFixed + + ", quality=" + quality + + ", rtkNumber=" + rtkNumber + + '}'; + } + + public Boolean getCalibration() { + return calibration; + } + + public DockPositionState setCalibration(Boolean calibration) { + this.calibration = calibration; + return this; + } + + public Integer getGpsNumber() { + return gpsNumber; + } + + public DockPositionState setGpsNumber(Integer gpsNumber) { + this.gpsNumber = gpsNumber; + return this; + } + + public PositionFixedEnum getIsFixed() { + return isFixed; + } + + public DockPositionState setIsFixed(PositionFixedEnum isFixed) { + this.isFixed = isFixed; + return this; + } + + public Integer getQuality() { + return quality; + } + + public DockPositionState setQuality(Integer quality) { + this.quality = quality; + return this; + } + + public Integer getRtkNumber() { + return rtkNumber; + } + + public DockPositionState setRtkNumber(Integer rtkNumber) { + this.rtkNumber = rtkNumber; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockSilentMode.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockSilentMode.java new file mode 100644 index 0000000..0d6ef0a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockSilentMode.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.cloudapi.property.SilentModeEnum; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class DockSilentMode extends BaseModel { + + @NotNull + @JsonProperty("silent_mode") + private SilentModeEnum silentMode; + + public DockSilentMode() { + } + + @Override + public String toString() { + return "DockSilentMode{" + + "silentMode=" + silentMode + + '}'; + } + + public SilentModeEnum getSilentMode() { + return silentMode; + } + + public DockSilentMode setSilentMode(SilentModeEnum silentMode) { + this.silentMode = silentMode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockSubDevice.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockSubDevice.java new file mode 100644 index 0000000..37f6b62 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DockSubDevice.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/11 + */ +public class DockSubDevice { + + private String deviceSn; + + private Boolean deviceOnlineStatus; + + private Boolean devicePaired; + + private DeviceEnum deviceModelKey; + + public DockSubDevice() { + } + + @Override + public String toString() { + return "DockSubDevice{" + + "deviceSn='" + deviceSn + '\'' + + ", deviceOnlineStatus=" + deviceOnlineStatus + + ", devicePaired=" + devicePaired + + ", deviceModelKey=" + deviceModelKey + + '}'; + } + + public String getDeviceSn() { + return deviceSn; + } + + public DockSubDevice setDeviceSn(String deviceSn) { + this.deviceSn = deviceSn; + return this; + } + + public Boolean getDeviceOnlineStatus() { + return deviceOnlineStatus; + } + + public DockSubDevice setDeviceOnlineStatus(Boolean deviceOnlineStatus) { + this.deviceOnlineStatus = deviceOnlineStatus; + return this; + } + + public Boolean getDevicePaired() { + return devicePaired; + } + + public DockSubDevice setDevicePaired(Boolean devicePaired) { + this.devicePaired = devicePaired; + return this; + } + + public DeviceEnum getDeviceModelKey() { + return deviceModelKey; + } + + public DockSubDevice setDeviceModelKey(DeviceEnum deviceModelKey) { + this.deviceModelKey = deviceModelKey; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DongleInfo.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DongleInfo.java new file mode 100644 index 0000000..6f1b5e1 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DongleInfo.java @@ -0,0 +1,140 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/19 + */ +public class DongleInfo { + + /** + * Dongle’s unique identification mark + */ + private String imei; + + /** + * dongle type + */ + private DongleTypeEnum dongleType; + + /** + * The unique identification mark of eSIM is used for public account query packages and purchase services. + */ + private String eid; + + /** + * esim activation status + */ + private EsimActivateStateEnum esimActivateState; + + /** + * The status of the physical sim card in the dongle. + */ + private SimCardStateEnum simCardState; + + /** + * Identifies the sim card slot currently being used by the dongle. + */ + private SimSlotEnum simSlot; + + /** + * esim information + */ + private List esimInfos; + + /** + * Physical sim card information that can be inserted into the dongle. + */ + private SimInfo simInfo; + + public DongleInfo() { + } + + @Override + public String toString() { + return "DongleInfo{" + + "imei='" + imei + '\'' + + ", dongleType=" + dongleType + + ", eid='" + eid + '\'' + + ", esimActivateState=" + esimActivateState + + ", simCardState=" + simCardState + + ", simSlot=" + simSlot + + ", esimInfos=" + esimInfos + + ", simInfo=" + simInfo + + '}'; + } + + public String getImei() { + return imei; + } + + public DongleInfo setImei(String imei) { + this.imei = imei; + return this; + } + + public DongleTypeEnum getDongleType() { + return dongleType; + } + + public DongleInfo setDongleType(DongleTypeEnum dongleType) { + this.dongleType = dongleType; + return this; + } + + public String getEid() { + return eid; + } + + public DongleInfo setEid(String eid) { + this.eid = eid; + return this; + } + + public EsimActivateStateEnum getEsimActivateState() { + return esimActivateState; + } + + public DongleInfo setEsimActivateState(EsimActivateStateEnum esimActivateState) { + this.esimActivateState = esimActivateState; + return this; + } + + public SimCardStateEnum getSimCardState() { + return simCardState; + } + + public DongleInfo setSimCardState(SimCardStateEnum simCardState) { + this.simCardState = simCardState; + return this; + } + + public SimSlotEnum getSimSlot() { + return simSlot; + } + + public DongleInfo setSimSlot(SimSlotEnum simSlot) { + this.simSlot = simSlot; + return this; + } + + public List getEsimInfos() { + return esimInfos; + } + + public DongleInfo setEsimInfos(List esimInfos) { + this.esimInfos = esimInfos; + return this; + } + + public SimInfo getSimInfo() { + return simInfo; + } + + public DongleInfo setSimInfo(SimInfo simInfo) { + this.simInfo = simInfo; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DongleInfos.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DongleInfos.java new file mode 100644 index 0000000..c0a82e9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DongleInfos.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class DongleInfos { + + private List dongleInfos; + + public DongleInfos() { + } + + @Override + public String toString() { + return "DongleInfos{" + + "dongleInfos=" + dongleInfos + + '}'; + } + + public List getDongleInfos() { + return dongleInfos; + } + + public DongleInfos setDongleInfos(List dongleInfos) { + this.dongleInfos = dongleInfos; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DongleTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DongleTypeEnum.java new file mode 100644 index 0000000..3a5cef4 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DongleTypeEnum.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public enum DongleTypeEnum { + + OLD_DONGLE(6), + + SUPPORTED_ESIM(10), + + ; + + private final int type; + + DongleTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static DongleTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(DongleTypeEnum.class, type)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DrcStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DrcStateEnum.java new file mode 100644 index 0000000..c2e8b50 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DrcStateEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/2/28 + */ +public enum DrcStateEnum { + + DISCONNECTED(0), + + CONNECTING(1), + + CONNECTED(2); + + private final int state; + + DrcStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static DrcStateEnum find(int state) { + return Arrays.stream(values()).filter(drcState -> drcState.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(DrcStateEnum.class, state)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneBattery.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneBattery.java new file mode 100644 index 0000000..b493866 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneBattery.java @@ -0,0 +1,80 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 0.3 + * @date 2022/1/27 + */ +public class DroneBattery { + + private List batteries; + + private Integer capacityPercent; + + private Integer landingPower; + + private Integer remainFlightTime; + + private Integer returnHomePower; + + public DroneBattery() { + } + + @Override + public String toString() { + return "DroneBattery{" + + "batteries=" + batteries + + ", capacityPercent=" + capacityPercent + + ", landingPower=" + landingPower + + ", remainFlightTime=" + remainFlightTime + + ", returnHomePower=" + returnHomePower + + '}'; + } + + public List getBatteries() { + return batteries; + } + + public DroneBattery setBatteries(List batteries) { + this.batteries = batteries; + return this; + } + + public Integer getCapacityPercent() { + return capacityPercent; + } + + public DroneBattery setCapacityPercent(Integer capacityPercent) { + this.capacityPercent = capacityPercent; + return this; + } + + public Integer getLandingPower() { + return landingPower; + } + + public DroneBattery setLandingPower(Integer landingPower) { + this.landingPower = landingPower; + return this; + } + + public Integer getRemainFlightTime() { + return remainFlightTime; + } + + public DroneBattery setRemainFlightTime(Integer remainFlightTime) { + this.remainFlightTime = remainFlightTime; + return this; + } + + public Integer getReturnHomePower() { + return returnHomePower; + } + + public DroneBattery setReturnHomePower(Integer returnHomePower) { + this.returnHomePower = returnHomePower; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneBatteryMaintenance.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneBatteryMaintenance.java new file mode 100644 index 0000000..df01386 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneBatteryMaintenance.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class DroneBatteryMaintenance { + + private BatteryIndexEnum index; + + private Integer capacityPercent; + + private Integer voltage; + + private Float temperature; + + public DroneBatteryMaintenance() { + } + + @Override + public String toString() { + return "DroneBatteryMaintenance{" + + "index=" + index + + ", capacityPercent=" + capacityPercent + + ", voltage=" + voltage + + ", temperature=" + temperature + + '}'; + } + + public BatteryIndexEnum getIndex() { + return index; + } + + public DroneBatteryMaintenance setIndex(BatteryIndexEnum index) { + this.index = index; + return this; + } + + public Integer getCapacityPercent() { + return capacityPercent; + } + + public DroneBatteryMaintenance setCapacityPercent(Integer capacityPercent) { + this.capacityPercent = capacityPercent; + return this; + } + + public Integer getVoltage() { + return voltage; + } + + public DroneBatteryMaintenance setVoltage(Integer voltage) { + this.voltage = voltage; + return this; + } + + public Float getTemperature() { + return temperature; + } + + public DroneBatteryMaintenance setTemperature(Float temperature) { + this.temperature = temperature; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneBatteryMaintenanceInfo.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneBatteryMaintenanceInfo.java new file mode 100644 index 0000000..1512cb5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneBatteryMaintenanceInfo.java @@ -0,0 +1,76 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 1.4 + * @date 2022/11/3 + */ +public class DroneBatteryMaintenanceInfo { + + private List batteries; + + private MaintenanceStateEnum maintenanceState; + + /** + * Remaining time of battery maintenance + * Round down + * unit: hour + */ + private Integer maintenanceTimeLeft; + + /** + * When the drone is powered off in the dock, this property will report the heating and insulation information of the drone battery. + */ + private HeatStateEnum heatState; + + public DroneBatteryMaintenanceInfo() { + } + + @Override + public String toString() { + return "DroneBatteryMaintenanceInfo{" + + "batteries=" + batteries + + ", maintenanceState=" + maintenanceState + + ", maintenanceTimeLeft=" + maintenanceTimeLeft + + ", heatState=" + heatState + + '}'; + } + + public List getBatteries() { + return batteries; + } + + public DroneBatteryMaintenanceInfo setBatteries(List batteries) { + this.batteries = batteries; + return this; + } + + public MaintenanceStateEnum getMaintenanceState() { + return maintenanceState; + } + + public DroneBatteryMaintenanceInfo setMaintenanceState(MaintenanceStateEnum maintenanceState) { + this.maintenanceState = maintenanceState; + return this; + } + + public Integer getMaintenanceTimeLeft() { + return maintenanceTimeLeft; + } + + public DroneBatteryMaintenanceInfo setMaintenanceTimeLeft(Integer maintenanceTimeLeft) { + this.maintenanceTimeLeft = maintenanceTimeLeft; + return this; + } + + public HeatStateEnum getHeatState() { + return heatState; + } + + public DroneBatteryMaintenanceInfo setHeatState(HeatStateEnum heatState) { + this.heatState = heatState; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneChargeState.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneChargeState.java new file mode 100644 index 0000000..d109e02 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneChargeState.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/11 + */ +public class DroneChargeState { + + private Boolean state; + + private Integer capacityPercent; + + public DroneChargeState() { + } + + @Override + public String toString() { + return "DroneChargeState{" + + "state=" + state + + ", capacityPercent=" + capacityPercent + + '}'; + } + + public Boolean getState() { + return state; + } + + public DroneChargeState setState(Boolean state) { + this.state = state; + return this; + } + + public Integer getCapacityPercent() { + return capacityPercent; + } + + public DroneChargeState setCapacityPercent(Integer capacityPercent) { + this.capacityPercent = capacityPercent; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneMaintainStatus.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneMaintainStatus.java new file mode 100644 index 0000000..4400aeb --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneMaintainStatus.java @@ -0,0 +1,78 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class DroneMaintainStatus { + + private Integer lastMaintainFlightSorties; + + private Integer lastMaintainFlightTime; + + private Long lastMaintainTime; + + private MaintainTypeEnum lastMaintainType; + + private Boolean state; + + public DroneMaintainStatus() { + } + + @Override + public String toString() { + return "DroneMaintainStatus{" + + "lastMaintainFlightSorties=" + lastMaintainFlightSorties + + ", lastMaintainFlightTime=" + lastMaintainFlightTime + + ", lastMaintainTime=" + lastMaintainTime + + ", lastMaintainType=" + lastMaintainType + + ", state=" + state + + '}'; + } + + public Integer getLastMaintainFlightSorties() { + return lastMaintainFlightSorties; + } + + public DroneMaintainStatus setLastMaintainFlightSorties(Integer lastMaintainFlightSorties) { + this.lastMaintainFlightSorties = lastMaintainFlightSorties; + return this; + } + + public Integer getLastMaintainFlightTime() { + return lastMaintainFlightTime; + } + + public DroneMaintainStatus setLastMaintainFlightTime(Integer lastMaintainFlightTime) { + this.lastMaintainFlightTime = lastMaintainFlightTime; + return this; + } + + public Long getLastMaintainTime() { + return lastMaintainTime; + } + + public DroneMaintainStatus setLastMaintainTime(Long lastMaintainTime) { + this.lastMaintainTime = lastMaintainTime; + return this; + } + + public MaintainTypeEnum getLastMaintainType() { + return lastMaintainType; + } + + public DroneMaintainStatus setLastMaintainType(MaintainTypeEnum lastMaintainType) { + this.lastMaintainType = lastMaintainType; + return this; + } + + public Boolean getState() { + return state; + } + + public DroneMaintainStatus setState(Boolean state) { + this.state = state; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneModeCodeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneModeCodeEnum.java new file mode 100644 index 0000000..b32a8e8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DroneModeCodeEnum.java @@ -0,0 +1,76 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/9 + */ +public enum DroneModeCodeEnum { + + IDLE(0), + + TAKEOFF_PREPARE(1), + + TAKEOFF_FINISHED(2), + + MANUAL(3), + + TAKEOFF_AUTO(4), + + WAYLINE(5), + + PANORAMIC_SHOT(6), + + ACTIVE_TRACK(7), + + ADS_B_AVOIDANCE(8), + + RETURN_AUTO(9), + + LANDING_AUTO(10), + + LANDING_FORCED(11), + + LANDING_THREE_PROPELLER(12), + + UPGRADING(13), + + DISCONNECTED(14), + + APAS(15), + + VIRTUAL_JOYSTICK(16), + + LIVE_FLIGHT_CONTROLS(17), + + AERIAL_RTK_FIXED(18), + + DOCK_SITE_EVALUATION(19), + + POI(20), + + ; + + private final int code; + + DroneModeCodeEnum(int code) { + this.code = code; + } + + @JsonValue + public int getCode() { + return code; + } + + @JsonCreator + public static DroneModeCodeEnum find(int code) { + return Arrays.stream(values()).filter(modeCodeEnum -> modeCodeEnum.ordinal() == code).findAny() + .orElseThrow(() -> new CloudSDKException(DroneModeCodeEnum.class, code)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DronePositionState.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DronePositionState.java new file mode 100644 index 0000000..55e9c50 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/DronePositionState.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 0.3 + * @date 2022/1/27 + */ +public class DronePositionState { + + private Integer gpsNumber; + + private PositionFixedEnum isFixed; + + private Integer quality; + + private Integer rtkNumber; + + public DronePositionState() { + } + + @Override + public String toString() { + return "DronePositionState{" + + "gpsNumber=" + gpsNumber + + ", isFixed=" + isFixed + + ", quality=" + quality + + ", rtkNumber=" + rtkNumber + + '}'; + } + + public Integer getGpsNumber() { + return gpsNumber; + } + + public DronePositionState setGpsNumber(Integer gpsNumber) { + this.gpsNumber = gpsNumber; + return this; + } + + public PositionFixedEnum getIsFixed() { + return isFixed; + } + + public DronePositionState setIsFixed(PositionFixedEnum isFixed) { + this.isFixed = isFixed; + return this; + } + + public Integer getQuality() { + return quality; + } + + public DronePositionState setQuality(Integer quality) { + this.quality = quality; + return this; + } + + public Integer getRtkNumber() { + return rtkNumber; + } + + public DronePositionState setRtkNumber(Integer rtkNumber) { + this.rtkNumber = rtkNumber; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/EsimActivateStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/EsimActivateStateEnum.java new file mode 100644 index 0000000..12f5133 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/EsimActivateStateEnum.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public enum EsimActivateStateEnum { + + INACTIVATED(0), + + ACTIVATED(1), + + ; + + private final int state; + + EsimActivateStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static EsimActivateStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(EsimActivateStateEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/EsimInfo.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/EsimInfo.java new file mode 100644 index 0000000..d47b45b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/EsimInfo.java @@ -0,0 +1,63 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class EsimInfo { + + /** + * esim supported operators + */ + private TelecomOperatorEnum telecomOperator; + + /** + * In esim infos, only one esim can be enabled at the same time. + */ + private Boolean enabled; + + /** + * The unique identification mark of the sim card can be used to purchase physical sim card packages. + */ + private String iccid; + + public EsimInfo() { + } + + @Override + public String toString() { + return "EsimInfo{" + + "telecomOperator=" + telecomOperator + + ", enabled=" + enabled + + ", iccid='" + iccid + '\'' + + '}'; + } + + public TelecomOperatorEnum getTelecomOperator() { + return telecomOperator; + } + + public EsimInfo setTelecomOperator(TelecomOperatorEnum telecomOperator) { + this.telecomOperator = telecomOperator; + return this; + } + + public Boolean getEnabled() { + return enabled; + } + + public EsimInfo setEnabled(Boolean enabled) { + this.enabled = enabled; + return this; + } + + public String getIccid() { + return iccid; + } + + public EsimInfo setIccid(String iccid) { + this.iccid = iccid; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ExitWaylineWhenRcLostEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ExitWaylineWhenRcLostEnum.java new file mode 100644 index 0000000..067bd13 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ExitWaylineWhenRcLostEnum.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum ExitWaylineWhenRcLostEnum { + + CONTINUE(0), + + EXECUTE_RC_LOST_ACTION(1); + + private final int action; + + ExitWaylineWhenRcLostEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static ExitWaylineWhenRcLostEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(ExitWaylineWhenRcLostEnum.class, action)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/FirmwareVersion.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/FirmwareVersion.java new file mode 100644 index 0000000..b4151fe --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/FirmwareVersion.java @@ -0,0 +1,31 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/28 + */ +public class FirmwareVersion { + + private String firmwareVersion; + + public FirmwareVersion() { + } + + @Override + public String toString() { + return "FirmwareVersion{" + + "firmwareVersion='" + firmwareVersion + '\'' + + '}'; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public FirmwareVersion setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/FlighttaskStepCodeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/FlighttaskStepCodeEnum.java new file mode 100644 index 0000000..32e6ab0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/FlighttaskStepCodeEnum.java @@ -0,0 +1,50 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum FlighttaskStepCodeEnum { + + TASK_PREPARING(0), + + TASK_OPERATING(1), + + STATE_RECOVERING(2), + + CUSTOM_FLIGHT_AREA_UPDATING(3), + + OFFLINE_MAP_UPDATING(4), + + IDLE(5), + + UNKNOWN1(255), + + UNKNOWN2(256), + ; + + private final int code; + + FlighttaskStepCodeEnum(int code) { + this.code = code; + } + + @JsonValue + public int getCode() { + return code; + } + + @JsonCreator + public static FlighttaskStepCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny() + .orElseThrow(() -> new CloudSDKException(FlighttaskStepCodeEnum.class, code)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/FocusStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/FocusStateEnum.java new file mode 100644 index 0000000..eac0a7c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/FocusStateEnum.java @@ -0,0 +1,43 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public enum FocusStateEnum { + + IDLE(0), + + FOCUSING(1), + + SUCCESS(2), + + FAILED(3), + + ; + + private final int state; + + FocusStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static FocusStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(FocusStateEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/GearEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/GearEnum.java new file mode 100644 index 0000000..d5eb6cc --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/GearEnum.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum GearEnum { + + A(0), + + P(1), + + NAV(2), + + FPV(3), + + FARM(4), + + S(5), + + F(6), + + M(7), + + G(8), + + T(9), + ; + + private final int gear; + + GearEnum(int gear) { + this.gear = gear; + } + + @JsonValue + public int getGear() { + return gear; + } + + @JsonCreator + public static GearEnum find(int gear) { + return Arrays.stream(values()).filter(gearEnum -> gearEnum.gear == gear).findAny() + .orElseThrow(() -> new CloudSDKException(GearEnum.class, gear)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/HeatStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/HeatStateEnum.java new file mode 100644 index 0000000..6f4d466 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/HeatStateEnum.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2022/11/3 + */ +public enum HeatStateEnum { + + DISABLED(0), + + HEATING(1), + + INSULATION(2), + + ; + + private final int state; + + HeatStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static HeatStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(HeatStateEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/IrMeteringArea.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/IrMeteringArea.java new file mode 100644 index 0000000..0cd2c93 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/IrMeteringArea.java @@ -0,0 +1,114 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class IrMeteringArea { + + private Float x; + + private Float y; + + private Float temperature; + + private Float width; + + private Float height; + + private Float averTemperature; + + private IrMeteringPoint minTemperaturePoint; + + private IrMeteringPoint maxTemperaturePoint; + + public IrMeteringArea() { + } + + @Override + public String toString() { + return "IrMeteringArea{" + + "x=" + x + + ", y=" + y + + ", temperature=" + temperature + + ", width=" + width + + ", height=" + height + + ", averTemperature=" + averTemperature + + ", minTemperaturePoint=" + minTemperaturePoint + + ", maxTemperaturePoint=" + maxTemperaturePoint + + '}'; + } + + public Float getX() { + return x; + } + + public IrMeteringArea setX(Float x) { + this.x = x; + return this; + } + + public Float getY() { + return y; + } + + public IrMeteringArea setY(Float y) { + this.y = y; + return this; + } + + public Float getTemperature() { + return temperature; + } + + public IrMeteringArea setTemperature(Float temperature) { + this.temperature = temperature; + return this; + } + + public Float getWidth() { + return width; + } + + public IrMeteringArea setWidth(Float width) { + this.width = width; + return this; + } + + public Float getHeight() { + return height; + } + + public IrMeteringArea setHeight(Float height) { + this.height = height; + return this; + } + + public Float getAverTemperature() { + return averTemperature; + } + + public IrMeteringArea setAverTemperature(Float averTemperature) { + this.averTemperature = averTemperature; + return this; + } + + public IrMeteringPoint getMinTemperaturePoint() { + return minTemperaturePoint; + } + + public IrMeteringArea setMinTemperaturePoint(IrMeteringPoint minTemperaturePoint) { + this.minTemperaturePoint = minTemperaturePoint; + return this; + } + + public IrMeteringPoint getMaxTemperaturePoint() { + return maxTemperaturePoint; + } + + public IrMeteringArea setMaxTemperaturePoint(IrMeteringPoint maxTemperaturePoint) { + this.maxTemperaturePoint = maxTemperaturePoint; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/IrMeteringPoint.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/IrMeteringPoint.java new file mode 100644 index 0000000..c71e1a0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/IrMeteringPoint.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public class IrMeteringPoint { + + private Float x; + + private Float y; + + private Float temperature; + + public IrMeteringPoint() { + } + + @Override + public String toString() { + return "IrMeteringPoint{" + + "x=" + x + + ", y=" + y + + ", temperature=" + temperature + + '}'; + } + + public Float getX() { + return x; + } + + public IrMeteringPoint setX(Float x) { + this.x = x; + return this; + } + + public Float getY() { + return y; + } + + public IrMeteringPoint setY(Float y) { + this.y = y; + return this; + } + + public Float getTemperature() { + return temperature; + } + + public IrMeteringPoint setTemperature(Float temperature) { + this.temperature = temperature; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/LinkWorkModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/LinkWorkModeEnum.java new file mode 100644 index 0000000..aae7515 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/LinkWorkModeEnum.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public enum LinkWorkModeEnum { + + SDR_ONLY(0), + + SDR_WITH_4G(1); + + private final int mode; + + LinkWorkModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static LinkWorkModeEnum find(int mode) { + return Arrays.stream(LinkWorkModeEnum.values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(LinkWorkModeEnum.class, mode)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/LiveviewWorldRegion.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/LiveviewWorldRegion.java new file mode 100644 index 0000000..0859f2d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/LiveviewWorldRegion.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/8 + */ +public class LiveviewWorldRegion { + + private Float bottom; + + private Float left; + + private Float right; + + private Float top; + + public LiveviewWorldRegion() { + } + + @Override + public String toString() { + return "LiveviewWorldRegion{" + + "bottom=" + bottom + + ", left=" + left + + ", right=" + right + + ", top=" + top + + '}'; + } + + public Float getBottom() { + return bottom; + } + + public LiveviewWorldRegion setBottom(Float bottom) { + this.bottom = bottom; + return this; + } + + public Float getLeft() { + return left; + } + + public LiveviewWorldRegion setLeft(Float left) { + this.left = left; + return this; + } + + public Float getRight() { + return right; + } + + public LiveviewWorldRegion setRight(Float right) { + this.right = right; + return this; + } + + public Float getTop() { + return top; + } + + public LiveviewWorldRegion setTop(Float top) { + this.top = top; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MaintainTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MaintainTypeEnum.java new file mode 100644 index 0000000..a6d8614 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MaintainTypeEnum.java @@ -0,0 +1,46 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum MaintainTypeEnum { + + NO(0), + + DRONE_BASIC(1), + + DRONE_ROUTINE(2), + + DRONE_DEEP(3), + + DOCK_ROUTINE(17), + + DOCK_DEEP(18), + ; + + private final int type; + + MaintainTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static MaintainTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(MaintainTypeEnum.class, type)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MaintenanceStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MaintenanceStateEnum.java new file mode 100644 index 0000000..8cc9c8d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MaintenanceStateEnum.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2022/11/3 + */ +public enum MaintenanceStateEnum { + + NO_NEED_TO_MAINTENANCE(0), + + NEED_MAINTENANCE(1), + + UNDER_MAINTENANCE(2), + + ; + + private final int state; + + MaintenanceStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static MaintenanceStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(MaintenanceStateEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MeasureTargetStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MeasureTargetStateEnum.java new file mode 100644 index 0000000..2cc1b8b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MeasureTargetStateEnum.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum MeasureTargetStateEnum { + + NORMAL(0), + + TOO_CLOSE(1), + + TOO_FAR(2), + + NO_SIGNAL(3), + ; + + private final int state; + + MeasureTargetStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static MeasureTargetStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(MeasureTargetStateEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MediaFileDetail.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MediaFileDetail.java new file mode 100644 index 0000000..3de4135 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/MediaFileDetail.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/17 + */ +public class MediaFileDetail { + + private Integer remainUpload; + + public MediaFileDetail() { + } + + @Override + public String toString() { + return "MediaFileDetail{" + + "remainUpload=" + remainUpload + + '}'; + } + + public Integer getRemainUpload() { + return remainUpload; + } + + public MediaFileDetail setRemainUpload(Integer remainUpload) { + this.remainUpload = remainUpload; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ModeCodeReasonEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ModeCodeReasonEnum.java new file mode 100644 index 0000000..2653d41 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ModeCodeReasonEnum.java @@ -0,0 +1,82 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/2/28 + */ +public enum ModeCodeReasonEnum { + + NO_MEANING(0), + + LOW_POWER(1), + + LOW_VOLTAGE(2), + + SERIOUS_LOW_VOLTAGE(3), + + RC_CONTROL(4), + + APP_CONTROL(5), + + RC_SIGNAL_LOST(6), + + EXTERNAL_DEVICE_TRIGGERED(7), + + GEO_ZONE(8), + + HOME_POINT_TOO_CLOSED(9), + + HOME_POINT_TOO_FAR(10), + + EXECUTING_WAYPOINT_MISSION(11), + + ARRIVE_HOME_POINT(12), + + SECOND_LIMIT_LANDING(13), + + APP_FORCIBLY_BREAK_PROTECTION(14), + + PLANES_PASSING_NEARBY(15), + + HEIGHT_CONTROL_FAILED(16), + + LOW_POWER_RTH(17), + + AP_CONTROL(18), + + HARDWARE_ABNORMAL(19), + + TOUCHDOWN_AVOIDANCE_PROTECTION(20), + + CANCEL_RTH(21), + + RTH_OBSTACLE_AVOIDANCE(22), + + RTH_STRONG_GALE(23), + + ; + + private final int reason; + + ModeCodeReasonEnum(int reason) { + this.reason = reason; + } + + @JsonValue + public int getReason() { + return reason; + } + + @JsonCreator + public static ModeCodeReasonEnum find(int reason) { + return Arrays.stream(values()).filter(reasonEnum -> reasonEnum.reason == reason).findAny() + .orElseThrow(() -> new CloudSDKException(ModeCodeReasonEnum.class, reason)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/NetworkState.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/NetworkState.java new file mode 100644 index 0000000..0667055 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/NetworkState.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/11 + */ +public class NetworkState { + + private NetworkStateTypeEnum type; + + private NetworkStateQualityEnum quality; + + private Float rate; + + public NetworkState() { + } + + @Override + public String toString() { + return "NetworkState{" + + "type=" + type + + ", quality=" + quality + + ", rate=" + rate + + '}'; + } + + public NetworkStateTypeEnum getType() { + return type; + } + + public NetworkState setType(NetworkStateTypeEnum type) { + this.type = type; + return this; + } + + public NetworkStateQualityEnum getQuality() { + return quality; + } + + public NetworkState setQuality(NetworkStateQualityEnum quality) { + this.quality = quality; + return this; + } + + public Float getRate() { + return rate; + } + + public NetworkState setRate(Float rate) { + this.rate = rate; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/NetworkStateQualityEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/NetworkStateQualityEnum.java new file mode 100644 index 0000000..988fb07 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/NetworkStateQualityEnum.java @@ -0,0 +1,46 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum NetworkStateQualityEnum { + + NO_SIGNAL(0), + + BAD(1), + + POOR(2), + + FAIR(3), + + GOOD(4), + + EXCELLENT(5), + ; + + private final int quality; + + NetworkStateQualityEnum(int quality) { + this.quality = quality; + } + + @JsonValue + public int getQuality() { + return quality; + } + + @JsonCreator + public static NetworkStateQualityEnum find(int quality) { + return Arrays.stream(values()).filter(qualityEnum -> qualityEnum.quality == quality).findAny() + .orElseThrow(() -> new CloudSDKException(NetworkStateQualityEnum.class, quality)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/NetworkStateTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/NetworkStateTypeEnum.java new file mode 100644 index 0000000..9276a43 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/NetworkStateTypeEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum NetworkStateTypeEnum { + + FOURTH_GENERATION(1), + + ETHERNET(2), + ; + + private final int type; + + NetworkStateTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static NetworkStateTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(NetworkStateTypeEnum.class, type)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ObstacleAvoidance.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ObstacleAvoidance.java new file mode 100644 index 0000000..3b4c2a8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ObstacleAvoidance.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class ObstacleAvoidance { + + private SwitchActionEnum horizon; + + private SwitchActionEnum upside; + + private SwitchActionEnum downside; + + public ObstacleAvoidance() { + } + + @Override + public String toString() { + return "ObstacleAvoidanceSet{" + + "horizon=" + horizon + + ", upside=" + upside + + ", downside=" + downside + + '}'; + } + + public SwitchActionEnum getHorizon() { + return horizon; + } + + public ObstacleAvoidance setHorizon(SwitchActionEnum horizon) { + this.horizon = horizon; + return this; + } + + public SwitchActionEnum getUpside() { + return upside; + } + + public ObstacleAvoidance setUpside(SwitchActionEnum upside) { + this.upside = upside; + return this; + } + + public SwitchActionEnum getDownside() { + return downside; + } + + public ObstacleAvoidance setDownside(SwitchActionEnum downside) { + this.downside = downside; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdCamera.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdCamera.java new file mode 100644 index 0000000..4a76c07 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdCamera.java @@ -0,0 +1,417 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.control.*; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; + +import java.util.List; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/8 + */ +public class OsdCamera { + + private CameraModeEnum cameraMode; + + private LiveviewWorldRegion liveviewWorldRegion; + + private PayloadIndex payloadIndex; + + private CameraStateEnum photoState; + + private Integer recordTime; + + private CameraStateEnum recordingState; + + private Long remainPhotoNum; + + private Integer remainRecordDuration; + + private Float zoomFactor; + + private Float irZoomFactor; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private Boolean screenSplitEnable; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private List photoStorageSettings; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private List videoStorageSettings; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private ExposureModeEnum wideExposureMode; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private CameraIsoEnum wideIso; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private ShutterSpeedEnum wideShutterSpeed; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private ExposureValueEnum wideExposureValue; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private ExposureModeEnum zoomExposureMode; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private CameraIsoEnum zoomIso; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private ShutterSpeedEnum zoomShutterSpeed; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private ExposureValueEnum zoomExposureValue; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private FocusModeEnum zoomFocusMode; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private Integer zoomFocusValue; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private Integer zoomMaxFocusValue; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private Integer zoomMinFocusValue; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private MeteringModeEnum irMeteringMode; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private IrMeteringPoint irMeteringPoint; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private IrMeteringArea irMeteringArea; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private Integer zoomCalibrateFarthestFocusValue; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private Integer zoomCalibrateNearestFocusValue; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2) + private FocusStateEnum zoomFocusState; + + public OsdCamera() { + } + + @Override + public String toString() { + return "OsdCamera{" + + "cameraMode=" + cameraMode + + ", liveviewWorldRegion=" + liveviewWorldRegion + + ", payloadIndex=" + payloadIndex + + ", photoState=" + photoState + + ", recordTime=" + recordTime + + ", recordingState=" + recordingState + + ", remainPhotoNum=" + remainPhotoNum + + ", remainRecordDuration=" + remainRecordDuration + + ", zoomFactor=" + zoomFactor + + ", irZoomFactor=" + irZoomFactor + + ", screenSplitEnable=" + screenSplitEnable + + ", photoStorageSettings=" + photoStorageSettings + + ", videoStorageSettings=" + videoStorageSettings + + ", wideExposureMode=" + wideExposureMode + + ", wideIso=" + wideIso + + ", wideShutterSpeed=" + wideShutterSpeed + + ", wideExposureValue=" + wideExposureValue + + ", zoomExposureMode=" + zoomExposureMode + + ", zoomIso=" + zoomIso + + ", zoomShutterSpeed=" + zoomShutterSpeed + + ", zoomExposureValue=" + zoomExposureValue + + ", zoomFocusMode=" + zoomFocusMode + + ", zoomFocusValue=" + zoomFocusValue + + ", zoomMaxFocusValue=" + zoomMaxFocusValue + + ", zoomMinFocusValue=" + zoomMinFocusValue + + ", irMeteringMode=" + irMeteringMode + + ", irMeteringPoint=" + irMeteringPoint + + ", irMeteringArea=" + irMeteringArea + + ", zoomCalibrateFarthestFocusValue=" + zoomCalibrateFarthestFocusValue + + ", zoomCalibrateNearestFocusValue=" + zoomCalibrateNearestFocusValue + + ", zoomFocusState=" + zoomFocusState + + '}'; + } + + public CameraModeEnum getCameraMode() { + return cameraMode; + } + + public OsdCamera setCameraMode(CameraModeEnum cameraMode) { + this.cameraMode = cameraMode; + return this; + } + + public LiveviewWorldRegion getLiveviewWorldRegion() { + return liveviewWorldRegion; + } + + public OsdCamera setLiveviewWorldRegion(LiveviewWorldRegion liveviewWorldRegion) { + this.liveviewWorldRegion = liveviewWorldRegion; + return this; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public OsdCamera setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public CameraStateEnum getPhotoState() { + return photoState; + } + + public OsdCamera setPhotoState(CameraStateEnum photoState) { + this.photoState = photoState; + return this; + } + + public Integer getRecordTime() { + return recordTime; + } + + public OsdCamera setRecordTime(Integer recordTime) { + this.recordTime = recordTime; + return this; + } + + public CameraStateEnum getRecordingState() { + return recordingState; + } + + public OsdCamera setRecordingState(CameraStateEnum recordingState) { + this.recordingState = recordingState; + return this; + } + + public Long getRemainPhotoNum() { + return remainPhotoNum; + } + + public OsdCamera setRemainPhotoNum(Long remainPhotoNum) { + this.remainPhotoNum = remainPhotoNum; + return this; + } + + public Integer getRemainRecordDuration() { + return remainRecordDuration; + } + + public OsdCamera setRemainRecordDuration(Integer remainRecordDuration) { + this.remainRecordDuration = remainRecordDuration; + return this; + } + + public Float getZoomFactor() { + return zoomFactor; + } + + public OsdCamera setZoomFactor(Float zoomFactor) { + this.zoomFactor = zoomFactor; + return this; + } + + public Float getIrZoomFactor() { + return irZoomFactor; + } + + public OsdCamera setIrZoomFactor(Float irZoomFactor) { + this.irZoomFactor = irZoomFactor; + return this; + } + + public Boolean getScreenSplitEnable() { + return screenSplitEnable; + } + + public OsdCamera setScreenSplitEnable(Boolean screenSplitEnable) { + this.screenSplitEnable = screenSplitEnable; + return this; + } + + public List getPhotoStorageSettings() { + return photoStorageSettings; + } + + public OsdCamera setPhotoStorageSettings(List photoStorageSettings) { + this.photoStorageSettings = photoStorageSettings; + return this; + } + + public List getVideoStorageSettings() { + return videoStorageSettings; + } + + public OsdCamera setVideoStorageSettings(List videoStorageSettings) { + this.videoStorageSettings = videoStorageSettings; + return this; + } + + public ExposureModeEnum getWideExposureMode() { + return wideExposureMode; + } + + public OsdCamera setWideExposureMode(ExposureModeEnum wideExposureMode) { + this.wideExposureMode = wideExposureMode; + return this; + } + + public CameraIsoEnum getWideIso() { + return wideIso; + } + + public OsdCamera setWideIso(CameraIsoEnum wideIso) { + this.wideIso = wideIso; + return this; + } + + public ShutterSpeedEnum getWideShutterSpeed() { + return wideShutterSpeed; + } + + public OsdCamera setWideShutterSpeed(ShutterSpeedEnum wideShutterSpeed) { + this.wideShutterSpeed = wideShutterSpeed; + return this; + } + + public ExposureValueEnum getWideExposureValue() { + return wideExposureValue; + } + + public OsdCamera setWideExposureValue(ExposureValueEnum wideExposureValue) { + this.wideExposureValue = wideExposureValue; + return this; + } + + public ExposureModeEnum getZoomExposureMode() { + return zoomExposureMode; + } + + public OsdCamera setZoomExposureMode(ExposureModeEnum zoomExposureMode) { + this.zoomExposureMode = zoomExposureMode; + return this; + } + + public CameraIsoEnum getZoomIso() { + return zoomIso; + } + + public OsdCamera setZoomIso(CameraIsoEnum zoomIso) { + this.zoomIso = zoomIso; + return this; + } + + public ShutterSpeedEnum getZoomShutterSpeed() { + return zoomShutterSpeed; + } + + public OsdCamera setZoomShutterSpeed(ShutterSpeedEnum zoomShutterSpeed) { + this.zoomShutterSpeed = zoomShutterSpeed; + return this; + } + + public ExposureValueEnum getZoomExposureValue() { + return zoomExposureValue; + } + + public OsdCamera setZoomExposureValue(ExposureValueEnum zoomExposureValue) { + this.zoomExposureValue = zoomExposureValue; + return this; + } + + public FocusModeEnum getZoomFocusMode() { + return zoomFocusMode; + } + + public OsdCamera setZoomFocusMode(FocusModeEnum zoomFocusMode) { + this.zoomFocusMode = zoomFocusMode; + return this; + } + + public Integer getZoomFocusValue() { + return zoomFocusValue; + } + + public OsdCamera setZoomFocusValue(Integer zoomFocusValue) { + this.zoomFocusValue = zoomFocusValue; + return this; + } + + public Integer getZoomMaxFocusValue() { + return zoomMaxFocusValue; + } + + public OsdCamera setZoomMaxFocusValue(Integer zoomMaxFocusValue) { + this.zoomMaxFocusValue = zoomMaxFocusValue; + return this; + } + + public Integer getZoomMinFocusValue() { + return zoomMinFocusValue; + } + + public OsdCamera setZoomMinFocusValue(Integer zoomMinFocusValue) { + this.zoomMinFocusValue = zoomMinFocusValue; + return this; + } + + public MeteringModeEnum getIrMeteringMode() { + return irMeteringMode; + } + + public OsdCamera setIrMeteringMode(MeteringModeEnum irMeteringMode) { + this.irMeteringMode = irMeteringMode; + return this; + } + + public IrMeteringPoint getIrMeteringPoint() { + return irMeteringPoint; + } + + public OsdCamera setIrMeteringPoint(IrMeteringPoint irMeteringPoint) { + this.irMeteringPoint = irMeteringPoint; + return this; + } + + public IrMeteringArea getIrMeteringArea() { + return irMeteringArea; + } + + public OsdCamera setIrMeteringArea(IrMeteringArea irMeteringArea) { + this.irMeteringArea = irMeteringArea; + return this; + } + + public Integer getZoomCalibrateFarthestFocusValue() { + return zoomCalibrateFarthestFocusValue; + } + + public OsdCamera setZoomCalibrateFarthestFocusValue(Integer zoomCalibrateFarthestFocusValue) { + this.zoomCalibrateFarthestFocusValue = zoomCalibrateFarthestFocusValue; + return this; + } + + public Integer getZoomCalibrateNearestFocusValue() { + return zoomCalibrateNearestFocusValue; + } + + public OsdCamera setZoomCalibrateNearestFocusValue(Integer zoomCalibrateNearestFocusValue) { + this.zoomCalibrateNearestFocusValue = zoomCalibrateNearestFocusValue; + return this; + } + + public FocusStateEnum getZoomFocusState() { + return zoomFocusState; + } + + public OsdCamera setZoomFocusState(FocusStateEnum zoomFocusState) { + this.zoomFocusState = zoomFocusState; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDock.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDock.java new file mode 100644 index 0000000..42b5e8d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDock.java @@ -0,0 +1,493 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/3 + */ +public class OsdDock { + + private NetworkState networkState; + + private Boolean droneInDock; + + private DroneChargeState droneChargeState; + + private RainfallEnum rainfall; + + private Float windSpeed; + + private Float environmentTemperature; + + private Float temperature; + + private Integer humidity; + + private Float latitude; + + private Float longitude; + + private Float height; + + private AlternateLandPoint alternateLandPoint; + + private Long firstPowerOn; + + private DockPositionState positionState; + + private Storage storage; + + private DockModeCodeEnum modeCode; + + private CoverStateEnum coverState; + + private Boolean supplementLightState; + + private Boolean emergencyStopState; + + private AirConditioner airConditioner; + + private BatteryStoreModeEnum batteryStoreMode; + + private Boolean alarmState; + + private PutterStateEnum putterState; + + private DockSubDevice subDevice; + + private Integer jobNumber; + + private Long accTime; + + private Long activationTime; + + private OsdDockMaintainStatus maintainStatus; + + private Integer electricSupplyVoltage; + + private Integer workingVoltage; + + private Integer workingCurrent; + + private BackupBattery backupBattery; + + private DroneBatteryMaintenanceInfo droneBatteryMaintenanceInfo; + + private FlighttaskStepCodeEnum flighttaskStepCode; + + private Integer flighttaskPrepareCapacity; + + private MediaFileDetail mediaFileDetail; + + private WirelessLink wirelessLink; + + private DrcStateEnum drcState; + + /** + * User experience improvement program + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private UserExperienceImprovementEnum userExperienceImprovement; + + public OsdDock() { + } + + @Override + public String toString() { + return "OsdDock{" + + "networkState=" + networkState + + ", droneInDock=" + droneInDock + + ", droneChargeState=" + droneChargeState + + ", rainfall=" + rainfall + + ", windSpeed=" + windSpeed + + ", environmentTemperature=" + environmentTemperature + + ", temperature=" + temperature + + ", humidity=" + humidity + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + ", alternateLandPoint=" + alternateLandPoint + + ", firstPowerOn=" + firstPowerOn + + ", positionState=" + positionState + + ", storage=" + storage + + ", modeCode=" + modeCode + + ", coverState=" + coverState + + ", supplementLightState=" + supplementLightState + + ", emergencyStopState=" + emergencyStopState + + ", airConditioner=" + airConditioner + + ", batteryStoreMode=" + batteryStoreMode + + ", alarmState=" + alarmState + + ", putterState=" + putterState + + ", subDevice=" + subDevice + + ", jobNumber=" + jobNumber + + ", accTime=" + accTime + + ", activationTime=" + activationTime + + ", maintainStatus=" + maintainStatus + + ", electricSupplyVoltage=" + electricSupplyVoltage + + ", workingVoltage=" + workingVoltage + + ", workingCurrent=" + workingCurrent + + ", backupBattery=" + backupBattery + + ", droneBatteryMaintenanceInfo=" + droneBatteryMaintenanceInfo + + ", flighttaskStepCode=" + flighttaskStepCode + + ", flighttaskPrepareCapacity=" + flighttaskPrepareCapacity + + ", mediaFileDetail=" + mediaFileDetail + + ", wirelessLink=" + wirelessLink + + ", drcState=" + drcState + + ", userExperienceImprovement=" + userExperienceImprovement + + '}'; + } + + public NetworkState getNetworkState() { + return networkState; + } + + public OsdDock setNetworkState(NetworkState networkState) { + this.networkState = networkState; + return this; + } + + public Boolean getDroneInDock() { + return droneInDock; + } + + public OsdDock setDroneInDock(Boolean droneInDock) { + this.droneInDock = droneInDock; + return this; + } + + public DroneChargeState getDroneChargeState() { + return droneChargeState; + } + + public OsdDock setDroneChargeState(DroneChargeState droneChargeState) { + this.droneChargeState = droneChargeState; + return this; + } + + public RainfallEnum getRainfall() { + return rainfall; + } + + public OsdDock setRainfall(RainfallEnum rainfall) { + this.rainfall = rainfall; + return this; + } + + public Float getWindSpeed() { + return windSpeed; + } + + public OsdDock setWindSpeed(Float windSpeed) { + this.windSpeed = windSpeed; + return this; + } + + public Float getEnvironmentTemperature() { + return environmentTemperature; + } + + public OsdDock setEnvironmentTemperature(Float environmentTemperature) { + this.environmentTemperature = environmentTemperature; + return this; + } + + public Float getTemperature() { + return temperature; + } + + public OsdDock setTemperature(Float temperature) { + this.temperature = temperature; + return this; + } + + public Integer getHumidity() { + return humidity; + } + + public OsdDock setHumidity(Integer humidity) { + this.humidity = humidity; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public OsdDock setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public OsdDock setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public OsdDock setHeight(Float height) { + this.height = height; + return this; + } + + public AlternateLandPoint getAlternateLandPoint() { + return alternateLandPoint; + } + + public OsdDock setAlternateLandPoint(AlternateLandPoint alternateLandPoint) { + this.alternateLandPoint = alternateLandPoint; + return this; + } + + public Long getFirstPowerOn() { + return firstPowerOn; + } + + public OsdDock setFirstPowerOn(Long firstPowerOn) { + this.firstPowerOn = firstPowerOn; + return this; + } + + public DockPositionState getPositionState() { + return positionState; + } + + public OsdDock setPositionState(DockPositionState positionState) { + this.positionState = positionState; + return this; + } + + public Storage getStorage() { + return storage; + } + + public OsdDock setStorage(Storage storage) { + this.storage = storage; + return this; + } + + public DockModeCodeEnum getModeCode() { + return modeCode; + } + + public OsdDock setModeCode(DockModeCodeEnum modeCode) { + this.modeCode = modeCode; + return this; + } + + public CoverStateEnum getCoverState() { + return coverState; + } + + public OsdDock setCoverState(CoverStateEnum coverState) { + this.coverState = coverState; + return this; + } + + public Boolean getSupplementLightState() { + return supplementLightState; + } + + public OsdDock setSupplementLightState(Boolean supplementLightState) { + this.supplementLightState = supplementLightState; + return this; + } + + public Boolean getEmergencyStopState() { + return emergencyStopState; + } + + public OsdDock setEmergencyStopState(Boolean emergencyStopState) { + this.emergencyStopState = emergencyStopState; + return this; + } + + public AirConditioner getAirConditioner() { + return airConditioner; + } + + public OsdDock setAirConditioner(AirConditioner airConditioner) { + this.airConditioner = airConditioner; + return this; + } + + public BatteryStoreModeEnum getBatteryStoreMode() { + return batteryStoreMode; + } + + public OsdDock setBatteryStoreMode(BatteryStoreModeEnum batteryStoreMode) { + this.batteryStoreMode = batteryStoreMode; + return this; + } + + public Boolean getAlarmState() { + return alarmState; + } + + public OsdDock setAlarmState(Boolean alarmState) { + this.alarmState = alarmState; + return this; + } + + public PutterStateEnum getPutterState() { + return putterState; + } + + public OsdDock setPutterState(PutterStateEnum putterState) { + this.putterState = putterState; + return this; + } + + public DockSubDevice getSubDevice() { + return subDevice; + } + + public OsdDock setSubDevice(DockSubDevice subDevice) { + this.subDevice = subDevice; + return this; + } + + public Integer getJobNumber() { + return jobNumber; + } + + public OsdDock setJobNumber(Integer jobNumber) { + this.jobNumber = jobNumber; + return this; + } + + public Long getAccTime() { + return accTime; + } + + public OsdDock setAccTime(Long accTime) { + this.accTime = accTime; + return this; + } + + public Long getActivationTime() { + return activationTime; + } + + public OsdDock setActivationTime(Long activationTime) { + this.activationTime = activationTime; + return this; + } + + public OsdDockMaintainStatus getMaintainStatus() { + return maintainStatus; + } + + public OsdDock setMaintainStatus(OsdDockMaintainStatus maintainStatus) { + this.maintainStatus = maintainStatus; + return this; + } + + public Integer getElectricSupplyVoltage() { + return electricSupplyVoltage; + } + + public OsdDock setElectricSupplyVoltage(Integer electricSupplyVoltage) { + this.electricSupplyVoltage = electricSupplyVoltage; + return this; + } + + public Integer getWorkingVoltage() { + return workingVoltage; + } + + public OsdDock setWorkingVoltage(Integer workingVoltage) { + this.workingVoltage = workingVoltage; + return this; + } + + public Integer getWorkingCurrent() { + return workingCurrent; + } + + public OsdDock setWorkingCurrent(Integer workingCurrent) { + this.workingCurrent = workingCurrent; + return this; + } + + public BackupBattery getBackupBattery() { + return backupBattery; + } + + public OsdDock setBackupBattery(BackupBattery backupBattery) { + this.backupBattery = backupBattery; + return this; + } + + public DroneBatteryMaintenanceInfo getDroneBatteryMaintenanceInfo() { + return droneBatteryMaintenanceInfo; + } + + public OsdDock setDroneBatteryMaintenanceInfo(DroneBatteryMaintenanceInfo droneBatteryMaintenanceInfo) { + this.droneBatteryMaintenanceInfo = droneBatteryMaintenanceInfo; + return this; + } + + public FlighttaskStepCodeEnum getFlighttaskStepCode() { + return flighttaskStepCode; + } + + public OsdDock setFlighttaskStepCode(FlighttaskStepCodeEnum flighttaskStepCode) { + this.flighttaskStepCode = flighttaskStepCode; + return this; + } + + public Integer getFlighttaskPrepareCapacity() { + return flighttaskPrepareCapacity; + } + + public OsdDock setFlighttaskPrepareCapacity(Integer flighttaskPrepareCapacity) { + this.flighttaskPrepareCapacity = flighttaskPrepareCapacity; + return this; + } + + public MediaFileDetail getMediaFileDetail() { + return mediaFileDetail; + } + + public OsdDock setMediaFileDetail(MediaFileDetail mediaFileDetail) { + this.mediaFileDetail = mediaFileDetail; + return this; + } + + public WirelessLink getWirelessLink() { + return wirelessLink; + } + + public OsdDock setWirelessLink(WirelessLink wirelessLink) { + this.wirelessLink = wirelessLink; + return this; + } + + public DrcStateEnum getDrcState() { + return drcState; + } + + public OsdDock setDrcState(DrcStateEnum drcState) { + this.drcState = drcState; + return this; + } + + public UserExperienceImprovementEnum getUserExperienceImprovement() { + return userExperienceImprovement; + } + + public OsdDock setUserExperienceImprovement(UserExperienceImprovementEnum userExperienceImprovement) { + this.userExperienceImprovement = userExperienceImprovement; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDockDrone.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDockDrone.java new file mode 100644 index 0000000..2d059f6 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDockDrone.java @@ -0,0 +1,472 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class OsdDockDrone { + + private Float attitudeHead; + + private Double attitudePitch; + + private Double attitudeRoll; + + private Float elevation; + + private DroneBattery battery; + + private String firmwareVersion; + + private GearEnum gear; + + private Float height; + + private Float homeDistance; + + private Float horizontalSpeed; + + private Float latitude; + + private Float longitude; + + private DroneModeCodeEnum modeCode; + + private Double totalFlightDistance; + + private Float totalFlightTime; + + private Float verticalSpeed; + + private WindDirectionEnum windDirection; + + private Float windSpeed; + + private DronePositionState positionState; + + @JsonProperty(PayloadModelConst.PAYLOAD_KEY) + private List payloads; + + private Storage storage; + + private SwitchActionEnum nightLightsState; + + private Integer heightLimit; + + private DockDistanceLimitStatus distanceLimitStatus; + + private ObstacleAvoidance obstacleAvoidance; + + private Long activationTime; + + private List cameras; + + private RcLostActionEnum rcLostAction; + + private Integer rthAltitude; + + private Integer totalFlightSorties; + + @CloudSDKVersion(deprecated = CloudSDKVersionEnum.V1_0_0) + private ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost; + + private String country; + + private Boolean ridState; + + @JsonProperty("is_near_area_limit") + private Boolean nearAreaLimit; + + @JsonProperty("is_near_height_limit") + private Boolean nearHeightLimit; + + private OsdDroneMaintainStatus maintainStatus; + + private String trackId; + + public OsdDockDrone() { + } + + @Override + public String toString() { + return "OsdDockDrone{" + + "attitudeHead=" + attitudeHead + + ", attitudePitch=" + attitudePitch + + ", attitudeRoll=" + attitudeRoll + + ", elevation=" + elevation + + ", battery=" + battery + + ", firmwareVersion='" + firmwareVersion + '\'' + + ", gear=" + gear + + ", height=" + height + + ", homeDistance=" + homeDistance + + ", horizontalSpeed=" + horizontalSpeed + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", modeCode=" + modeCode + + ", totalFlightDistance=" + totalFlightDistance + + ", totalFlightTime=" + totalFlightTime + + ", verticalSpeed=" + verticalSpeed + + ", windDirection=" + windDirection + + ", windSpeed=" + windSpeed + + ", positionState=" + positionState + + ", payloads=" + payloads + + ", storage=" + storage + + ", nightLightsState=" + nightLightsState + + ", heightLimit=" + heightLimit + + ", distanceLimitStatus=" + distanceLimitStatus + + ", obstacleAvoidance=" + obstacleAvoidance + + ", activationTime=" + activationTime + + ", cameras=" + cameras + + ", rcLostAction=" + rcLostAction + + ", rthAltitude=" + rthAltitude + + ", totalFlightSorties=" + totalFlightSorties + + ", exitWaylineWhenRcLost=" + exitWaylineWhenRcLost + + ", country='" + country + '\'' + + ", ridState=" + ridState + + ", nearAreaLimit=" + nearAreaLimit + + ", nearHeightLimit=" + nearHeightLimit + + ", maintainStatus=" + maintainStatus + + ", trackId='" + trackId + '\'' + + '}'; + } + + public Float getAttitudeHead() { + return attitudeHead; + } + + public OsdDockDrone setAttitudeHead(Float attitudeHead) { + this.attitudeHead = attitudeHead; + return this; + } + + public Double getAttitudePitch() { + return attitudePitch; + } + + public OsdDockDrone setAttitudePitch(Double attitudePitch) { + this.attitudePitch = attitudePitch; + return this; + } + + public Double getAttitudeRoll() { + return attitudeRoll; + } + + public OsdDockDrone setAttitudeRoll(Double attitudeRoll) { + this.attitudeRoll = attitudeRoll; + return this; + } + + public Float getElevation() { + return elevation; + } + + public OsdDockDrone setElevation(Float elevation) { + this.elevation = elevation; + return this; + } + + public DroneBattery getBattery() { + return battery; + } + + public OsdDockDrone setBattery(DroneBattery battery) { + this.battery = battery; + return this; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public OsdDockDrone setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } + + public GearEnum getGear() { + return gear; + } + + public OsdDockDrone setGear(GearEnum gear) { + this.gear = gear; + return this; + } + + public Float getHeight() { + return height; + } + + public OsdDockDrone setHeight(Float height) { + this.height = height; + return this; + } + + public Float getHomeDistance() { + return homeDistance; + } + + public OsdDockDrone setHomeDistance(Float homeDistance) { + this.homeDistance = homeDistance; + return this; + } + + public Float getHorizontalSpeed() { + return horizontalSpeed; + } + + public OsdDockDrone setHorizontalSpeed(Float horizontalSpeed) { + this.horizontalSpeed = horizontalSpeed; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public OsdDockDrone setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public OsdDockDrone setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public DroneModeCodeEnum getModeCode() { + return modeCode; + } + + public OsdDockDrone setModeCode(DroneModeCodeEnum modeCode) { + this.modeCode = modeCode; + return this; + } + + public Double getTotalFlightDistance() { + return totalFlightDistance; + } + + public OsdDockDrone setTotalFlightDistance(Double totalFlightDistance) { + this.totalFlightDistance = totalFlightDistance; + return this; + } + + public Float getTotalFlightTime() { + return totalFlightTime; + } + + public OsdDockDrone setTotalFlightTime(Float totalFlightTime) { + this.totalFlightTime = totalFlightTime; + return this; + } + + public Float getVerticalSpeed() { + return verticalSpeed; + } + + public OsdDockDrone setVerticalSpeed(Float verticalSpeed) { + this.verticalSpeed = verticalSpeed; + return this; + } + + public WindDirectionEnum getWindDirection() { + return windDirection; + } + + public OsdDockDrone setWindDirection(WindDirectionEnum windDirection) { + this.windDirection = windDirection; + return this; + } + + public Float getWindSpeed() { + return windSpeed; + } + + public OsdDockDrone setWindSpeed(Float windSpeed) { + this.windSpeed = windSpeed; + return this; + } + + public DronePositionState getPositionState() { + return positionState; + } + + public OsdDockDrone setPositionState(DronePositionState positionState) { + this.positionState = positionState; + return this; + } + + public List getPayloads() { + return payloads; + } + + public OsdDockDrone setPayloads(List payloads) { + this.payloads = payloads; + return this; + } + + public Storage getStorage() { + return storage; + } + + public OsdDockDrone setStorage(Storage storage) { + this.storage = storage; + return this; + } + + public SwitchActionEnum getNightLightsState() { + return nightLightsState; + } + + public OsdDockDrone setNightLightsState(SwitchActionEnum nightLightsState) { + this.nightLightsState = nightLightsState; + return this; + } + + public Integer getHeightLimit() { + return heightLimit; + } + + public OsdDockDrone setHeightLimit(Integer heightLimit) { + this.heightLimit = heightLimit; + return this; + } + + public DockDistanceLimitStatus getDistanceLimitStatus() { + return distanceLimitStatus; + } + + public OsdDockDrone setDistanceLimitStatus(DockDistanceLimitStatus distanceLimitStatus) { + this.distanceLimitStatus = distanceLimitStatus; + return this; + } + + public ObstacleAvoidance getObstacleAvoidance() { + return obstacleAvoidance; + } + + public OsdDockDrone setObstacleAvoidance(ObstacleAvoidance obstacleAvoidance) { + this.obstacleAvoidance = obstacleAvoidance; + return this; + } + + public Long getActivationTime() { + return activationTime; + } + + public OsdDockDrone setActivationTime(Long activationTime) { + this.activationTime = activationTime; + return this; + } + + public List getCameras() { + return cameras; + } + + public OsdDockDrone setCameras(List cameras) { + this.cameras = cameras; + return this; + } + + public RcLostActionEnum getRcLostAction() { + return rcLostAction; + } + + public OsdDockDrone setRcLostAction(RcLostActionEnum rcLostAction) { + this.rcLostAction = rcLostAction; + return this; + } + + public Integer getRthAltitude() { + return rthAltitude; + } + + public OsdDockDrone setRthAltitude(Integer rthAltitude) { + this.rthAltitude = rthAltitude; + return this; + } + + public Integer getTotalFlightSorties() { + return totalFlightSorties; + } + + public OsdDockDrone setTotalFlightSorties(Integer totalFlightSorties) { + this.totalFlightSorties = totalFlightSorties; + return this; + } + + public ExitWaylineWhenRcLostEnum getExitWaylineWhenRcLost() { + return exitWaylineWhenRcLost; + } + + public OsdDockDrone setExitWaylineWhenRcLost(ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost) { + this.exitWaylineWhenRcLost = exitWaylineWhenRcLost; + return this; + } + + public String getCountry() { + return country; + } + + public OsdDockDrone setCountry(String country) { + this.country = country; + return this; + } + + public Boolean getRidState() { + return ridState; + } + + public OsdDockDrone setRidState(Boolean ridState) { + this.ridState = ridState; + return this; + } + + public Boolean getNearAreaLimit() { + return nearAreaLimit; + } + + public OsdDockDrone setNearAreaLimit(Boolean nearAreaLimit) { + this.nearAreaLimit = nearAreaLimit; + return this; + } + + public Boolean getNearHeightLimit() { + return nearHeightLimit; + } + + public OsdDockDrone setNearHeightLimit(Boolean nearHeightLimit) { + this.nearHeightLimit = nearHeightLimit; + return this; + } + + public OsdDroneMaintainStatus getMaintainStatus() { + return maintainStatus; + } + + public OsdDockDrone setMaintainStatus(OsdDroneMaintainStatus maintainStatus) { + this.maintainStatus = maintainStatus; + return this; + } + + public String getTrackId() { + return trackId; + } + + public OsdDockDrone setTrackId(String trackId) { + this.trackId = trackId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDockMaintainStatus.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDockMaintainStatus.java new file mode 100644 index 0000000..d4e9659 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDockMaintainStatus.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class OsdDockMaintainStatus { + + private List maintainStatusArray; + + public OsdDockMaintainStatus() { + } + + @Override + public String toString() { + return "OsdDroneMaintainStatus{" + + "maintainStatusArray=" + maintainStatusArray + + '}'; + } + + public List getMaintainStatusArray() { + return maintainStatusArray; + } + + public OsdDockMaintainStatus setMaintainStatusArray(List maintainStatusArray) { + this.maintainStatusArray = maintainStatusArray; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDroneMaintainStatus.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDroneMaintainStatus.java new file mode 100644 index 0000000..12136e3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdDroneMaintainStatus.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class OsdDroneMaintainStatus { + + private List maintainStatusArray; + + public OsdDroneMaintainStatus() { + } + + @Override + public String toString() { + return "OsdDroneMaintainStatus{" + + "maintainStatusArray=" + maintainStatusArray + + '}'; + } + + public List getMaintainStatusArray() { + return maintainStatusArray; + } + + public OsdDroneMaintainStatus setMaintainStatusArray(List maintainStatusArray) { + this.maintainStatusArray = maintainStatusArray; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdRcDrone.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdRcDrone.java new file mode 100644 index 0000000..a358ff9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdRcDrone.java @@ -0,0 +1,311 @@ +package org.dromara.common.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class OsdRcDrone { + + private Float attitudeHead; + + private Double attitudePitch; + + private Double attitudeRoll; + + private Float elevation; + + private DroneBattery battery; + + private String firmwareVersion; + + private GearEnum gear; + + private Float height; + + private Float homeDistance; + + private Float horizontalSpeed; + + private Float latitude; + + private Float longitude; + + private DroneModeCodeEnum modeCode; + + private Double totalFlightDistance; + + private Float totalFlightTime; + + private Float verticalSpeed; + + private WindDirectionEnum windDirection; + + private Float windSpeed; + + private DronePositionState positionState; + + @JsonProperty(PayloadModelConst.PAYLOAD_KEY) + private List payloads; + + private Storage storage; + + private Integer heightLimit; + + private RcDistanceLimitStatus distanceLimitStatus; + + private String trackId; + + public OsdRcDrone() { + } + + @Override + public String toString() { + return "OsdRcDrone{" + + "attitudeHead=" + attitudeHead + + ", attitudePitch=" + attitudePitch + + ", attitudeRoll=" + attitudeRoll + + ", elevation=" + elevation + + ", battery=" + battery + + ", firmwareVersion='" + firmwareVersion + '\'' + + ", gear=" + gear + + ", height=" + height + + ", homeDistance=" + homeDistance + + ", horizontalSpeed=" + horizontalSpeed + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", modeCode=" + modeCode + + ", totalFlightDistance=" + totalFlightDistance + + ", totalFlightTime=" + totalFlightTime + + ", verticalSpeed=" + verticalSpeed + + ", windDirection=" + windDirection + + ", windSpeed=" + windSpeed + + ", positionState=" + positionState + + ", payloads=" + payloads + + ", storage=" + storage + + ", heightLimit=" + heightLimit + + ", distanceLimitStatus=" + distanceLimitStatus + + ", trackId='" + trackId + '\'' + + '}'; + } + + public Float getAttitudeHead() { + return attitudeHead; + } + + public OsdRcDrone setAttitudeHead(Float attitudeHead) { + this.attitudeHead = attitudeHead; + return this; + } + + public Double getAttitudePitch() { + return attitudePitch; + } + + public OsdRcDrone setAttitudePitch(Double attitudePitch) { + this.attitudePitch = attitudePitch; + return this; + } + + public Double getAttitudeRoll() { + return attitudeRoll; + } + + public OsdRcDrone setAttitudeRoll(Double attitudeRoll) { + this.attitudeRoll = attitudeRoll; + return this; + } + + public Float getElevation() { + return elevation; + } + + public OsdRcDrone setElevation(Float elevation) { + this.elevation = elevation; + return this; + } + + public DroneBattery getBattery() { + return battery; + } + + public OsdRcDrone setBattery(DroneBattery battery) { + this.battery = battery; + return this; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public OsdRcDrone setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } + + public GearEnum getGear() { + return gear; + } + + public OsdRcDrone setGear(GearEnum gear) { + this.gear = gear; + return this; + } + + public Float getHeight() { + return height; + } + + public OsdRcDrone setHeight(Float height) { + this.height = height; + return this; + } + + public Float getHomeDistance() { + return homeDistance; + } + + public OsdRcDrone setHomeDistance(Float homeDistance) { + this.homeDistance = homeDistance; + return this; + } + + public Float getHorizontalSpeed() { + return horizontalSpeed; + } + + public OsdRcDrone setHorizontalSpeed(Float horizontalSpeed) { + this.horizontalSpeed = horizontalSpeed; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public OsdRcDrone setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public OsdRcDrone setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public DroneModeCodeEnum getModeCode() { + return modeCode; + } + + public OsdRcDrone setModeCode(DroneModeCodeEnum modeCode) { + this.modeCode = modeCode; + return this; + } + + public Double getTotalFlightDistance() { + return totalFlightDistance; + } + + public OsdRcDrone setTotalFlightDistance(Double totalFlightDistance) { + this.totalFlightDistance = totalFlightDistance; + return this; + } + + public Float getTotalFlightTime() { + return totalFlightTime; + } + + public OsdRcDrone setTotalFlightTime(Float totalFlightTime) { + this.totalFlightTime = totalFlightTime; + return this; + } + + public Float getVerticalSpeed() { + return verticalSpeed; + } + + public OsdRcDrone setVerticalSpeed(Float verticalSpeed) { + this.verticalSpeed = verticalSpeed; + return this; + } + + public WindDirectionEnum getWindDirection() { + return windDirection; + } + + public OsdRcDrone setWindDirection(WindDirectionEnum windDirection) { + this.windDirection = windDirection; + return this; + } + + public Float getWindSpeed() { + return windSpeed; + } + + public OsdRcDrone setWindSpeed(Float windSpeed) { + this.windSpeed = windSpeed; + return this; + } + + public DronePositionState getPositionState() { + return positionState; + } + + public OsdRcDrone setPositionState(DronePositionState positionState) { + this.positionState = positionState; + return this; + } + + public List getPayloads() { + return payloads; + } + + public OsdRcDrone setPayloads(List payloads) { + this.payloads = payloads; + return this; + } + + public Storage getStorage() { + return storage; + } + + public OsdRcDrone setStorage(Storage storage) { + this.storage = storage; + return this; + } + + public Integer getHeightLimit() { + return heightLimit; + } + + public OsdRcDrone setHeightLimit(Integer heightLimit) { + this.heightLimit = heightLimit; + return this; + } + + public RcDistanceLimitStatus getDistanceLimitStatus() { + return distanceLimitStatus; + } + + public OsdRcDrone setDistanceLimitStatus(RcDistanceLimitStatus distanceLimitStatus) { + this.distanceLimitStatus = distanceLimitStatus; + return this; + } + + public String getTrackId() { + return trackId; + } + + public OsdRcDrone setTrackId(String trackId) { + this.trackId = trackId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdRemoteControl.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdRemoteControl.java new file mode 100644 index 0000000..5fe950e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/OsdRemoteControl.java @@ -0,0 +1,78 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class OsdRemoteControl { + + private Float latitude; + + private Float longitude; + + private Float height; + + private Integer capacityPercent; + + private WirelessLink wirelessLink; + + public OsdRemoteControl() { + } + + @Override + public String toString() { + return "OsdRemoteControl{" + + "latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + ", capacityPercent=" + capacityPercent + + ", wirelessLink=" + wirelessLink + + '}'; + } + + public Float getLatitude() { + return latitude; + } + + public OsdRemoteControl setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public OsdRemoteControl setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public OsdRemoteControl setHeight(Float height) { + this.height = height; + return this; + } + + public Integer getCapacityPercent() { + return capacityPercent; + } + + public OsdRemoteControl setCapacityPercent(Integer capacityPercent) { + this.capacityPercent = capacityPercent; + return this; + } + + public WirelessLink getWirelessLink() { + return wirelessLink; + } + + public OsdRemoteControl setWirelessLink(WirelessLink wirelessLink) { + this.wirelessLink = wirelessLink; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadFirmwareVersion.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadFirmwareVersion.java new file mode 100644 index 0000000..ab15bee --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadFirmwareVersion.java @@ -0,0 +1,53 @@ +package org.dromara.common.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonCreator; + +import java.util.Map; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/28 + */ +public class PayloadFirmwareVersion { + + private PayloadPositionEnum position; + + private String firmwareVersion; + + public PayloadFirmwareVersion() { + } + + @JsonCreator + public PayloadFirmwareVersion(Map map) { + Map.Entry entry = (Map.Entry) map.entrySet().toArray()[0]; + this.position = PayloadPositionEnum.find(Integer.parseInt(entry.getKey().split("-")[1])); + this.firmwareVersion = ((Map) entry.getValue()).values().toArray(String[]::new)[0]; + } + + @Override + public String toString() { + return "PayloadFirmwareVersion{" + + "position=" + position + + ", firmwareVersion='" + firmwareVersion + '\'' + + '}'; + } + + public PayloadPositionEnum getPosition() { + return position; + } + + public PayloadFirmwareVersion setPosition(PayloadPositionEnum position) { + this.position = position; + return this; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public PayloadFirmwareVersion setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadIndex.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadIndex.java new file mode 100644 index 0000000..16154aa --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadIndex.java @@ -0,0 +1,75 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.constraints.NotNull; + +import java.util.Arrays; +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public class PayloadIndex { + + @NotNull + private DeviceTypeEnum type; + + @NotNull + private DeviceSubTypeEnum subType; + + @NotNull + private PayloadPositionEnum position; + + public PayloadIndex() { + } + + @JsonCreator + public PayloadIndex(String payloadIndex) { + Objects.requireNonNull(payloadIndex); + int[] payloadIndexArr = Arrays.stream(payloadIndex.split("-")).mapToInt(Integer::parseInt).toArray(); + if (payloadIndexArr.length != 3) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + this.type = DeviceTypeEnum.find(payloadIndexArr[0]); + this.subType = DeviceSubTypeEnum.find(payloadIndexArr[1]); + this.position = PayloadPositionEnum.find(payloadIndexArr[2]); + } + + @Override + @JsonValue + public String toString() { + return String.format("%s-%s-%s", type.getType(), subType.getSubType(), position.getPosition()); + } + + public DeviceTypeEnum getType() { + return type; + } + + public PayloadIndex setType(DeviceTypeEnum type) { + this.type = type; + return this; + } + + public DeviceSubTypeEnum getSubType() { + return subType; + } + + public PayloadIndex setSubType(DeviceSubTypeEnum subType) { + this.subType = subType; + return this; + } + + public PayloadPositionEnum getPosition() { + return position; + } + + public PayloadIndex setPosition(PayloadPositionEnum position) { + this.position = position; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadModelConst.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadModelConst.java new file mode 100644 index 0000000..69d3be6 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadModelConst.java @@ -0,0 +1,35 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/29 + */ +public class PayloadModelConst { + + private PayloadModelConst() { + } + + public static final String PAYLOAD_KEY = "payload"; + + public static Set getAllModelWithPosition() { + Set position = Arrays.stream(PayloadPositionEnum.values()).map(PayloadPositionEnum::getPosition) + .map(String::valueOf).collect(Collectors.toSet()); + return Arrays.stream(DeviceEnum.values()).filter(device -> DeviceDomainEnum.PAYLOAD == device.getDomain()) + .map(Enum::name).map(name -> name.replace("_CAMERA", "")) + .flatMap(m -> position.stream().map(p -> m.concat("-").concat(p))).collect(Collectors.toSet()); + } + + public static Set getAllIndexWithPosition() { + Set position = Arrays.stream(PayloadPositionEnum.values()).map(PayloadPositionEnum::getPosition) + .map(String::valueOf).collect(Collectors.toSet()); + return Arrays.stream(DeviceEnum.values()).filter(device -> DeviceDomainEnum.PAYLOAD == device.getDomain()) + .map(device -> String.format("%d-%d", device.getType().getType(), device.getSubType().getSubType())) + .flatMap(m -> position.stream().map(p -> m.concat("-").concat(p))).collect(Collectors.toSet()); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadPositionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadPositionEnum.java new file mode 100644 index 0000000..14cd95e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PayloadPositionEnum.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/25 + */ +public enum PayloadPositionEnum { + + FRONT_LEFT(0), + + FRONT_RIGHT(1), + + TOP(2), + + FPV(7); + + private final int position; + + PayloadPositionEnum(int position) { + this.position = position; + } + + @JsonValue + public int getPosition() { + return position; + } + + @JsonCreator + public static PayloadPositionEnum find(int position) { + return Arrays.stream(values()).filter(positionEnum -> positionEnum.position == position).findAny() + .orElseThrow(() -> new CloudSDKException(PayloadPositionEnum.class, position)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PositionFixedEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PositionFixedEnum.java new file mode 100644 index 0000000..471e103 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PositionFixedEnum.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum PositionFixedEnum { + + NOT_START(0), + + FIXING(1), + + SUCCESSFUL(2), + + FAILED(3), + ; + + private final int fixed; + + PositionFixedEnum(int fixed) { + this.fixed = fixed; + } + + @JsonValue + public int getFixed() { + return fixed; + } + + @JsonCreator + public static PositionFixedEnum find(int fixed) { + return Arrays.stream(values()).filter(fixedEnum -> fixedEnum.fixed == fixed).findAny() + .orElseThrow(() -> new CloudSDKException(PositionFixedEnum.class, fixed)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PutterStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PutterStateEnum.java new file mode 100644 index 0000000..b82926f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/PutterStateEnum.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum PutterStateEnum { + + CLOSED(0), + + OPENED(1), + + HALF_OPEN(2), + + ABNORMAL(3), + ; + + private final int state; + + PutterStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static PutterStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(PutterStateEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RainfallEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RainfallEnum.java new file mode 100644 index 0000000..c97c596 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RainfallEnum.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum RainfallEnum { + + NO(0), + + LIGHT(1), + + MODERATE(2), + + HEAVY(3), + ; + + private final int rain; + + RainfallEnum(int rain) { + this.rain = rain; + } + + @JsonValue + public int getRain() { + return rain; + } + + @JsonCreator + public static RainfallEnum find(int rain) { + return Arrays.stream(values()).filter(rainEnum -> rainEnum.rain == rain).findAny() + .orElseThrow(() -> new CloudSDKException(RainfallEnum.class, rain)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcDistanceLimitStatus.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcDistanceLimitStatus.java new file mode 100644 index 0000000..e794ae6 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcDistanceLimitStatus.java @@ -0,0 +1,43 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * The state of the drone's limited distance + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class RcDistanceLimitStatus { + + private Integer state; + + private Integer distanceLimit; + + public RcDistanceLimitStatus() { + } + + @Override + public String toString() { + return "RcDistanceLimitStatusSet{" + + "state=" + state + + ", distanceLimit=" + distanceLimit + + '}'; + } + + public Integer getState() { + return state; + } + + public RcDistanceLimitStatus setState(Integer state) { + this.state = state; + return this; + } + + public Integer getDistanceLimit() { + return distanceLimit; + } + + public RcDistanceLimitStatus setDistanceLimit(Integer distanceLimit) { + this.distanceLimit = distanceLimit; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcDroneControlSource.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcDroneControlSource.java new file mode 100644 index 0000000..8c5490d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcDroneControlSource.java @@ -0,0 +1,92 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class RcDroneControlSource { + + private ControlSourceEnum controlSource; + + private Float homeLatitude; + + private Float homeLongitude; + + private Integer lowBatteryWarningThreshold; + + private Integer seriousLowBatteryWarningThreshold; + + private List payloads; + + public RcDroneControlSource() { + } + + @Override + public String toString() { + return "RcDroneControlSource{" + + "controlSource=" + controlSource + + ", homeLatitude=" + homeLatitude + + ", homeLongitude=" + homeLongitude + + ", lowBatteryWarningThreshold=" + lowBatteryWarningThreshold + + ", seriousLowBatteryWarningThreshold=" + seriousLowBatteryWarningThreshold + + ", payloads=" + payloads + + '}'; + } + + public ControlSourceEnum getControlSource() { + return controlSource; + } + + public RcDroneControlSource setControlSource(ControlSourceEnum controlSource) { + this.controlSource = controlSource; + return this; + } + + public Float getHomeLatitude() { + return homeLatitude; + } + + public RcDroneControlSource setHomeLatitude(Float homeLatitude) { + this.homeLatitude = homeLatitude; + return this; + } + + public Float getHomeLongitude() { + return homeLongitude; + } + + public RcDroneControlSource setHomeLongitude(Float homeLongitude) { + this.homeLongitude = homeLongitude; + return this; + } + + public Integer getLowBatteryWarningThreshold() { + return lowBatteryWarningThreshold; + } + + public RcDroneControlSource setLowBatteryWarningThreshold(Integer lowBatteryWarningThreshold) { + this.lowBatteryWarningThreshold = lowBatteryWarningThreshold; + return this; + } + + public Integer getSeriousLowBatteryWarningThreshold() { + return seriousLowBatteryWarningThreshold; + } + + public RcDroneControlSource setSeriousLowBatteryWarningThreshold(Integer seriousLowBatteryWarningThreshold) { + this.seriousLowBatteryWarningThreshold = seriousLowBatteryWarningThreshold; + return this; + } + + public List getPayloads() { + return payloads; + } + + public RcDroneControlSource setPayloads(List payloads) { + this.payloads = payloads; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcDronePayload.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcDronePayload.java new file mode 100644 index 0000000..ed0db2b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcDronePayload.java @@ -0,0 +1,140 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/6 + */ +public class RcDronePayload { + + private PayloadIndex payloadIndex; + + private Float gimbalPitch; + + private Float gimbalRoll; + + private Float gimbalYaw; + + private Float measureTargetAltitude; + + private Float measureTargetDistance; + + private Float measureTargetLatitude; + + private Float measureTargetLongitude; + + private MeasureTargetStateEnum measureTargetErrorState; + + private List smartTrackPoint; + + public RcDronePayload() { + } + + @Override + public String toString() { + return "RcDronePayload{" + + "payloadIndex=" + payloadIndex + + ", gimbalPitch=" + gimbalPitch + + ", gimbalRoll=" + gimbalRoll + + ", gimbalYaw=" + gimbalYaw + + ", measureTargetAltitude=" + measureTargetAltitude + + ", measureTargetDistance=" + measureTargetDistance + + ", measureTargetLatitude=" + measureTargetLatitude + + ", measureTargetLongitude=" + measureTargetLongitude + + ", measureTargetErrorState=" + measureTargetErrorState + + ", smartTrackPoint=" + smartTrackPoint + + '}'; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public RcDronePayload setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public Float getGimbalPitch() { + return gimbalPitch; + } + + public RcDronePayload setGimbalPitch(Float gimbalPitch) { + this.gimbalPitch = gimbalPitch; + return this; + } + + public Float getGimbalRoll() { + return gimbalRoll; + } + + public RcDronePayload setGimbalRoll(Float gimbalRoll) { + this.gimbalRoll = gimbalRoll; + return this; + } + + public Float getGimbalYaw() { + return gimbalYaw; + } + + public RcDronePayload setGimbalYaw(Float gimbalYaw) { + this.gimbalYaw = gimbalYaw; + return this; + } + + public Float getMeasureTargetAltitude() { + return measureTargetAltitude; + } + + public RcDronePayload setMeasureTargetAltitude(Float measureTargetAltitude) { + this.measureTargetAltitude = measureTargetAltitude; + return this; + } + + public Float getMeasureTargetDistance() { + return measureTargetDistance; + } + + public RcDronePayload setMeasureTargetDistance(Float measureTargetDistance) { + this.measureTargetDistance = measureTargetDistance; + return this; + } + + public Float getMeasureTargetLatitude() { + return measureTargetLatitude; + } + + public RcDronePayload setMeasureTargetLatitude(Float measureTargetLatitude) { + this.measureTargetLatitude = measureTargetLatitude; + return this; + } + + public Float getMeasureTargetLongitude() { + return measureTargetLongitude; + } + + public RcDronePayload setMeasureTargetLongitude(Float measureTargetLongitude) { + this.measureTargetLongitude = measureTargetLongitude; + return this; + } + + public MeasureTargetStateEnum getMeasureTargetErrorState() { + return measureTargetErrorState; + } + + public RcDronePayload setMeasureTargetErrorState(MeasureTargetStateEnum measureTargetErrorState) { + this.measureTargetErrorState = measureTargetErrorState; + return this; + } + + public List getSmartTrackPoint() { + return smartTrackPoint; + } + + public RcDronePayload setSmartTrackPoint(List smartTrackPoint) { + this.smartTrackPoint = smartTrackPoint; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcLiveStatus.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcLiveStatus.java new file mode 100644 index 0000000..e39324d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcLiveStatus.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.cloudapi.device; + +import java.util.List; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class RcLiveStatus { + + private List liveStatus; + + public RcLiveStatus() { + } + + @Override + public String toString() { + return "RcLiveStatus{" + + "liveStatus=" + liveStatus + + '}'; + } + + public List getLiveStatus() { + return liveStatus; + } + + public RcLiveStatus setLiveStatus(List liveStatus) { + this.liveStatus = liveStatus; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcLiveStatusData.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcLiveStatusData.java new file mode 100644 index 0000000..336a2ee --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcLiveStatusData.java @@ -0,0 +1,56 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.cloudapi.livestream.VideoQualityEnum; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +public class RcLiveStatusData { + + private Boolean status; + + private VideoId videoId; + + private VideoQualityEnum videoQuality; + + public RcLiveStatusData() { + } + + @Override + public String toString() { + return "RcLiveStatusData{" + + "status=" + status + + ", videoId=" + videoId + + ", videoQuality=" + videoQuality + + '}'; + } + + public Boolean getStatus() { + return status; + } + + public RcLiveStatusData setStatus(Boolean status) { + this.status = status; + return this; + } + + public VideoId getVideoId() { + return videoId; + } + + public RcLiveStatusData setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } + + public VideoQualityEnum getVideoQuality() { + return videoQuality; + } + + public RcLiveStatusData setVideoQuality(VideoQualityEnum videoQuality) { + this.videoQuality = videoQuality; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcLostActionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcLostActionEnum.java new file mode 100644 index 0000000..11095a5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcLostActionEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public enum RcLostActionEnum { + + HOVER(0), + + LAND(1), + + RETURN_HOME(2); + + private final int action; + + RcLostActionEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static RcLostActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.ordinal() == action).findAny() + .orElseThrow(() -> new CloudSDKException(RcLostActionEnum.class, action)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcPayloadControlSource.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcPayloadControlSource.java new file mode 100644 index 0000000..0a9ff5e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/RcPayloadControlSource.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class RcPayloadControlSource { + + private ControlSourceEnum controlSource; + + private PayloadIndex payloadIndex; + + private String sn; + + private String firmwareVersion; + + public RcPayloadControlSource() { + } + + @Override + public String toString() { + return "RcPayloadControlSource{" + + "controlSource=" + controlSource + + ", payloadIndex=" + payloadIndex + + ", sn='" + sn + '\'' + + ", firmwareVersion='" + firmwareVersion + '\'' + + '}'; + } + + public ControlSourceEnum getControlSource() { + return controlSource; + } + + public RcPayloadControlSource setControlSource(ControlSourceEnum controlSource) { + this.controlSource = controlSource; + return this; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public RcPayloadControlSource setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public String getSn() { + return sn; + } + + public RcPayloadControlSource setSn(String sn) { + this.sn = sn; + return this; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public RcPayloadControlSource setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ShutterSpeedEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ShutterSpeedEnum.java new file mode 100644 index 0000000..7df8ff2 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ShutterSpeedEnum.java @@ -0,0 +1,169 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/12 + */ +public enum ShutterSpeedEnum { + + /** + * 1/8000 s + */ + _1_8000TH_S(0), + + _1_6400TH_S(1), + + _1_6000TH_S(2), + + _1_5000TH_S(3), + + _1_4000TH_S(4), + + _1_3200TH_S(5), + + _1_3000TH_S(6), + + _1_2500TH_S(7), + + _1_2000TH_S(8), + + _1_1600TH_S(9), + + _1_1500TH_S(10), + + _1_1250TH_S(11), + + _1_1000TH_S(12), + + _1_800TH_S(13), + + _1_725TH_S(14), + + _1_640TH_S(15), + + _1_500TH_S(16), + + _1_400TH_S(17), + + _1_350TH_S(18), + + _1_320TH_S(19), + + _1_250TH_S(20), + + _1_240TH_S(21), + + _1_200TH_S(22), + + _1_180TH_S(23), + + _1_160TH_S(24), + + _1_125TH_S(25), + + _1_120TH_S(26), + + _1_100TH_S(27), + + _1_90TH_S(28), + + _1_80TH_S(29), + + _1_60TH_S(30), + + _1_50TH_S(31), + + _1_40TH_S(32), + + _1_30TH_S(33), + + _1_25TH_S(34), + + _1_20TH_S(35), + + _1_15TH_S(36), + + _2_25THS_S(37), + + _1_10TH_S(38), + + _1_8TH_S(39), + + _4_25THS_S(40), + + _1_5TH_S(41), + + _1_4TH_S(42), + + _1_3TH_S(43), + + _2_5THS_S(44), + + _1_2TH_S(45), + + /** + * 3/5 s + */ + _3_5THS_S(46), + + _4_5TH_S(47), + + /** + * 1 s + */ + _1S(48), + + /** + * 1.3 s + */ + _1_DOT_3S(49), + + _1_DOT_6_S(50), + + _2_S(51), + + _2_DOT_5_S(52), + + _3_DOT_S(53), + + _3_DOT_2_S(54), + + _4_DOT_S(55), + + _5_DOT_S(56), + + _6_DOT_S(57), + + _7_DOT_S(58), + + _8_DOT_S(59), + + AUTO(65534), + + ; + + private final int speed; + + ShutterSpeedEnum(int speed) { + this.speed = speed; + } + + @JsonValue + public int getSpeed() { + return speed; + } + + @JsonCreator + public static ShutterSpeedEnum find(int speed) { + return Arrays.stream(values()).filter(speedEnum -> speedEnum.speed == speed).findAny() + .orElseThrow(() -> new CloudSDKException(ShutterSpeedEnum.class, speed)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimCardStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimCardStateEnum.java new file mode 100644 index 0000000..d7d4e35 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimCardStateEnum.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public enum SimCardStateEnum { + + NO_CARD(0), + + INSERTED(1), + + ; + + private final int state; + + SimCardStateEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static SimCardStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(SimCardStateEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimInfo.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimInfo.java new file mode 100644 index 0000000..bae7582 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimInfo.java @@ -0,0 +1,63 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class SimInfo { + + /** + * sim supported operators + */ + private TelecomOperatorEnum telecomOperator; + + /** + * Type of physical sim card + */ + private SimTypeEnum simType; + + /** + * The unique identification mark of the sim card can be used to purchase physical sim card packages. + */ + private String iccid; + + public SimInfo() { + } + + @Override + public String toString() { + return "SimInfo{" + + "telecomOperator=" + telecomOperator + + ", simType=" + simType + + ", iccid='" + iccid + '\'' + + '}'; + } + + public TelecomOperatorEnum getTelecomOperator() { + return telecomOperator; + } + + public SimInfo setTelecomOperator(TelecomOperatorEnum telecomOperator) { + this.telecomOperator = telecomOperator; + return this; + } + + public SimTypeEnum getSimType() { + return simType; + } + + public SimInfo setSimType(SimTypeEnum simType) { + this.simType = simType; + return this; + } + + public String getIccid() { + return iccid; + } + + public SimInfo setIccid(String iccid) { + this.iccid = iccid; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimSlotEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimSlotEnum.java new file mode 100644 index 0000000..c0fcddb --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimSlotEnum.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public enum SimSlotEnum { + + UNKNOWN(0), + + SIM(1), + + ESIM(2), + + ; + + private final int slot; + + SimSlotEnum(int slot) { + this.slot = slot; + } + + @JsonValue + public int getSlot() { + return slot; + } + + @JsonCreator + public static SimSlotEnum find(int slot) { + return Arrays.stream(values()).filter(slotEnum -> slotEnum.slot == slot).findAny() + .orElseThrow(() -> new CloudSDKException(SimSlotEnum.class, slot)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimTypeEnum.java new file mode 100644 index 0000000..87ac825 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SimTypeEnum.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public enum SimTypeEnum { + + UNKNOWN(0), + + ORDINARY(1), + + THREE_NETWORK_MODES(2), + + ; + + private final int type; + + SimTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static SimTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(SimTypeEnum.class, type)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SmartTrackPoint.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SmartTrackPoint.java new file mode 100644 index 0000000..8787de5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SmartTrackPoint.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class SmartTrackPoint { + + private TrackTargetModeEnum trackTargetMode; + + private Float trackLatitude; + + private Float trackLongitude; + + private Float trackAltitude; + + public SmartTrackPoint() { + } + + @Override + public String toString() { + return "SmartTrackPoint{" + + "trackTargetMode=" + trackTargetMode + + ", trackLatitude=" + trackLatitude + + ", trackLongitude=" + trackLongitude + + ", trackAltitude=" + trackAltitude + + '}'; + } + + public TrackTargetModeEnum getTrackTargetMode() { + return trackTargetMode; + } + + public SmartTrackPoint setTrackTargetMode(TrackTargetModeEnum trackTargetMode) { + this.trackTargetMode = trackTargetMode; + return this; + } + + public Float getTrackLatitude() { + return trackLatitude; + } + + public SmartTrackPoint setTrackLatitude(Float trackLatitude) { + this.trackLatitude = trackLatitude; + return this; + } + + public Float getTrackLongitude() { + return trackLongitude; + } + + public SmartTrackPoint setTrackLongitude(Float trackLongitude) { + this.trackLongitude = trackLongitude; + return this; + } + + public Float getTrackAltitude() { + return trackAltitude; + } + + public SmartTrackPoint setTrackAltitude(Float trackAltitude) { + this.trackAltitude = trackAltitude; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/Storage.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/Storage.java new file mode 100644 index 0000000..c68a6cd --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/Storage.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/11 + */ +public class Storage { + + private Long total; + + private Long used; + + public Storage() { + } + + @Override + public String toString() { + return "Storage{" + + "total=" + total + + ", used=" + used + + '}'; + } + + public Long getTotal() { + return total; + } + + public Storage setTotal(Long total) { + this.total = total; + return this; + } + + public Long getUsed() { + return used; + } + + public Storage setUsed(Long used) { + this.used = used; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SwitchActionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SwitchActionEnum.java new file mode 100644 index 0000000..3b57d1e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/SwitchActionEnum.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/28 + */ +public enum SwitchActionEnum { + + DISABLE(0), + + ENABLE(1); + + private final int action; + + SwitchActionEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static SwitchActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(SwitchActionEnum.class, action)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/TelecomOperatorEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/TelecomOperatorEnum.java new file mode 100644 index 0000000..dbb1b05 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/TelecomOperatorEnum.java @@ -0,0 +1,43 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public enum TelecomOperatorEnum { + + UNKNOWN(0), + + CHINA_MOBILE(1), + + CHINA_UNICOM(2), + + CHINA_TELECOM(3), + + ; + + private final int operator; + + TelecomOperatorEnum(int operator) { + this.operator = operator; + } + + @JsonValue + public int getOperator() { + return operator; + } + + @JsonCreator + public static TelecomOperatorEnum find(int operator) { + return Arrays.stream(values()).filter(operatorEnum -> operatorEnum.operator == operator).findAny() + .orElseThrow(() -> new CloudSDKException(TelecomOperatorEnum.class, operator)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ThermalGainModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ThermalGainModeEnum.java new file mode 100644 index 0000000..3ce1d28 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ThermalGainModeEnum.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum ThermalGainModeEnum { + + AUTOMATIC(0), + + LOW(1), + + HIGH(2), + ; + + private final int mode; + + ThermalGainModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static ThermalGainModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(ThermalGainModeEnum.class, mode)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ThermalPaletteStyleEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ThermalPaletteStyleEnum.java new file mode 100644 index 0000000..c7a5144 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/ThermalPaletteStyleEnum.java @@ -0,0 +1,72 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum ThermalPaletteStyleEnum { + + WHITE_HOT(0), + + BLACK_HOT(1), + + RED_HOT(2), + + GREEN_HOT(3), + + FUSION(4), + + RAINBOW(5), + + IRONBOW1(6), + + IRONBOW2(7), + + ICE_FIRE(8), + + SEPIA(9), + + GLOWBOW(10), + + COLOR1(11), + + COLOR2(12), + + RAIN(13), + + HOT_SPOT(14), + + RAINBOW2(15), + + GRAY(16), + + METAL(17), + + COLD_SPOT(18), + ; + + private final int style; + + ThermalPaletteStyleEnum(int style) { + this.style = style; + } + + @JsonValue + public int getStyle() { + return style; + } + + @JsonCreator + public static ThermalPaletteStyleEnum find(int style) { + return Arrays.stream(values()).filter(styleEnum -> styleEnum.style == style).findAny() + .orElseThrow(() -> new CloudSDKException(ThermalPaletteStyleEnum.class, style)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/TrackTargetModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/TrackTargetModeEnum.java new file mode 100644 index 0000000..b222b38 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/TrackTargetModeEnum.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum TrackTargetModeEnum { + + NORMAL(1), + + LOW_CREDIBILITY(2), + + PREDICTED(3), + ; + private final int mode; + + TrackTargetModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static TrackTargetModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(TrackTargetModeEnum.class, mode)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/UpdateTopo.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/UpdateTopo.java new file mode 100644 index 0000000..87ea84d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/UpdateTopo.java @@ -0,0 +1,105 @@ +package org.dromara.common.sdk.cloudapi.device; + + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/26 + */ +public class UpdateTopo { + + private DeviceDomainEnum domain; + + private DeviceTypeEnum type; + + private DeviceSubTypeEnum subType; + + private String deviceSecret; + + private String nonce; + + private String thingVersion; + + private List subDevices; + + public UpdateTopo() { + } + + @Override + public String toString() { + return "UpdateTopo{" + + "domain=" + domain + + ", type=" + type + + ", subType=" + subType + + ", deviceSecret='" + deviceSecret + '\'' + + ", nonce='" + nonce + '\'' + + ", thingVersion=" + thingVersion + + ", subDevices=" + subDevices + + '}'; + } + + public DeviceDomainEnum getDomain() { + return domain; + } + + public UpdateTopo setDomain(DeviceDomainEnum domain) { + this.domain = domain; + return this; + } + + public DeviceTypeEnum getType() { + return type; + } + + public UpdateTopo setType(DeviceTypeEnum type) { + this.type = type; + return this; + } + + public DeviceSubTypeEnum getSubType() { + return subType; + } + + public UpdateTopo setSubType(DeviceSubTypeEnum subType) { + this.subType = subType; + return this; + } + + public String getDeviceSecret() { + return deviceSecret; + } + + public UpdateTopo setDeviceSecret(String deviceSecret) { + this.deviceSecret = deviceSecret; + return this; + } + + public String getNonce() { + return nonce; + } + + public UpdateTopo setNonce(String nonce) { + this.nonce = nonce; + return this; + } + + public String getThingVersion() { + return thingVersion; + } + + public UpdateTopo setThingVersion(String thingVersion) { + this.thingVersion = thingVersion; + return this; + } + + public List getSubDevices() { + return subDevices; + } + + public UpdateTopo setSubDevices(List subDevices) { + this.subDevices = subDevices; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/UpdateTopoSubDevice.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/UpdateTopoSubDevice.java new file mode 100644 index 0000000..234d0a4 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/UpdateTopoSubDevice.java @@ -0,0 +1,114 @@ +package org.dromara.common.sdk.cloudapi.device; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/26 + */ +public class UpdateTopoSubDevice { + + private String sn; + + private DeviceDomainEnum domain; + + private DeviceTypeEnum type; + + private DeviceSubTypeEnum subType; + + private ControlSourceEnum index; + + private String deviceSecret; + + private String nonce; + + private String thingVersion; + + public UpdateTopoSubDevice() { + } + + @Override + public String toString() { + return "UpdateTopoSubDevice{" + + "sn='" + sn + '\'' + + ", domain=" + domain + + ", type=" + type + + ", subType=" + subType + + ", index=" + index + + ", deviceSecret='" + deviceSecret + '\'' + + ", nonce='" + nonce + '\'' + + ", thingVersion=" + thingVersion + + '}'; + } + + public String getSn() { + return sn; + } + + public UpdateTopoSubDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public DeviceDomainEnum getDomain() { + return domain; + } + + public UpdateTopoSubDevice setDomain(DeviceDomainEnum domain) { + this.domain = domain; + return this; + } + + public DeviceTypeEnum getType() { + return type; + } + + public UpdateTopoSubDevice setType(DeviceTypeEnum type) { + this.type = type; + return this; + } + + public DeviceSubTypeEnum getSubType() { + return subType; + } + + public UpdateTopoSubDevice setSubType(DeviceSubTypeEnum subType) { + this.subType = subType; + return this; + } + + public ControlSourceEnum getIndex() { + return index; + } + + public UpdateTopoSubDevice setIndex(ControlSourceEnum index) { + this.index = index; + return this; + } + + public String getDeviceSecret() { + return deviceSecret; + } + + public UpdateTopoSubDevice setDeviceSecret(String deviceSecret) { + this.deviceSecret = deviceSecret; + return this; + } + + public String getNonce() { + return nonce; + } + + public UpdateTopoSubDevice setNonce(String nonce) { + this.nonce = nonce; + return this; + } + + public String getThingVersion() { + return thingVersion; + } + + public UpdateTopoSubDevice setThingVersion(String thingVersion) { + this.thingVersion = thingVersion; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/UserExperienceImprovementEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/UserExperienceImprovementEnum.java new file mode 100644 index 0000000..2e7113a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/UserExperienceImprovementEnum.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/13 + */ +public enum UserExperienceImprovementEnum { + + INITIAL(0), + + REFUSE(1), + + AGREE(2), + ; + + private final int state; + + UserExperienceImprovementEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static UserExperienceImprovementEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(UserExperienceImprovementEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/VideoId.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/VideoId.java new file mode 100644 index 0000000..ac6f859 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/VideoId.java @@ -0,0 +1,82 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.cloudapi.livestream.VideoTypeEnum; +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.constraints.NotNull; +import org.springframework.util.StringUtils; + +import java.util.Arrays; +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/25 + */ +public class VideoId { + + @NotNull + private String droneSn; + + @NotNull + private PayloadIndex payloadIndex; + + @NotNull + private VideoTypeEnum videoType = VideoTypeEnum.NORMAL; + + public VideoId() { + } + + @JsonCreator + public VideoId(String videoId) { + if (!StringUtils.hasText(videoId)) { + return; + } + String[] videoIdArr = Arrays.stream(videoId.split("/")).toArray(String[]::new); + if (videoIdArr.length != 3) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + this.droneSn = videoIdArr[0]; + this.payloadIndex = new PayloadIndex(videoIdArr[1]); + this.videoType = VideoTypeEnum.find(videoIdArr[2].split("-")[0]); + } + + @Override + @JsonValue + public String toString() { + if (Objects.isNull(payloadIndex)) { + return ""; + } + return String.format("%s/%s/%s-0", droneSn, payloadIndex.toString(), videoType.getType()); + } + + public String getDroneSn() { + return droneSn; + } + + public VideoId setDroneSn(String droneSn) { + this.droneSn = droneSn; + return this; + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public VideoId setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public VideoTypeEnum getVideoType() { + return videoType; + } + + public VideoId setVideoType(VideoTypeEnum videoType) { + this.videoType = videoType; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/WindDirectionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/WindDirectionEnum.java new file mode 100644 index 0000000..cad0855 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/WindDirectionEnum.java @@ -0,0 +1,52 @@ +package org.dromara.common.sdk.cloudapi.device; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public enum WindDirectionEnum { + + NO(0), + + NORTH(1), + + NORTHEAST(2), + + EAST(3), + + SOUTHEAST(4), + + SOUTH(5), + + SOUTHWEST(6), + + WEST(7), + + NORTHWEST(8), + ; + + private final int direction; + + WindDirectionEnum(int direction) { + this.direction = direction; + } + + @JsonValue + public int getDirection() { + return direction; + } + + @JsonCreator + public static WindDirectionEnum find(int direction) { + return Arrays.stream(values()).filter(directionEnum -> directionEnum.direction == direction).findAny() + .orElseThrow(() -> new CloudSDKException(WindDirectionEnum.class, direction)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/WirelessLink.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/WirelessLink.java new file mode 100644 index 0000000..49dd920 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/WirelessLink.java @@ -0,0 +1,145 @@ +package org.dromara.common.sdk.cloudapi.device; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/3 + */ +public class WirelessLink { + + @JsonProperty("4g_freq_band") + private Float fourthGenerationFreqBand; + + @JsonProperty("4g_gnd_quality") + private Integer fourthGenerationGndQuality; + + @JsonProperty("4g_link_state") + private Boolean fourthGenerationLinkState; + + @JsonProperty("4g_quality") + private Integer fourthGenerationQuality; + + @JsonProperty("4g_uav_quality") + private Integer fourthGenerationUavQuality; + + private Integer dongleNumber; + + private LinkWorkModeEnum linkWorkmode; + + private Float sdrFreqBand; + + private Boolean sdrLinkState; + + private Integer sdrQuality; + + public WirelessLink() { + } + + @Override + public String toString() { + return "WirelessLink{" + + "fourthGenerationFreqBand=" + fourthGenerationFreqBand + + ", fourthGenerationGndQuality=" + fourthGenerationGndQuality + + ", fourthGenerationLinkState=" + fourthGenerationLinkState + + ", fourthGenerationQuality=" + fourthGenerationQuality + + ", fourthGenerationUavQuality=" + fourthGenerationUavQuality + + ", dongleNumber=" + dongleNumber + + ", linkWorkmode=" + linkWorkmode + + ", sdrFreqBand=" + sdrFreqBand + + ", sdrLinkState=" + sdrLinkState + + ", sdrQuality=" + sdrQuality + + '}'; + } + + public Float getFourthGenerationFreqBand() { + return fourthGenerationFreqBand; + } + + public WirelessLink setFourthGenerationFreqBand(Float fourthGenerationFreqBand) { + this.fourthGenerationFreqBand = fourthGenerationFreqBand; + return this; + } + + public Integer getFourthGenerationGndQuality() { + return fourthGenerationGndQuality; + } + + public WirelessLink setFourthGenerationGndQuality(Integer fourthGenerationGndQuality) { + this.fourthGenerationGndQuality = fourthGenerationGndQuality; + return this; + } + + public Boolean getFourthGenerationLinkState() { + return fourthGenerationLinkState; + } + + public WirelessLink setFourthGenerationLinkState(Boolean fourthGenerationLinkState) { + this.fourthGenerationLinkState = fourthGenerationLinkState; + return this; + } + + public Integer getFourthGenerationQuality() { + return fourthGenerationQuality; + } + + public WirelessLink setFourthGenerationQuality(Integer fourthGenerationQuality) { + this.fourthGenerationQuality = fourthGenerationQuality; + return this; + } + + public Integer getFourthGenerationUavQuality() { + return fourthGenerationUavQuality; + } + + public WirelessLink setFourthGenerationUavQuality(Integer fourthGenerationUavQuality) { + this.fourthGenerationUavQuality = fourthGenerationUavQuality; + return this; + } + + public Integer getDongleNumber() { + return dongleNumber; + } + + public WirelessLink setDongleNumber(Integer dongleNumber) { + this.dongleNumber = dongleNumber; + return this; + } + + public LinkWorkModeEnum getLinkWorkmode() { + return linkWorkmode; + } + + public WirelessLink setLinkWorkmode(LinkWorkModeEnum linkWorkmode) { + this.linkWorkmode = linkWorkmode; + return this; + } + + public Float getSdrFreqBand() { + return sdrFreqBand; + } + + public WirelessLink setSdrFreqBand(Float sdrFreqBand) { + this.sdrFreqBand = sdrFreqBand; + return this; + } + + public Boolean getSdrLinkState() { + return sdrLinkState; + } + + public WirelessLink setSdrLinkState(Boolean sdrLinkState) { + this.sdrLinkState = sdrLinkState; + return this; + } + + public Integer getSdrQuality() { + return sdrQuality; + } + + public WirelessLink setSdrQuality(Integer sdrQuality) { + this.sdrQuality = sdrQuality; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/api/AbstractDeviceService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/api/AbstractDeviceService.java new file mode 100644 index 0000000..9676d1b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/device/api/AbstractDeviceService.java @@ -0,0 +1,274 @@ +package org.dromara.common.sdk.cloudapi.device.api; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.device.*; +import org.dromara.common.sdk.cloudapi.property.DockDroneCommanderFlightHeight; +import org.dromara.common.sdk.cloudapi.property.DockDroneCommanderModeLostAction; +import org.dromara.common.sdk.cloudapi.property.DockDroneRthMode; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.osd.TopicOsdRequest; +import org.dromara.common.sdk.mqtt.state.TopicStateRequest; +import org.dromara.common.sdk.mqtt.state.TopicStateResponse; +import org.dromara.common.sdk.mqtt.status.TopicStatusRequest; +import org.dromara.common.sdk.mqtt.status.TopicStatusResponse; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AbstractDeviceService { + + /** + * osd dock + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_OSD_DOCK) + public void osdDock(TopicOsdRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("osdDock not implemented"); + } + + /** + * osd dock drone + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_OSD_DOCK_DRONE) + public void osdDockDrone(TopicOsdRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("osdDockDrone not implemented"); + } + + /** + * osd remote control + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_OSD_RC) + public void osdRemoteControl(TopicOsdRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("osdRemoteControl not implemented"); + } + + /** + * osd remote control drone + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_OSD_RC_DRONE) + public void osdRcDrone(TopicOsdRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("osdRcDrone not implemented"); + } + + /** + * Gateway device + sub device online + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATUS_ONLINE, outputChannel = ChannelName.OUTBOUND_STATUS) + public TopicStatusResponse updateTopoOnline(TopicStatusRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("updateTopoOnline not implemented"); + } + + /** + * Sub device offline + * @param request data + * @param headers The headers for a {@link Message}. + * @return status_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATUS_OFFLINE, outputChannel = ChannelName.OUTBOUND_STATUS) + public TopicStatusResponse updateTopoOffline(TopicStatusRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("updateTopoOffline not implemented"); + } + + /** + * Firmware version update for dock and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_FIRMWARE_VERSION) + public void dockFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockFirmwareVersionUpdate not implemented"); + } + + /** + * Firmware version update for remote control and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_RC_AND_DRONE_FIRMWARE_VERSION) + public void rcAndDroneFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("rcAndDroneFirmwareVersionUpdate not implemented"); + } + + /** + * Drone control source update for dock and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_DRONE_CONTROL_SOURCE) + public void dockControlSourceUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockControlSourceUpdate not implemented"); + } + + /** + * Drone control source update for remote control and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_RC_CONTROL_SOURCE) + public void rcControlSourceUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("rcControlSourceUpdate未实现"); + } + + /** + * Live status update for dock and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_LIVE_STATUS) + public void dockLiveStatusUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockLiveStatusUpdate not implemented"); + } + + /** + * Live status source update for remote control and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_RC_LIVE_STATUS) + public void rcLiveStatusUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("rcLiveStatusUpdate not implemented"); + } + + /** + * Payload firmware version update for remote control and drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_RC_PAYLOAD_FIRMWARE) + public void rcPayloadFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("rcPayloadFirmwareVersionUpdate not implemented"); + } + + /** + * Wpmz firmware version update for drone + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_DRONE_WPMZ_VERSION) + public void dockWpmzVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockWpmzVersionUpdate not implemented"); + } + + /** + * Styles supported by the IR palette + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_DRONE_THERMAL_SUPPORTED_PALETTE_STYLE) + public void dockThermalSupportedPaletteStyle(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockThermalSupportedPaletteStyle not implemented"); + } + + /** + * Under optimal RTH mode, aircraft will automatically plan the optimal return altitude. + * When the environment and lighting do not meet the requirements of the visual system (such as direct sunlight in the evening or no light at night), the aircraft will perform a straight-line return at the altitude you have set. + * @param request data + * @param headers The headers for a {@link Message}. + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_DRONE_RTH_MODE, outputChannel = ChannelName.OUTBOUND_STATE) + public TopicStateResponse dockDroneRthMode(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockRthMode not implemented"); + } + + /** + * Current RTH height mode + * @param request data + * @param headers The headers for a {@link Message}. + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_DRONE_CURRENT_RTH_MODE, outputChannel = ChannelName.OUTBOUND_STATE) + public TopicStateResponse dockDroneCurrentRthMode(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockCurrentRthMode not implemented"); + } + + /** + * To-point flight mission out of control action + * @param request data + * @param headers The headers for a {@link Message}. + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_DRONE_COMMANDER_MODE_LOST_ACTION, outputChannel = ChannelName.OUTBOUND_STATE) + public TopicStateResponse dockDroneCommanderModeLostAction(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockDroneCommanderModeLostAction not implemented"); + } + + /** + * Current mode of to-point flight mission + * @param request data + * @param headers The headers for a {@link Message}. + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_DRONE_CURRENT_COMMANDER_FLIGHT_MODE, outputChannel = ChannelName.OUTBOUND_STATE) + public TopicStateResponse dockDroneCurrentCommanderFlightMode(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockDroneCurrentCommanderFlightMode not implemented"); + } + + /** + * Relative to (airport) takeoff point altitude. + * ALT. + * @param request data + * @param headers The headers for a {@link Message}. + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_DRONE_COMMANDER_FLIGHT_HEIGHT, outputChannel = ChannelName.OUTBOUND_STATE) + public TopicStateResponse dockDroneCommanderFlightHeight(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockDroneCommanderFlightHeight not implemented"); + } + + /** + * The reason why the drone enters current state + * @param request data + * @param headers The headers for a {@link Message}. + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_DRONE_MODE_CODE_REASON, outputChannel = ChannelName.OUTBOUND_STATE) + public TopicStateResponse dockDroneModeCodeReason(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockDroneModeCodeReason not implemented"); + } + + /** + * 4g dongle information + * @param request data + * @param headers The headers for a {@link Message}. + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_1, include = GatewayTypeEnum.DOCK2) + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_AND_DRONE_DONGLE_INFOS, outputChannel = ChannelName.OUTBOUND_STATE) + public TopicStateResponse dongleInfos(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dongleInfos not implemented"); + } + + /** + * silent mode + * @param request data + * @param headers The headers for a {@link Message}. + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_2, include = GatewayTypeEnum.DOCK) + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_SILENT_MODE, outputChannel = ChannelName.OUTBOUND_STATE) + public TopicStateResponse dockSilentMode(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockSilentMode not implemented"); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/FirmwareErrorCodeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/FirmwareErrorCodeEnum.java new file mode 100644 index 0000000..f2f7d53 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/FirmwareErrorCodeEnum.java @@ -0,0 +1,97 @@ +package org.dromara.common.sdk.cloudapi.firmware; + +import org.dromara.common.sdk.common.IErrorInfo; +import org.dromara.common.sdk.mqtt.events.IEventsErrorCode; +import org.dromara.common.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum FirmwareErrorCodeEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + WRONG_TYPE(312001, "一致性升级已完成,但设备未请求。"), + + READY_1_FAILED(312002, "升级失败。请再试一次。"), + + VALIDATION_FAILED(312003, "升级失败。请再试一次。"), + + READY_2_FAILED(312004, "升级失败。请再试一次。"), + + WRONG_PROTOCOL(312010, "升级请求与API不同。"), + + WRONG_PARAMETER(312012, "请检查参数,然后重试。"), + + COMMAND_1_FAILED(312013, "升级失败。请再试一次。"), + + UPDATING(312014, "正在更新设备固件。等待更新完成。"), + + WORKING(312015, "设备在飞行过程中无法升级。请稍候,然后重试。"), + + TRANSMISSION_ERROR(312016, "更新失败。码头和飞机传输错误。重新启动码头和飞机,然后再试一次。"), + + VERSION_CHECK_FAILED(312017, "未能检查版本。"), + + COMMAND_2_FAILED(312018, "升级失败。请再试一次。"), + + COMMAND_3_FAILED(312019, "升级失败。请再试一次。"), + + COMMAND_4_FAILED(312020, "升级失败。请再试一次。"), + + COMMAND_5_FAILED(312021, "升级失败。请再试一次。"), + + AIRCRAFT_NOT_FOUND(312022, "未能接通飞机电源,或飞机未连接。检查飞机是否在码头内,电池是否已安装,码头和飞机是否已连接。"), + + AIRCRAFT_OUTSIDE(312023, "未能将传动杆推回原位。无法更新飞机固件。检查紧急停止按钮是否按下或传动杆是否卡住。"), + + COMMAND_6_FAILED(312024, "升级失败。请再试一次。"), + + DELETE_FAILED(312025, "未能删除旧的固件包。"), + + DECOMPRESSION_FAILED(312026, "无法解压缩脱机升级包。"), + + NO_AIRCRAFT_DETECTED(312027, "无法更新固件。码头内未发现飞机。"), + + DEVICE_RESTART_1(312028, "无法更新固件。设备在更新过程中重新启动。"), + + DEVICE_RESTART_2(312029, "正在重新启动设备。无法更新固件。"), + + FOURTH_GENERATION_IS_ENABLE(312030, "启用了飞机增强传输。无法更新固件。请禁用4G传输,然后重试。"), + + LOW_POWER(312704, "飞机电池电量过低。等待飞机充电到20%以上,然后再试一次。"), + + UNKNOWN(-1, "UNKNOWN"), + ; + + + private final String msg; + + private final int code; + + FirmwareErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + /** + * @param code error code + * @return enumeration object + */ + public static FirmwareErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/FirmwareMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/FirmwareMethodEnum.java new file mode 100644 index 0000000..2623c0a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/FirmwareMethodEnum.java @@ -0,0 +1,24 @@ +package org.dromara.common.sdk.cloudapi.firmware; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum FirmwareMethodEnum { + + OTA_CREATE("ota_create"); + + private final String method; + + FirmwareMethodEnum(String method) { + this.method = method; + } + + @JsonValue + public String getMethod() { + return method; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/FirmwareUpgradeTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/FirmwareUpgradeTypeEnum.java new file mode 100644 index 0000000..076eab2 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/FirmwareUpgradeTypeEnum.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.cloudapi.firmware; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/15 + */ +public enum FirmwareUpgradeTypeEnum { + + /** + * to upgraded + */ + NORMAL_UPGRADE(2), + + /** + * A consistency upgrade is required. + */ + CONSISTENT_UPGRADE(3); + + private final int type; + + FirmwareUpgradeTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static FirmwareUpgradeTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(FirmwareUpgradeTypeEnum.class, type)); + + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaCreateDevice.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaCreateDevice.java new file mode 100644 index 0000000..997b347 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaCreateDevice.java @@ -0,0 +1,114 @@ +package org.dromara.common.sdk.cloudapi.firmware; + + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/16 + */ +public class OtaCreateDevice { + + @NotNull + private String sn; + + @NotNull + @Pattern(regexp = "^\\d{2}\\.\\d{2}\\.\\d{4}$") + private String productVersion; + + @NotNull + private String fileUrl; + + @NotNull + private String md5; + + @NotNull + private Long fileSize; + + @NotNull + private FirmwareUpgradeTypeEnum firmwareUpgradeType; + + @NotNull + private String fileName; + + public OtaCreateDevice() { + } + + @Override + public String toString() { + return "OtaCreateDevice{" + + "sn='" + sn + '\'' + + ", productVersion='" + productVersion + '\'' + + ", fileUrl='" + fileUrl + '\'' + + ", md5='" + md5 + '\'' + + ", fileSize=" + fileSize + + ", firmwareUpgradeType=" + firmwareUpgradeType + + ", fileName='" + fileName + '\'' + + '}'; + } + + public String getSn() { + return sn; + } + + public OtaCreateDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public String getProductVersion() { + return productVersion; + } + + public OtaCreateDevice setProductVersion(String productVersion) { + this.productVersion = productVersion; + return this; + } + + public String getFileUrl() { + return fileUrl; + } + + public OtaCreateDevice setFileUrl(String fileUrl) { + this.fileUrl = fileUrl; + return this; + } + + public String getMd5() { + return md5; + } + + public OtaCreateDevice setMd5(String md5) { + this.md5 = md5; + return this; + } + + public Long getFileSize() { + return fileSize; + } + + public OtaCreateDevice setFileSize(Long fileSize) { + this.fileSize = fileSize; + return this; + } + + public FirmwareUpgradeTypeEnum getFirmwareUpgradeType() { + return firmwareUpgradeType; + } + + public OtaCreateDevice setFirmwareUpgradeType(FirmwareUpgradeTypeEnum firmwareUpgradeType) { + this.firmwareUpgradeType = firmwareUpgradeType; + return this; + } + + public String getFileName() { + return fileName; + } + + public OtaCreateDevice setFileName(String fileName) { + this.fileName = fileName; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaCreateRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaCreateRequest.java new file mode 100644 index 0000000..505e3a3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaCreateRequest.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.firmware; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/28 + */ +public class OtaCreateRequest extends BaseModel { + + @Size(min = 1, max = 2) + @NotNull + private List<@Valid OtaCreateDevice> devices; + + public OtaCreateRequest() { + } + + @Override + public String toString() { + return "OtaCreateRequest{" + + "devices=" + devices + + '}'; + } + + public List getDevices() { + return devices; + } + + public OtaCreateRequest setDevices(List devices) { + this.devices = devices; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaCreateResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaCreateResponse.java new file mode 100644 index 0000000..8eaa61b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaCreateResponse.java @@ -0,0 +1,33 @@ +package org.dromara.common.sdk.cloudapi.firmware; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class OtaCreateResponse { + + /** + * Mission status + **/ + private OtaProgressStatusEnum status; + + public OtaCreateResponse() { + } + + @Override + public String toString() { + return "OtaCreateResponse{" + + "status=" + status + + '}'; + } + + public OtaProgressStatusEnum getStatus() { + return status; + } + + public OtaCreateResponse setStatus(OtaProgressStatusEnum status) { + this.status = status; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgress.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgress.java new file mode 100644 index 0000000..e8989f3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgress.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.firmware; + +/** + * @author sean + * @version 1.2 + * @date 2022/7/29 + */ +public class OtaProgress { + + private OtaProgressStatusEnum status; + + private OtaProgressData progress; + + private OtaProgressExt ext; + + public OtaProgress() { + } + + @Override + public String toString() { + return "OtaProgress{" + + "status=" + status + + ", progress=" + progress + + ", ext=" + ext + + '}'; + } + + public OtaProgressStatusEnum getStatus() { + return status; + } + + public OtaProgress setStatus(OtaProgressStatusEnum status) { + this.status = status; + return this; + } + + public OtaProgressData getProgress() { + return progress; + } + + public OtaProgress setProgress(OtaProgressData progress) { + this.progress = progress; + return this; + } + + public OtaProgressExt getExt() { + return ext; + } + + public OtaProgress setExt(OtaProgressExt ext) { + this.ext = ext; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressData.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressData.java new file mode 100644 index 0000000..ed3767c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressData.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.firmware; + +/** + * @author sean + * @version 1.2 + * @date 2022/7/29 + */ +public class OtaProgressData { + + private Integer percent; + + private OtaProgressStepEnum currentStep; + + public OtaProgressData() { + } + + @Override + public String toString() { + return "OtaProgressData{" + + "percent=" + percent + + ", currentStep=" + currentStep + + '}'; + } + + public Integer getPercent() { + return percent; + } + + public OtaProgressData setPercent(Integer percent) { + this.percent = percent; + return this; + } + + public OtaProgressStepEnum getCurrentStep() { + return currentStep; + } + + public OtaProgressData setCurrentStep(OtaProgressStepEnum currentStep) { + this.currentStep = currentStep; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressExt.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressExt.java new file mode 100644 index 0000000..f29f2bb --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressExt.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.firmware; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/30 + */ +public class OtaProgressExt { + + private Long rate; + + public OtaProgressExt() { + } + + @Override + public String toString() { + return "OtaProgressExt{" + + "rate=" + rate + + '}'; + } + + public Long getRate() { + return rate; + } + + public OtaProgressExt setRate(Long rate) { + this.rate = rate; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressStatusEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressStatusEnum.java new file mode 100644 index 0000000..a5a26a3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressStatusEnum.java @@ -0,0 +1,57 @@ +package org.dromara.common.sdk.cloudapi.firmware; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/17 + */ +public enum OtaProgressStatusEnum { + + SENT("sent", false), + + IN_PROGRESS("in_progress", false), + + OK("ok", true), + + PAUSED("paused", false), + + REJECTED("rejected", true), + + FAILED("failed", true), + + CANCELED("canceled", true), + + TIMEOUT("timeout", true); + + private final String status; + + private final boolean end; + + OtaProgressStatusEnum(String status, boolean end) { + this.status = status; + this.end = end; + } + + @JsonValue + public String getStatus() { + return status; + } + + public boolean isEnd() { + return end; + } + + @JsonCreator + public static OtaProgressStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(OtaProgressStatusEnum.class, status)); + } +} + + diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressStepEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressStepEnum.java new file mode 100644 index 0000000..9b80feb --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/OtaProgressStepEnum.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.firmware; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/28 + */ +public enum OtaProgressStepEnum { + + DOWNLOADING(1), + + UPGRADING(2); + + private final int step; + + OtaProgressStepEnum(int step) { + this.step = step; + } + + @JsonValue + public int getStep() { + return step; + } + + @JsonCreator + public static OtaProgressStepEnum find(int step) { + return Arrays.stream(values()).filter(stepEnum -> stepEnum.step == step).findAny() + .orElseThrow(() -> new CloudSDKException(OtaProgressStepEnum.class, step)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/api/AbstractFirmwareService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/api/AbstractFirmwareService.java new file mode 100644 index 0000000..26b10b0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/firmware/api/AbstractFirmwareService.java @@ -0,0 +1,57 @@ +package org.dromara.common.sdk.cloudapi.firmware.api; + +import org.dromara.common.sdk.cloudapi.firmware.FirmwareMethodEnum; +import org.dromara.common.sdk.cloudapi.firmware.OtaCreateRequest; +import org.dromara.common.sdk.cloudapi.firmware.OtaCreateResponse; +import org.dromara.common.sdk.cloudapi.firmware.OtaProgress; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.events.EventsDataRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsResponse; +import org.dromara.common.sdk.mqtt.services.ServicesPublish; +import org.dromara.common.sdk.mqtt.services.ServicesReplyData; +import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; +import com.fasterxml.jackson.core.type.TypeReference; +import jakarta.annotation.Resource; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + + +/** + * @author sean + * @version 1.7 + * @date 2023/6/28 + */ +public abstract class AbstractFirmwareService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Firmware upgrade progress + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_OTA_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse otaProgress(TopicEventsRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("otaProgress not implemented"); + } + + /** + * Firmware upgrade + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse> otaCreate(GatewayManager gateway, OtaCreateRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + FirmwareMethodEnum.OTA_CREATE.getMethod(), + request); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/DroneLocation.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/DroneLocation.java new file mode 100644 index 0000000..0920c80 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/DroneLocation.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/17 + */ +public class DroneLocation { + + /** + * Region unique ID + */ + private String areaId; + + /** + * Distance to the custom flight area boundary + */ + private Float areaDistance; + + /** + * Whether in custom flight area + */ + @JsonProperty("is_in_area") + private Boolean inArea; + + public String getAreaId() { + return areaId; + } + + public DroneLocation setAreaId(String areaId) { + this.areaId = areaId; + return this; + } + + public Float getAreaDistance() { + return areaDistance; + } + + public DroneLocation setAreaDistance(Float areaDistance) { + this.areaDistance = areaDistance; + return this; + } + + public Boolean getInArea() { + return inArea; + } + + public DroneLocation setInArea(Boolean inArea) { + this.inArea = inArea; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FeatureProperty.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FeatureProperty.java new file mode 100644 index 0000000..421cfdc --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FeatureProperty.java @@ -0,0 +1,60 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Min; + + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +public class FeatureProperty { + + @JsonProperty("subType") + private GeometrySubTypeEnum subType; + + @Min(10) + private Float radius = 0f; + + private Boolean enable; + + public FeatureProperty() { + } + + @Override + public String toString() { + return "FeatureProperty{" + + "subType=" + subType + + ", radius=" + radius + + ", enable=" + enable + + '}'; + } + + public GeometrySubTypeEnum getSubType() { + return subType; + } + + public FeatureProperty setSubType(GeometrySubTypeEnum subType) { + this.subType = subType; + return this; + } + + public Float getRadius() { + return radius; + } + + public FeatureProperty setRadius(Float radius) { + this.radius = radius; + return this; + } + + public Boolean getEnable() { + return enable; + } + + public FeatureProperty setEnable(Boolean enable) { + this.enable = enable; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaFeature.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaFeature.java new file mode 100644 index 0000000..df8474b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaFeature.java @@ -0,0 +1,84 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +public class FlightAreaFeature { + + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @NotNull + private String id; + + private final String type = "Feature"; + + @NotNull + private GeofenceTypeEnum geofenceType; + + @NotNull + @Valid + private FlightAreaGeometry geometry; + + @NotNull + private FeatureProperty properties; + + public FlightAreaFeature() { + } + + @Override + public String toString() { + return "FlightAreaFeature{" + + "id='" + id + '\'' + + ", type='" + type + '\'' + + ", geofenceType=" + geofenceType + + ", geometry=" + geometry + + ", properties=" + properties + + '}'; + } + + public String getId() { + return id; + } + + public FlightAreaFeature setId(String id) { + this.id = id; + return this; + } + + public String getType() { + return type; + } + + public GeofenceTypeEnum getGeofenceType() { + return geofenceType; + } + + public FlightAreaFeature setGeofenceType(GeofenceTypeEnum geofenceType) { + this.geofenceType = geofenceType; + return this; + } + + public FlightAreaGeometry getGeometry() { + return geometry; + } + + public FlightAreaFeature setGeometry(FlightAreaGeometry geometry) { + this.geometry = geometry; + return this; + } + + public FeatureProperty getProperties() { + return properties; + } + + public FlightAreaFeature setProperties(FeatureProperty properties) { + this.properties = properties; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaFile.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaFile.java new file mode 100644 index 0000000..4020e17 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaFile.java @@ -0,0 +1,48 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/17 + */ +public class FlightAreaFile { + + /** + * Custom flight area file name + */ + private String name; + + /** + * File SHA256 signature + */ + private String checksum; + + public FlightAreaFile() { + } + + @Override + public String toString() { + return "FlightAreaFile{" + + "name='" + name + '\'' + + ", checksum='" + checksum + '\'' + + '}'; + } + + public String getName() { + return name; + } + + public FlightAreaFile setName(String name) { + this.name = name; + return this; + } + + public String getChecksum() { + return checksum; + } + + public FlightAreaFile setChecksum(String checksum) { + this.checksum = checksum; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaGeometry.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaGeometry.java new file mode 100644 index 0000000..a8793ea --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaGeometry.java @@ -0,0 +1,21 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", + include = JsonTypeInfo.As.EXISTING_PROPERTY, defaultImpl = FlightAreaGeometry.class) +@JsonSubTypes({ + @JsonSubTypes.Type(value = FlightAreaPointGeometry.class, name = "Point"), + @JsonSubTypes.Type(value = FlightAreaPolygonGeometry.class, name = "Polygon") +}) +public abstract class FlightAreaGeometry { + + private GeometryTypeEnum type; + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaGetFile.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaGetFile.java new file mode 100644 index 0000000..2eebcb8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaGetFile.java @@ -0,0 +1,86 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/17 + */ +public class FlightAreaGetFile { + + /** + * File name + */ + @NotNull + @Pattern(regexp = "^geofence_[A-Za-z0-9]{32}.json$") + private String name; + + /** + * File URL + */ + @NotNull + private String url; + + /** + * File SHA256 signature + */ + @NotNull + private String checksum; + + /** + * File size + */ + @NotNull + private Integer size; + + public FlightAreaGetFile() { + } + + @Override + public String toString() { + return "FlightAreaGetFile{" + + "name='" + name + '\'' + + ", url='" + url + '\'' + + ", checksum='" + checksum + '\'' + + ", size=" + size + + '}'; + } + + public String getName() { + return name; + } + + public FlightAreaGetFile setName(String name) { + this.name = name; + return this; + } + + public String getUrl() { + return url; + } + + public FlightAreaGetFile setUrl(String url) { + this.url = url; + return this; + } + + public String getChecksum() { + return checksum; + } + + public FlightAreaGetFile setChecksum(String checksum) { + this.checksum = checksum; + return this; + } + + public Integer getSize() { + return size; + } + + public FlightAreaGetFile setSize(Integer size) { + this.size = size; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaJson.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaJson.java new file mode 100644 index 0000000..51b6d55 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaJson.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +public class FlightAreaJson { + + private final String type = "FeatureCollection"; + + @NotNull + private List features; + + public FlightAreaJson() { + } + + @Override + public String toString() { + return "FlightAreaJson{" + + "type='" + type + '\'' + + ", features=" + features + + '}'; + } + + public String getType() { + return type; + } + + public List getFeatures() { + return features; + } + + public FlightAreaJson setFeatures(List features) { + this.features = features; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaMethodEnum.java new file mode 100644 index 0000000..58e9eaa --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaMethodEnum.java @@ -0,0 +1,27 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/17 + */ +public enum FlightAreaMethodEnum { + + FLIGHT_AREAS_UPDATE("flight_areas_update"), + + FLIGHT_AREAS_DELETE("flight_areas_delete"), + ; + + private final String method; + + FlightAreaMethodEnum(String method) { + this.method = method; + } + + @JsonValue + public String getMethod() { + return method; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaPointGeometry.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaPointGeometry.java new file mode 100644 index 0000000..06130d9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaPointGeometry.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +public class FlightAreaPointGeometry extends FlightAreaGeometry { + + private final GeometryTypeEnum type = GeometryTypeEnum.POINT; + + private Double[] coordinates; + + public FlightAreaPointGeometry() { + } + + @Override + public String toString() { + return "FlightAreaPointGeometry{" + + "type=" + type + + ", coordinates=" + Arrays.toString(coordinates) + + '}'; + } + + public GeometryTypeEnum getType() { + return type; + } + + public Double[] getCoordinates() { + return coordinates; + } + + public FlightAreaPointGeometry setCoordinates(Double[] coordinates) { + this.coordinates = coordinates; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaPolygonGeometry.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaPolygonGeometry.java new file mode 100644 index 0000000..01c9bc1 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaPolygonGeometry.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +public class FlightAreaPolygonGeometry extends FlightAreaGeometry { + + private final GeometryTypeEnum type = GeometryTypeEnum.POLYGON; + + private Double[][][] coordinates; + + public FlightAreaPolygonGeometry() { + } + + @Override + public String toString() { + return "FlightAreaPointGeometry{" + + "type=" + type + + ", coordinates=" + Arrays.toString(coordinates) + + '}'; + } + + public GeometryTypeEnum getType() { + return type; + } + + public Double[][][] getCoordinates() { + return coordinates; + } + + public FlightAreaPolygonGeometry setCoordinates(Double[][][] coordinates) { + this.coordinates = coordinates; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaSyncReasonEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaSyncReasonEnum.java new file mode 100644 index 0000000..aa11cdf --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaSyncReasonEnum.java @@ -0,0 +1,70 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/17 + */ +public enum FlightAreaSyncReasonEnum { + + SUCCESS(0, "success"), + + PARSE_FILE_FAILED(1, "Failed to parse file information returned from the cloud."), + + RETRIEVE_FILE_FAILED(2, "Failed to retrieve file information from the aircraft's end."), + + DOWNLOAD_FILE_FAILED(3, "Failed to download the file from the cloud."), + + LINK_FLIPPING_FAILED(4, "Link flipping failed."), + + FILE_TRANSMISSION_FAILED(5, "File transmission failed."), + + DISABLE_FAILED(6, "Filed to disable."), + + FILE_DELETION_FAILED(7, "File deletion failed."), + + FILE_LOADING_FAILED(8, "Failed to load file on drone."), + + ENABLE_FAILED(9, "Filed to enable."), + + TURN_OFF_ENHANCED_FAILED(10, "Failed to turn off enhanced image transmission."), + + POWER_ON_FAILED(11, "Failed to power on the drone."), + + CHECK_FAILED(12, "The checksum check failed."), + + SYNCHRONIZATION_TIMED_OUT(13, "Synchronization exception timed out."), + + ; + + private final int reason; + + private final String msg; + + FlightAreaSyncReasonEnum(int reason, String msg) { + this.reason = reason; + this.msg = msg; + } + + @JsonValue + public int getReason() { + return reason; + } + + public String getMsg() { + return msg; + } + + @JsonCreator + public static FlightAreaSyncReasonEnum find(int reason) { + return Arrays.stream(values()).filter(reasonEnum -> reasonEnum.reason == reason).findAny() + .orElseThrow(() -> new CloudSDKException(FlightAreaSyncReasonEnum.class, reason)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaSyncStatusEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaSyncStatusEnum.java new file mode 100644 index 0000000..449578f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreaSyncStatusEnum.java @@ -0,0 +1,51 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/17 + */ +public enum FlightAreaSyncStatusEnum { + + WAIT_SYNC("wait_sync", false), + + SWITCH_FAIL("switch_fail", false), + + SYNCHRONIZING("synchronizing", false), + + SYNCHRONIZED("synchronized", true), + + FAIL("fail", true), + + ; + + private final String status; + + private final boolean end; + + FlightAreaSyncStatusEnum(String status, boolean end) { + this.status = status; + this.end = end; + } + + @JsonValue + public String getStatus() { + return status; + } + + public boolean isEnd() { + return end; + } + + @JsonCreator + public static FlightAreaSyncStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(FlightAreaSyncStatusEnum.class, status)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasDroneLocation.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasDroneLocation.java new file mode 100644 index 0000000..cdcc14f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasDroneLocation.java @@ -0,0 +1,35 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/17 + */ +public class FlightAreasDroneLocation { + + /** + * Flight area distance to aircraft + */ + private List droneLocations; + + public FlightAreasDroneLocation() { + } + + @Override + public String toString() { + return "FlightAreasDroneLocation{" + + "droneLocations=" + droneLocations + + '}'; + } + + public List getDroneLocations() { + return droneLocations; + } + + public FlightAreasDroneLocation setDroneLocations(List droneLocations) { + this.droneLocations = droneLocations; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasGetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasGetRequest.java new file mode 100644 index 0000000..babd242 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasGetRequest.java @@ -0,0 +1,9 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/17 + */ +public class FlightAreasGetRequest { +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasGetResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasGetResponse.java new file mode 100644 index 0000000..b0c05f9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasGetResponse.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/17 + */ +public class FlightAreasGetResponse extends BaseModel { + + /** + * File list + */ + @NotNull + private List<@Valid FlightAreaGetFile> files; + + public FlightAreasGetResponse() { + } + + @Override + public String toString() { + return "FlightAreasGetResponse{" + + "files=" + files + + '}'; + } + + public List getFiles() { + return files; + } + + public FlightAreasGetResponse setFiles(List files) { + this.files = files; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasSyncProgress.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasSyncProgress.java new file mode 100644 index 0000000..79c2131 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/FlightAreasSyncProgress.java @@ -0,0 +1,63 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/17 + */ +public class FlightAreasSyncProgress { + + /** + * Synchronize state + */ + private FlightAreaSyncStatusEnum status; + + /** + * Return Code + */ + private FlightAreaSyncReasonEnum reason; + + /** + * Custom flight area file + */ + private FlightAreaFile file; + + public FlightAreasSyncProgress() { + } + + @Override + public String toString() { + return "FlightAreasSyncProgress{" + + "status=" + status + + ", reason=" + reason + + ", file=" + file + + '}'; + } + + public FlightAreaSyncStatusEnum getStatus() { + return status; + } + + public FlightAreasSyncProgress setStatus(FlightAreaSyncStatusEnum status) { + this.status = status; + return this; + } + + public FlightAreaSyncReasonEnum getReason() { + return reason; + } + + public FlightAreasSyncProgress setReason(FlightAreaSyncReasonEnum reason) { + this.reason = reason; + return this; + } + + public FlightAreaFile getFile() { + return file; + } + + public FlightAreasSyncProgress setFile(FlightAreaFile file) { + this.file = file; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/GeofenceTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/GeofenceTypeEnum.java new file mode 100644 index 0000000..a4c486f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/GeofenceTypeEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +public enum GeofenceTypeEnum { + + DFENCE("dfence"), + + NFZ("nfz"), + + ; + + private final String type; + + GeofenceTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static GeofenceTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(GeofenceTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/GeometrySubTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/GeometrySubTypeEnum.java new file mode 100644 index 0000000..d7bc135 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/GeometrySubTypeEnum.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +public enum GeometrySubTypeEnum { + + CIRCLE("Circle"), + + ; + + private final String subType; + + GeometrySubTypeEnum(String subType) { + this.subType = subType; + } + + @JsonValue + public String getSubType() { + return subType; + } + + @JsonCreator + public static GeometrySubTypeEnum find(String subType) { + return Arrays.stream(values()).filter(subTypeEnum -> subTypeEnum.subType.equals(subType)).findAny() + .orElseThrow(() -> new CloudSDKException(GeometrySubTypeEnum.class, subType)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/GeometryTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/GeometryTypeEnum.java new file mode 100644 index 0000000..82093e9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/GeometryTypeEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.flightarea; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +public enum GeometryTypeEnum { + + POINT("Point"), + + POLYGON("Polygon"), + + ; + + private final String type; + + GeometryTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static GeometryTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(GeometryTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/api/AbstractFlightAreaService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/api/AbstractFlightAreaService.java new file mode 100644 index 0000000..0627e9c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/flightarea/api/AbstractFlightAreaService.java @@ -0,0 +1,80 @@ +package org.dromara.common.sdk.cloudapi.flightarea.api; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.flightarea.*; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.events.TopicEventsRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsResponse; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsRequest; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsResponse; +import org.dromara.common.sdk.mqtt.services.ServicesPublish; +import org.dromara.common.sdk.mqtt.services.ServicesReplyData; +import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; +import jakarta.annotation.Resource; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public abstract class AbstractFlightAreaService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Update command + * @param gateway gateway device + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0, exclude = GatewayTypeEnum.RC, include = {GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2}) + public TopicServicesResponse flightAreasUpdate(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + FlightAreaMethodEnum.FLIGHT_AREAS_UPDATE.getMethod()); + } + + /** + * Progress of custom flight area file synchronize from the Cloud to the Device. Used for further defining flight area. + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHT_AREAS_SYNC_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + public TopicEventsResponse flightAreasSyncProgress(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("flightAreasSyncProgress not implemented"); + } + + /** + * Push warning information + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHT_AREAS_DRONE_LOCATION, outputChannel = ChannelName.OUTBOUND_EVENTS) + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + public TopicEventsResponse flightAreasDroneLocation(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("flightAreasDroneLocation not implemented"); + } + + /** + * Get custom flight area file + * @param request data + * @param headers The headers for a {@link Message}. + * @return requests_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_FLIGHT_AREAS_GET, outputChannel = ChannelName.OUTBOUND_REQUESTS) + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + public TopicRequestsResponse> flightAreasGet(TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("flightAreasGet not implemented"); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/DeviceHms.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/DeviceHms.java new file mode 100644 index 0000000..82889aa --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/DeviceHms.java @@ -0,0 +1,104 @@ +package org.dromara.common.sdk.cloudapi.hms; + +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/6 + */ +public class DeviceHms { + + private String code; + + private DeviceEnum deviceType; + + private Boolean imminent; + + private Boolean inTheSky; + + private HmsLevelEnum level; + + private HmsModuleEnum module; + + private DeviceHmsArgs args; + + public DeviceHms() { + } + + @Override + public String toString() { + return "DeviceHms{" + + "code='" + code + '\'' + + ", deviceType=" + deviceType + + ", imminent=" + imminent + + ", inTheSky=" + inTheSky + + ", level=" + level + + ", module=" + module + + ", args=" + args + + '}'; + } + + public String getCode() { + return code; + } + + public DeviceHms setCode(String code) { + this.code = code; + return this; + } + + public DeviceEnum getDeviceType() { + return deviceType; + } + + public DeviceHms setDeviceType(DeviceEnum deviceType) { + this.deviceType = deviceType; + return this; + } + + public Boolean getImminent() { + return imminent; + } + + public DeviceHms setImminent(Boolean imminent) { + this.imminent = imminent; + return this; + } + + public Boolean getInTheSky() { + return inTheSky; + } + + public DeviceHms setInTheSky(Boolean inTheSky) { + this.inTheSky = inTheSky; + return this; + } + + public HmsLevelEnum getLevel() { + return level; + } + + public DeviceHms setLevel(HmsLevelEnum level) { + this.level = level; + return this; + } + + public HmsModuleEnum getModule() { + return module; + } + + public DeviceHms setModule(HmsModuleEnum module) { + this.module = module; + return this; + } + + public DeviceHmsArgs getArgs() { + return args; + } + + public DeviceHms setArgs(DeviceHmsArgs args) { + this.args = args; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/DeviceHmsArgs.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/DeviceHmsArgs.java new file mode 100644 index 0000000..17bb409 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/DeviceHmsArgs.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.hms; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/6 + */ +public class DeviceHmsArgs { + + private Long componentIndex; + + private Integer sensorIndex; + + private Integer alarmId; + + public DeviceHmsArgs() { + } + + @Override + public String toString() { + return "DeviceHmsArgs{" + + "componentIndex=" + componentIndex + + ", sensorIndex=" + sensorIndex + + ", alarmId=" + alarmId + + '}'; + } + + public Long getComponentIndex() { + return componentIndex; + } + + public DeviceHmsArgs setComponentIndex(Long componentIndex) { + this.componentIndex = componentIndex; + return this; + } + + public Integer getSensorIndex() { + return sensorIndex; + } + + public DeviceHmsArgs setSensorIndex(Integer sensorIndex) { + this.sensorIndex = sensorIndex; + return this; + } + + public Integer getAlarmId() { + return alarmId; + } + + public DeviceHmsArgs setAlarmId(Integer alarmId) { + this.alarmId = alarmId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/Hms.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/Hms.java new file mode 100644 index 0000000..0a21468 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/Hms.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.cloudapi.hms; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public class Hms { + + private List list; + + public Hms() { + } + + @Override + public String toString() { + return "Hms{" + + "list=" + list + + '}'; + } + + public List getList() { + return list; + } + + public Hms setList(List list) { + this.list = list; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsBatteryIndexEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsBatteryIndexEnum.java new file mode 100644 index 0000000..a26ef82 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsBatteryIndexEnum.java @@ -0,0 +1,48 @@ +package org.dromara.common.sdk.cloudapi.hms; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsBatteryIndexEnum { + + LEFT(0, "left", "左"), + + RIGHT(1, "right", "右"); + + private final int val; + + private final String en; + + private final String zh; + + HmsBatteryIndexEnum(int val, String en, String zh) { + this.val = val; + this.en = en; + this.zh = zh; + } + + @JsonValue + public int getVal() { + return val; + } + + public String getEn() { + return en; + } + + public String getZh() { + return zh; + } + + public static HmsBatteryIndexEnum find(int val) { + return Arrays.stream(HmsBatteryIndexEnum.values()).filter(battery -> battery.val == val).findAny() + .orElseThrow(() -> new CloudSDKException(HmsBatteryIndexEnum.class, val)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsChargingRodIndexEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsChargingRodIndexEnum.java new file mode 100644 index 0000000..ddb3f24 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsChargingRodIndexEnum.java @@ -0,0 +1,50 @@ +package org.dromara.common.sdk.cloudapi.hms; + +import org.dromara.common.sdk.exception.CloudSDKException; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsChargingRodIndexEnum { + + FRONT(0, "front", "前"), + + BACK(1, "back", "后"), + + LEFT(2, "left", "左"), + + RIGHT(3, "right", "右"); + + private final int val; + + private final String en; + + private final String zh; + + HmsChargingRodIndexEnum(int val, String en, String zh) { + this.val = val; + this.en = en; + this.zh = zh; + } + + public int getVal() { + return val; + } + + public String getEn() { + return en; + } + + public String getZh() { + return zh; + } + + public static HmsChargingRodIndexEnum find(int val) { + return Arrays.stream(HmsChargingRodIndexEnum.values()).filter(rod -> rod.val == val).findAny() + .orElseThrow(() -> new CloudSDKException(HmsChargingRodIndexEnum.class, val)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsDockCoverIndexEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsDockCoverIndexEnum.java new file mode 100644 index 0000000..6e86a91 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsDockCoverIndexEnum.java @@ -0,0 +1,48 @@ +package org.dromara.common.sdk.cloudapi.hms; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsDockCoverIndexEnum { + + LEFT(0, "left", "左"), + + RIGHT(1, "right", "右"); + + private final int val; + + private final String en; + + private final String zh; + + HmsDockCoverIndexEnum(int val, String en, String zh) { + this.val = val; + this.en = en; + this.zh = zh; + } + + @JsonValue + public int getVal() { + return val; + } + + public String getEn() { + return en; + } + + public String getZh() { + return zh; + } + + public static HmsDockCoverIndexEnum find(int val) { + return Arrays.stream(HmsDockCoverIndexEnum.values()).filter(dockCover -> dockCover.val == val).findAny() + .orElseThrow(() -> new CloudSDKException(HmsDockCoverIndexEnum.class, val)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsFaqIdEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsFaqIdEnum.java new file mode 100644 index 0000000..aac4e98 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsFaqIdEnum.java @@ -0,0 +1,43 @@ +package org.dromara.common.sdk.cloudapi.hms; + +import org.dromara.common.sdk.cloudapi.device.DeviceDomainEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsFaqIdEnum { + + DOCK_TIP("dock_tip_", DeviceDomainEnum.DOCK), + + FPV_TIP("fpv_tip_", DeviceDomainEnum.DRONE); + + private final String text; + + private final DeviceDomainEnum domain; + + @JsonValue + public String getText() { + return text; + } + + public DeviceDomainEnum getDomain() { + return domain; + } + + HmsFaqIdEnum(String text, DeviceDomainEnum domain) { + this.text = text; + this.domain = domain; + } + + public static HmsFaqIdEnum find(DeviceDomainEnum domain) { + return Arrays.stream(values()).filter(faqIdEnum -> faqIdEnum.domain == domain).findAny() + .orElseThrow(() -> new CloudSDKException(HmsFaqIdEnum.class, domain)); + } +} + diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsFormatKeyEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsFormatKeyEnum.java new file mode 100644 index 0000000..6c7cdad --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsFormatKeyEnum.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.cloudapi.hms; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsFormatKeyEnum { + + ALARM_ID("%alarmid"), + + COMPONENT_INDEX("%component_index"), + + INDEX("%index"), + + BATTERY_INDEX("%battery_index"), + + DOCK_COVER_INDEX("%dock_cover_index"), + + CHARGING_ROD_INDEX("%charging_rod_index"); + +// public static final char KEY_START = '%'; + + private final String key; + + HmsFormatKeyEnum(String key) { + this.key = key; + } + + @JsonValue + public String getKey() { + return key; + } + + public static HmsFormatKeyEnum find(String key) { + return Arrays.stream(HmsFormatKeyEnum.values()).filter(format -> format.getKey().equals(key)).findAny() + .orElseThrow(() -> new CloudSDKException(HmsFormatKeyEnum.class, key)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsInTheSkyEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsInTheSkyEnum.java new file mode 100644 index 0000000..11eb44b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsInTheSkyEnum.java @@ -0,0 +1,24 @@ +package org.dromara.common.sdk.cloudapi.hms; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsInTheSkyEnum { + + IN_THE_SKY("_in_the_sky"); + + private final String text; + + HmsInTheSkyEnum(String text) { + this.text = text; + } + + @JsonValue + public String getText() { + return text; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsLevelEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsLevelEnum.java new file mode 100644 index 0000000..5e9bbb0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsLevelEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.hms; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public enum HmsLevelEnum { + + INFORM(0), + + NOTICE(1), + + ALARM(2); + + private final int level; + + HmsLevelEnum(int level) { + this.level = level; + } + + @JsonValue + public int getLevel() { + return level; + } + + @JsonCreator + public static HmsLevelEnum find(int level) { + return Arrays.stream(values()).filter(levelEnum -> levelEnum.level == level).findAny() + .orElseThrow(() -> new CloudSDKException(HmsLevelEnum.class, level)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsMessageLanguageEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsMessageLanguageEnum.java new file mode 100644 index 0000000..5e5d3bb --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsMessageLanguageEnum.java @@ -0,0 +1,23 @@ +package org.dromara.common.sdk.cloudapi.hms; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +public enum HmsMessageLanguageEnum { + + EN("en"), + + ZH("zh"); + + private final String language; + + HmsMessageLanguageEnum(String language) { + this.language = language; + } + + public String getLanguage() { + return language; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsModuleEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsModuleEnum.java new file mode 100644 index 0000000..b2f95b5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/HmsModuleEnum.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.hms; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public enum HmsModuleEnum { + + FLIGHT_MISSION(0), + + DEVICE_MANAGEMENT(1), + + MEDIA(2), + + HMS(3); + + private final int module; + + HmsModuleEnum(int module) { + this.module = module; + } + + @JsonValue + public int getModule() { + return module; + } + + @JsonCreator + public static HmsModuleEnum find(int module) { + return Arrays.stream(values()).filter(moduleEnum -> moduleEnum.module == module).findAny() + .orElseThrow(() -> new CloudSDKException(HmsModuleEnum.class, module)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/api/AbstractHmsService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/api/AbstractHmsService.java new file mode 100644 index 0000000..c407cb9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/hms/api/AbstractHmsService.java @@ -0,0 +1,27 @@ +package org.dromara.common.sdk.cloudapi.hms.api; + +import org.dromara.common.sdk.cloudapi.hms.Hms; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.events.TopicEventsRequest; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.MessageHeaders; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public abstract class AbstractHmsService { + + /** + * Reporting of hms + * @param response + * @param headers + * @return + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_HMS) + public void hms(TopicEventsRequest response, MessageHeaders headers) { + throw new UnsupportedOperationException("hms not implemented"); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionFromEsdk.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionFromEsdk.java new file mode 100644 index 0000000..52e2a20 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionFromEsdk.java @@ -0,0 +1,34 @@ +package org.dromara.common.sdk.cloudapi.interconnection; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public class CustomDataTransmissionFromEsdk { + + /** + * Data content + * length: Less than 256 + */ + private String value; + + public CustomDataTransmissionFromEsdk() { + } + + @Override + public String toString() { + return "CustomDataTransmissionFromEsdk{" + + "value='" + value + '\'' + + '}'; + } + + public String getValue() { + return value; + } + + public CustomDataTransmissionFromEsdk setValue(String value) { + this.value = value; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionFromPsdk.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionFromPsdk.java new file mode 100644 index 0000000..c9188b3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionFromPsdk.java @@ -0,0 +1,34 @@ +package org.dromara.common.sdk.cloudapi.interconnection; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public class CustomDataTransmissionFromPsdk { + + /** + * Data content + * length: Less than 256 + */ + private String value; + + public CustomDataTransmissionFromPsdk() { + } + + @Override + public String toString() { + return "CustomDataTransmissionFromPsdk{" + + "value='" + value + '\'' + + '}'; + } + + public String getValue() { + return value; + } + + public CustomDataTransmissionFromPsdk setValue(String value) { + this.value = value; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionToEsdkRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionToEsdkRequest.java new file mode 100644 index 0000000..ce6f38d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionToEsdkRequest.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.interconnection; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; +import org.hibernate.validator.constraints.Length; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public class CustomDataTransmissionToEsdkRequest extends BaseModel { + + /** + * Data content + * length: Less than 256 + */ + @NotNull + @Length(max = 256) + private String value; + + public CustomDataTransmissionToEsdkRequest() { + } + + @Override + public String toString() { + return "CustomDataTransmissionToEsdkRequest{" + + "value='" + value + '\'' + + '}'; + } + + public String getValue() { + return value; + } + + public CustomDataTransmissionToEsdkRequest setValue(String value) { + this.value = value; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionToPsdkRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionToPsdkRequest.java new file mode 100644 index 0000000..f0f9050 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/CustomDataTransmissionToPsdkRequest.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.interconnection; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; +import org.hibernate.validator.constraints.Length; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public class CustomDataTransmissionToPsdkRequest extends BaseModel { + + /** + * Data content + * length: Less than 256 + */ + @NotNull + @Length(max = 256) + private String value; + + public CustomDataTransmissionToPsdkRequest() { + } + + @Override + public String toString() { + return "CustomDataTransmissionToPsdkRequest{" + + "value='" + value + '\'' + + '}'; + } + + public String getValue() { + return value; + } + + public CustomDataTransmissionToPsdkRequest setValue(String value) { + this.value = value; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/InterconnectionMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/InterconnectionMethodEnum.java new file mode 100644 index 0000000..817cb29 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/InterconnectionMethodEnum.java @@ -0,0 +1,29 @@ +package org.dromara.common.sdk.cloudapi.interconnection; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public enum InterconnectionMethodEnum { + + CUSTOM_DATA_TRANSMISSION_TO_ESDK("custom_data_transmission_to_esdk"), + + CUSTOM_DATA_TRANSMISSION_TO_PSDK("custom_data_transmission_to_psdk"), + + ; + + private final String method; + + InterconnectionMethodEnum(String method) { + this.method = method; + } + + @JsonValue + public String getMethod() { + return method; + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/api/AbstractInterconnectionService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/api/AbstractInterconnectionService.java new file mode 100644 index 0000000..2b8051a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/interconnection/api/AbstractInterconnectionService.java @@ -0,0 +1,83 @@ +package org.dromara.common.sdk.cloudapi.interconnection.api; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.interconnection.CustomDataTransmissionFromEsdk; +import org.dromara.common.sdk.cloudapi.interconnection.CustomDataTransmissionToEsdkRequest; +import org.dromara.common.sdk.cloudapi.interconnection.CustomDataTransmissionToPsdkRequest; +import org.dromara.common.sdk.cloudapi.interconnection.InterconnectionMethodEnum; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.events.TopicEventsRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsResponse; +import org.dromara.common.sdk.mqtt.services.ServicesPublish; +import org.dromara.common.sdk.mqtt.services.ServicesReplyData; +import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; +import jakarta.annotation.Resource; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/16 + */ +public abstract class AbstractInterconnectionService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * cloud-custom data transmit from esdk + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_CUSTOM_DATA_TRANSMISSION_FROM_ESDK, outputChannel = ChannelName.OUTBOUND_EVENTS) + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + public TopicEventsResponse customDataTransmissionFromEsdk(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("customDataTransmissionFromEsdk not implemented"); + } + + /** + * cloud-custom data transmit to esdk + * @param gateway gateway device + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0, exclude = GatewayTypeEnum.RC) + public TopicServicesResponse customDataTransmissionToEsdk(GatewayManager gateway, CustomDataTransmissionToEsdkRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + InterconnectionMethodEnum.CUSTOM_DATA_TRANSMISSION_TO_ESDK.getMethod(), + request); + } + + /** + * cloud-custom data transmit from psdk + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_CUSTOM_DATA_TRANSMISSION_FROM_PSDK, outputChannel = ChannelName.OUTBOUND_EVENTS) + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + public TopicEventsResponse customDataTransmissionFromPsdk(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("customDataTransmissionFromPsdk not implemented"); + } + + /** + * cloud-custom data transmit to psdk + * @param gateway gateway device + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0, exclude = GatewayTypeEnum.RC) + public TopicServicesResponse customDataTransmissionToPsdk(GatewayManager gateway, CustomDataTransmissionToPsdkRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + InterconnectionMethodEnum.CUSTOM_DATA_TRANSMISSION_TO_PSDK.getMethod(), + request); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacity.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacity.java new file mode 100644 index 0000000..c612894 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacity.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class DockLiveCapacity { + + /** + * Total number of video streams available for livestreaming. + * Indicates the total number of all available live video streams owned by the aircraft or device. + */ + private Integer availableVideoNumber; + + /** + * Maximum total number of video streams that can be lived stream simultaneously. + */ + private Integer coexistVideoNumberMax; + + /** + * Device live streaming capability list + */ + private List deviceList; + + public DockLiveCapacity() { + } + + @Override + public String toString() { + return "DockLiveCapacity{" + + "availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", deviceList=" + deviceList + + '}'; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public DockLiveCapacity setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public DockLiveCapacity setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public List getDeviceList() { + return deviceList; + } + + public DockLiveCapacity setDeviceList(List deviceList) { + this.deviceList = deviceList; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacityCamera.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacityCamera.java new file mode 100644 index 0000000..6922395 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacityCamera.java @@ -0,0 +1,80 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class DockLiveCapacityCamera { + + /** + * Total number of video streams that can be used for livestreaming + * Total number of video streams that the camera can live stream + */ + private Integer availableVideoNumber; + + /** + * Maximum number of video streams that the camera can live stream at the same time. + */ + private Integer coexistVideoNumberMax; + + /** + * Camera index, composed of product type enumeration and gimbal index. + */ + private PayloadIndex cameraIndex; + + private List videoList; + + public DockLiveCapacityCamera() { + } + + @Override + public String toString() { + return "DockLiveCapacityCamera{" + + "availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", cameraIndex=" + cameraIndex + + ", videoList=" + videoList + + '}'; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public DockLiveCapacityCamera setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public DockLiveCapacityCamera setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public PayloadIndex getCameraIndex() { + return cameraIndex; + } + + public DockLiveCapacityCamera setCameraIndex(PayloadIndex cameraIndex) { + this.cameraIndex = cameraIndex; + return this; + } + + public List getVideoList() { + return videoList; + } + + public DockLiveCapacityCamera setVideoList(List videoList) { + this.videoList = videoList; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacityDevice.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacityDevice.java new file mode 100644 index 0000000..9784c26 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacityDevice.java @@ -0,0 +1,81 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class DockLiveCapacityDevice { + + /** + * Device serial number + */ + private String sn; + + /** + * Total number of video streams that can be used for livestreaming + * Total number of video streams used for livestreaming that belongs to devices. + */ + private Integer availableVideoNumber; + + /** + * Maximum number of video streams that can be used for livestreaming at the same time + */ + private Integer coexistVideoNumberMax; + + /** + * Camera list on the device + */ + private List cameraList; + + public DockLiveCapacityDevice() { + } + + @Override + public String toString() { + return "DockLiveCapacityDevice{" + + "sn='" + sn + '\'' + + ", availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", cameraList=" + cameraList + + '}'; + } + + public String getSn() { + return sn; + } + + public DockLiveCapacityDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public DockLiveCapacityDevice setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public DockLiveCapacityDevice setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public List getCameraList() { + return cameraList; + } + + public DockLiveCapacityDevice setCameraList(List cameraList) { + this.cameraList = cameraList; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacityVideo.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacityVideo.java new file mode 100644 index 0000000..4098a53 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLiveCapacityVideo.java @@ -0,0 +1,56 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class DockLiveCapacityVideo { + + private String videoIndex; + + private VideoTypeEnum videoType; + + private List switchableVideoTypes; + + public DockLiveCapacityVideo() { + } + + @Override + public String toString() { + return "DockLiveCapacityVideo{" + + "videoIndex='" + videoIndex + '\'' + + ", videoType=" + videoType + + ", switchableVideoTypes=" + switchableVideoTypes + + '}'; + } + + public String getVideoIndex() { + return videoIndex; + } + + public DockLiveCapacityVideo setVideoIndex(String videoIndex) { + this.videoIndex = videoIndex; + return this; + } + + public VideoTypeEnum getVideoType() { + return videoType; + } + + public DockLiveCapacityVideo setVideoType(VideoTypeEnum videoType) { + this.videoType = videoType; + return this; + } + + public List getSwitchableVideoTypes() { + return switchableVideoTypes; + } + + public DockLiveCapacityVideo setSwitchableVideoTypes(List switchableVideoTypes) { + this.switchableVideoTypes = switchableVideoTypes; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLivestreamAbilityUpdate.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLivestreamAbilityUpdate.java new file mode 100644 index 0000000..9dda75a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/DockLivestreamAbilityUpdate.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class DockLivestreamAbilityUpdate { + + private DockLiveCapacity liveCapacity; + + public DockLivestreamAbilityUpdate() { + } + + @Override + public String toString() { + return "DockLivestreamAbilityUpdate{" + + "liveCapacity=" + liveCapacity + + '}'; + } + + public DockLiveCapacity getLiveCapacity() { + return liveCapacity; + } + + public DockLivestreamAbilityUpdate setLiveCapacity(DockLiveCapacity liveCapacity) { + this.liveCapacity = liveCapacity; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/ILivestreamUrl.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/ILivestreamUrl.java new file mode 100644 index 0000000..a0a29dc --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/ILivestreamUrl.java @@ -0,0 +1,16 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/13 + */ +public interface ILivestreamUrl { + + @JsonValue + String toString(); + + ILivestreamUrl clone(); +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LensChangeVideoTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LensChangeVideoTypeEnum.java new file mode 100644 index 0000000..89f943b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LensChangeVideoTypeEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/25 + */ +public enum LensChangeVideoTypeEnum { + + ZOOM("zoom"), + + WIDE("wide"), + + IR("ir"); + + private final String type; + + LensChangeVideoTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static LensChangeVideoTypeEnum find(String videoType) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(videoType)).findAny() + .orElseThrow(() -> new CloudSDKException(LensChangeVideoTypeEnum.class , videoType)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveErrorCodeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveErrorCodeEnum.java new file mode 100644 index 0000000..52d504b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveErrorCodeEnum.java @@ -0,0 +1,82 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.common.IErrorInfo; +import org.dromara.common.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum LiveErrorCodeEnum implements IServicesErrorCode, IErrorInfo { + + SUCCESS(0, "Success"), + + NO_AIRCRAFT(13001, "没有飞机。"), + + NO_CAMERA(13002, "没有摄像头。"), + + LIVE_STREAM_ALREADY_STARTED(13003, "摄像机已开始直播。"), + + FUNCTION_NOT_SUPPORT(13004, "不支持该功能。"), + + STRATEGY_NOT_SUPPORT(13005, "该策略不受支持。"), + + NOT_IN_CAMERA_INTERFACE(13006, "当前应用程序不在相机界面中。"), + + NO_FLIGHT_CONTROL(13007, "遥控器没有飞行控制权,无法响应控制命令"), + + NO_STREAM_DATA(13008, "当前应用程序没有流数据。"), + + TOO_FREQUENT(13009, "操作过于频繁。"), + + ENABLE_FAILED(13010, "请检查直播服务是否正常。"), + + NO_LIVE_STREAM(13011, "目前没有直播。"), + + SWITCH_NOT_SUPPORT(13012, "直播中已经有另一台摄像机。不支持直接切换流。"), + + URL_TYPE_NOT_SUPPORTED(13013, "不支持此url类型。"), + + ERROR_PARAMETERS(13014, "直播参数异常或不完整。"), + + NETWORK_CONGESTION(13015, "请检查网络。"), + + ERROR_FRAME(13016, "实时解码失败。"), + + DEVICE_UNKNOWN(13099, "设备内部出现未知错误。"), + + UNKNOWN(-1, "UNKNOWN"), + ; + + + private final String msg; + + private final int code; + + LiveErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + /** + * @param code error code + * @return enumeration object + */ + public static LiveErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveLensChangeRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveLensChangeRequest.java new file mode 100644 index 0000000..550300f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveLensChangeRequest.java @@ -0,0 +1,53 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.cloudapi.device.VideoId; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class LiveLensChangeRequest extends BaseModel { + + @NotNull + private LensChangeVideoTypeEnum videoType; + + /** + * The format is #{uav_sn}/#{camera_id}/#{video_index}, + * drone serial number/payload and mounted location enumeration value/payload lens numbering + */ + @NotNull + private VideoId videoId; + + public LiveLensChangeRequest() { + } + + @Override + public String toString() { + return "LiveLensChangeRequest{" + + "videoType=" + videoType + + ", videoId=" + videoId + + '}'; + } + + public LensChangeVideoTypeEnum getVideoType() { + return videoType; + } + + public LiveLensChangeRequest setVideoType(LensChangeVideoTypeEnum videoType) { + this.videoType = videoType; + return this; + } + + public VideoId getVideoId() { + return videoId; + } + + public LiveLensChangeRequest setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveSetQualityRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveSetQualityRequest.java new file mode 100644 index 0000000..de756d5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveSetQualityRequest.java @@ -0,0 +1,53 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.cloudapi.device.VideoId; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class LiveSetQualityRequest extends BaseModel { + + /** + * The format is #{uav_sn}/#{camera_id}/#{video_index}, + * drone serial number/payload and mounted location enumeration value/payload lens numbering + */ + @NotNull + private VideoId videoId; + + @NotNull + private VideoQualityEnum videoQuality; + + public LiveSetQualityRequest() { + } + + @Override + public String toString() { + return "LiveSetQualityRequest{" + + "videoId=" + videoId + + ", videoQuality=" + videoQuality + + '}'; + } + + public VideoId getVideoId() { + return videoId; + } + + public LiveSetQualityRequest setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } + + public VideoQualityEnum getVideoQuality() { + return videoQuality; + } + + public LiveSetQualityRequest setVideoQuality(VideoQualityEnum videoQuality) { + this.videoQuality = videoQuality; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveStartPushRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveStartPushRequest.java new file mode 100644 index 0000000..e9c3b87 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveStartPushRequest.java @@ -0,0 +1,94 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.cloudapi.device.VideoId; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class LiveStartPushRequest extends BaseModel { + + @NotNull + private UrlTypeEnum urlType; + + /** + * RTMP: (rtmp://xxxxxxx) Example: rtmp://192.168.1.1:8080/live + * RTSP:(uerName&password&port) Example: userName=dji-cloud-api&password=123456&port=8080 + * GB28181:(serverIP&serverPort&serverID&agentID&agentPassword&localPort&channel) + * Example: serverIP=192.168.1.1&serverPort=8080&serverID=34000000000000000000&agentID= + * 300000000010000000000&agentPassword=0000000&localPort=7060&channel=340000000000000000000 + * AGORA:(channel&sn&token&uid) + * Example: channel=1ZNDH360010162_39-0-7&sn=1ZNDH360010162&token=006dca67721582a48768ec4d8 + * 17b7b25a86IAB4cw2JgN6iX8BpTPdc3e4S1Iendz94IFJ56aSXKvzAJei27MqF2zyCIgCLIIoBt41+YAQAAQC3jX + * 5gAgC3jX5gAwC3jX5gBAC3jX5g&uid=50000 + * Notice: The token generated by Shengwang may have special characters such as '+' ' ', + * and need to do url encode, otherwise there will be a parsing error on the PILOT side + */ + @NotNull + @Valid + private ILivestreamUrl url; + + /** + * The format is #{uav_sn}/#{camera_id}/#{video_index}, + * drone serial number/payload and mounted location enumeration value/payload lens numbering + */ + @NotNull + private VideoId videoId; + + @NotNull + private VideoQualityEnum videoQuality; + + public LiveStartPushRequest() { + } + + @Override + public String toString() { + return "LiveStartPushRequest{" + + "urlType=" + urlType + + ", url=" + url + + ", videoId=" + videoId + + ", videoQuality=" + videoQuality + + '}'; + } + + public UrlTypeEnum getUrlType() { + return urlType; + } + + public LiveStartPushRequest setUrlType(UrlTypeEnum urlType) { + this.urlType = urlType; + return this; + } + + public ILivestreamUrl getUrl() { + return url; + } + + public LiveStartPushRequest setUrl(ILivestreamUrl url) { + this.url = url; + return this; + } + + public VideoId getVideoId() { + return videoId; + } + + public LiveStartPushRequest setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } + + public VideoQualityEnum getVideoQuality() { + return videoQuality; + } + + public LiveStartPushRequest setVideoQuality(VideoQualityEnum videoQuality) { + this.videoQuality = videoQuality; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveStopPushRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveStopPushRequest.java new file mode 100644 index 0000000..ae739ba --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveStopPushRequest.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.cloudapi.device.VideoId; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class LiveStopPushRequest extends BaseModel { + + /** + * The format is #{uav_sn}/#{camera_id}/#{video_index}, + * drone serial number/payload and mounted location enumeration value/payload lens numbering + */ + @NotNull + private VideoId videoId; + + public LiveStopPushRequest() { + } + + @Override + public String toString() { + return "LiveStopPushRequest{" + + "videoId=" + videoId + + '}'; + } + + public VideoId getVideoId() { + return videoId; + } + + public LiveStopPushRequest setVideoId(VideoId videoId) { + this.videoId = videoId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveStreamMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveStreamMethodEnum.java new file mode 100644 index 0000000..d90c2fa --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LiveStreamMethodEnum.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum LiveStreamMethodEnum { + + LIVE_START_PUSH("live_start_push"), + + LIVE_STOP_PUSH("live_stop_push"), + + LIVE_SET_QUALITY("live_set_quality"), + + LIVE_LENS_CHANGE("live_lens_change"); + + private final String method; + + LiveStreamMethodEnum(String method) { + this.method = method; + } + + @JsonValue + public String getMethod() { + return method; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamAgoraUrl.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamAgoraUrl.java new file mode 100644 index 0000000..747ea60 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamAgoraUrl.java @@ -0,0 +1,83 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + +import java.net.URLEncoder; +import java.nio.charset.Charset; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/13 + */ +public class LivestreamAgoraUrl extends BaseModel implements ILivestreamUrl { + + @NotNull + private String channel; + + @NotNull + private String sn; + + @NotNull + private String token; + + @NotNull + private Integer uid; + + public LivestreamAgoraUrl() { + } + + @Override + public String toString() { + return "channel=" + channel + + "&sn=" + sn + + "&token=" + URLEncoder.encode(token, Charset.defaultCharset()) + + "&uid=" + uid; + } + + @Override + public LivestreamAgoraUrl clone() { + try { + return (LivestreamAgoraUrl) super.clone(); + } catch (CloneNotSupportedException e) { + return new LivestreamAgoraUrl().setSn(sn).setToken(token).setChannel(channel).setUid(uid); + } + } + + public String getChannel() { + return channel; + } + + public LivestreamAgoraUrl setChannel(String channel) { + this.channel = channel; + return this; + } + + public String getSn() { + return sn; + } + + public LivestreamAgoraUrl setSn(String sn) { + this.sn = sn; + return this; + } + + public String getToken() { + return token; + } + + public LivestreamAgoraUrl setToken(String token) { + this.token = token; + return this; + } + + public Integer getUid() { + return uid; + } + + public LivestreamAgoraUrl setUid(Integer uid) { + this.uid = uid; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamGb28181Url.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamGb28181Url.java new file mode 100644 index 0000000..510e1fd --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamGb28181Url.java @@ -0,0 +1,127 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/13 + */ +public class LivestreamGb28181Url extends BaseModel implements ILivestreamUrl { + + @NotNull + private String serverIP; + + @NotNull + private Integer serverPort; + + @NotNull + private String serverID; + + @NotNull + private String agentID; + + @NotNull + private String agentPassword; + + @NotNull + private Integer localPort; + + @NotNull + private String channel; + + public LivestreamGb28181Url() { + } + + @Override + public String toString() { + return "serverIP=" + serverIP + + "&serverPort=" + serverPort + + "&serverID=" + serverID + + "&agentID=" + agentID + + "&agentPassword=" + agentPassword + + "&localPort=" + localPort + + "&channel=" + channel; + } + + @Override + public LivestreamGb28181Url clone() { + try { + return (LivestreamGb28181Url) super.clone(); + } catch (CloneNotSupportedException e) { + return new LivestreamGb28181Url() + .setServerIP(serverIP) + .setServerPort(serverPort) + .setServerID(serverID) + .setAgentID(agentID) + .setAgentPassword(agentPassword) + .setLocalPort(localPort) + .setChannel(channel); + } + } + + public String getServerIP() { + return serverIP; + } + + public LivestreamGb28181Url setServerIP(String serverIP) { + this.serverIP = serverIP; + return this; + } + + public Integer getServerPort() { + return serverPort; + } + + public LivestreamGb28181Url setServerPort(Integer serverPort) { + this.serverPort = serverPort; + return this; + } + + public String getServerID() { + return serverID; + } + + public LivestreamGb28181Url setServerID(String serverID) { + this.serverID = serverID; + return this; + } + + public String getAgentID() { + return agentID; + } + + public LivestreamGb28181Url setAgentID(String agentID) { + this.agentID = agentID; + return this; + } + + public String getAgentPassword() { + return agentPassword; + } + + public LivestreamGb28181Url setAgentPassword(String agentPassword) { + this.agentPassword = agentPassword; + return this; + } + + public Integer getLocalPort() { + return localPort; + } + + public LivestreamGb28181Url setLocalPort(Integer localPort) { + this.localPort = localPort; + return this; + } + + public String getChannel() { + return channel; + } + + public LivestreamGb28181Url setChannel(String channel) { + this.channel = channel; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamRtmpUrl.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamRtmpUrl.java new file mode 100644 index 0000000..f35d948 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamRtmpUrl.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/13 + */ +public class LivestreamRtmpUrl extends BaseModel implements ILivestreamUrl { + + @NotNull + private String url; + + public LivestreamRtmpUrl() { + } + + @Override + public String toString() { + return url; + } + + @Override + public LivestreamRtmpUrl clone() { + try { + return (LivestreamRtmpUrl) super.clone(); + } catch (CloneNotSupportedException e) { + return new LivestreamRtmpUrl().setUrl(url); + } + } + + public LivestreamRtmpUrl setUrl(String url) { + this.url = url; + return this; + } + + public String getUrl() { + return url; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamRtspUrl.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamRtspUrl.java new file mode 100644 index 0000000..e93b1c8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamRtspUrl.java @@ -0,0 +1,68 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/13 + */ +public class LivestreamRtspUrl extends BaseModel implements ILivestreamUrl { + + @NotNull + private String username; + + @NotNull + private String password; + + @NotNull + private Integer port; + + public LivestreamRtspUrl() { + } + + @Override + public String toString() { + return "userName=" + username + + "&password=" + password + + "&port=" + port; + } + + @Override + public LivestreamRtspUrl clone() { + try { + return (LivestreamRtspUrl) super.clone(); + } catch (CloneNotSupportedException e) { + return new LivestreamRtspUrl().setUsername(username).setPassword(password).setPort(port); + } + } + + public String getUsername() { + return username; + } + + public LivestreamRtspUrl setUsername(String username) { + this.username = username; + return this; + } + + public String getPassword() { + return password; + } + + public LivestreamRtspUrl setPassword(String password) { + this.password = password; + return this; + } + + public Integer getPort() { + return port; + } + + public LivestreamRtspUrl setPort(Integer port) { + this.port = port; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamWhipUrl.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamWhipUrl.java new file mode 100644 index 0000000..209a056 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/LivestreamWhipUrl.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/13 + */ +public class LivestreamWhipUrl extends BaseModel implements ILivestreamUrl { + + @NotNull + private String url; + + public LivestreamWhipUrl() { + } + + @Override + public String toString() { + return url; + } + + @Override + public LivestreamWhipUrl clone() { + try { + return (LivestreamWhipUrl) super.clone(); + } catch (CloneNotSupportedException e) { + return new LivestreamWhipUrl().setUrl(url); + } + } + + public String getUrl() { + return url; + } + + public LivestreamWhipUrl setUrl(String url) { + this.url = url; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacity.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacity.java new file mode 100644 index 0000000..b7e0c9f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacity.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class RcLiveCapacity { + + /** + * Total number of video streams available for livestreaming. + * Indicates the total number of all available live video streams owned by the aircraft or device. + */ + private Integer availableVideoNumber; + + /** + * Maximum total number of video streams that can be lived stream simultaneously. + */ + private Integer coexistVideoNumberMax; + + /** + * Device live streaming capability list + */ + private List deviceList; + + public RcLiveCapacity() { + } + + @Override + public String toString() { + return "RcLiveCapacity{" + + "availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", deviceList=" + deviceList + + '}'; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public RcLiveCapacity setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public RcLiveCapacity setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public List getDeviceList() { + return deviceList; + } + + public RcLiveCapacity setDeviceList(List deviceList) { + this.deviceList = deviceList; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacityCamera.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacityCamera.java new file mode 100644 index 0000000..55715dd --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacityCamera.java @@ -0,0 +1,80 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class RcLiveCapacityCamera { + + /** + * Total number of video streams that can be used for livestreaming + * Total number of video streams that the camera can live stream + */ + private Integer availableVideoNumber; + + /** + * Maximum number of video streams that the camera can live stream at the same time. + */ + private Integer coexistVideoNumberMax; + + /** + * Camera index, composed of product type enumeration and gimbal index. + */ + private PayloadIndex cameraIndex; + + private List videoList; + + public RcLiveCapacityCamera() { + } + + @Override + public String toString() { + return "RcLiveCapacityCamera{" + + "availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", cameraIndex=" + cameraIndex + + ", videoList=" + videoList + + '}'; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public RcLiveCapacityCamera setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public RcLiveCapacityCamera setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public PayloadIndex getCameraIndex() { + return cameraIndex; + } + + public RcLiveCapacityCamera setCameraIndex(PayloadIndex cameraIndex) { + this.cameraIndex = cameraIndex; + return this; + } + + public List getVideoList() { + return videoList; + } + + public RcLiveCapacityCamera setVideoList(List videoList) { + this.videoList = videoList; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacityDevice.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacityDevice.java new file mode 100644 index 0000000..4d67eec --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacityDevice.java @@ -0,0 +1,81 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class RcLiveCapacityDevice { + + /** + * Device serial number + */ + private String sn; + + /** + * Total number of video streams that can be used for livestreaming + * Total number of video streams used for livestreaming that belongs to devices. + */ + private Integer availableVideoNumber; + + /** + * Maximum number of video streams that can be used for livestreaming at the same time + */ + private Integer coexistVideoNumberMax; + + /** + * Camera list on the device + */ + private List cameraList; + + public RcLiveCapacityDevice() { + } + + @Override + public String toString() { + return "RcLiveCapacityDevice{" + + "sn='" + sn + '\'' + + ", availableVideoNumber=" + availableVideoNumber + + ", coexistVideoNumberMax=" + coexistVideoNumberMax + + ", cameraList=" + cameraList + + '}'; + } + + public String getSn() { + return sn; + } + + public RcLiveCapacityDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public Integer getAvailableVideoNumber() { + return availableVideoNumber; + } + + public RcLiveCapacityDevice setAvailableVideoNumber(Integer availableVideoNumber) { + this.availableVideoNumber = availableVideoNumber; + return this; + } + + public Integer getCoexistVideoNumberMax() { + return coexistVideoNumberMax; + } + + public RcLiveCapacityDevice setCoexistVideoNumberMax(Integer coexistVideoNumberMax) { + this.coexistVideoNumberMax = coexistVideoNumberMax; + return this; + } + + public List getCameraList() { + return cameraList; + } + + public RcLiveCapacityDevice setCameraList(List cameraList) { + this.cameraList = cameraList; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacityVideo.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacityVideo.java new file mode 100644 index 0000000..4dcf93f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLiveCapacityVideo.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public class RcLiveCapacityVideo { + + private String videoIndex; + + private VideoTypeEnum videoType; + + public RcLiveCapacityVideo() { + } + + @Override + public String toString() { + return "RcLiveCapacityVideo{" + + "videoIndex='" + videoIndex + '\'' + + ", videoType=" + videoType + + '}'; + } + + public String getVideoIndex() { + return videoIndex; + } + + public RcLiveCapacityVideo setVideoIndex(String videoIndex) { + this.videoIndex = videoIndex; + return this; + } + + public VideoTypeEnum getVideoType() { + return videoType; + } + + public RcLiveCapacityVideo setVideoType(VideoTypeEnum videoType) { + this.videoType = videoType; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLivestreamAbilityUpdate.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLivestreamAbilityUpdate.java new file mode 100644 index 0000000..57585f9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/RcLivestreamAbilityUpdate.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class RcLivestreamAbilityUpdate { + + private RcLiveCapacity liveCapacity; + + public RcLivestreamAbilityUpdate() { + } + + @Override + public String toString() { + return "RcLivestreamAbilityUpdate{" + + "liveCapacity=" + liveCapacity + + '}'; + } + + public RcLiveCapacity getLiveCapacity() { + return liveCapacity; + } + + public RcLivestreamAbilityUpdate setLiveCapacity(RcLiveCapacity liveCapacity) { + this.liveCapacity = liveCapacity; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/UrlTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/UrlTypeEnum.java new file mode 100644 index 0000000..1426590 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/UrlTypeEnum.java @@ -0,0 +1,43 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/22 + */ +public enum UrlTypeEnum { + + AGORA(0), + + RTMP(1), + + RTSP(2), + + GB28181(3), + + WHIP(4), + ; + + private final int type; + + UrlTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static UrlTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(UrlTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/VideoQualityEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/VideoQualityEnum.java new file mode 100644 index 0000000..f75f890 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/VideoQualityEnum.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 0.1 + * @date 2021/11/26 + */ +public enum VideoQualityEnum { + + AUTO (0), + + SMOOTH(1), + + STANDARD_DEFINITION(2), + + HIGH_DEFINITION(3), + + ULTRA_HD(4); + + private final int quality; + + VideoQualityEnum(int quality) { + this.quality = quality; + } + + @JsonValue + public int getQuality() { + return quality; + } + + @JsonCreator + public static VideoQualityEnum find(int quality) { + return Arrays.stream(values()).filter(qualityEnum -> qualityEnum.quality == quality).findAny() + .orElseThrow(() -> new CloudSDKException(VideoQualityEnum.class, quality)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/VideoTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/VideoTypeEnum.java new file mode 100644 index 0000000..0003810 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/VideoTypeEnum.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.livestream; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/25 + */ +public enum VideoTypeEnum { + + ZOOM("zoom"), + + WIDE("wide"), + + THERMAL("thermal"), + + NORMAL("normal"), + + IR("ir"); + + private final String type; + + VideoTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static VideoTypeEnum find(String videoType) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(videoType)).findAny() + .orElseThrow(() -> new CloudSDKException(VideoTypeEnum.class , videoType)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/api/AbstractLivestreamService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/api/AbstractLivestreamService.java new file mode 100644 index 0000000..d8a13fa --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/livestream/api/AbstractLivestreamService.java @@ -0,0 +1,107 @@ +package org.dromara.common.sdk.cloudapi.livestream.api; + +import org.dromara.common.sdk.cloudapi.livestream.*; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.services.ServicesPublish; +import org.dromara.common.sdk.mqtt.services.ServicesReplyData; +import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; +import org.dromara.common.sdk.mqtt.state.TopicStateRequest; +import com.fasterxml.jackson.core.type.TypeReference; +import jakarta.annotation.Resource; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public abstract class AbstractLivestreamService { + + @Resource + private ServicesPublish servicesPublish; + + private static final long DEFAULT_TIMEOUT = 20_000; + + /** + * Livestream ability update for remote control + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_LIVESTREAM_ABILITY_UPDATE) + public void dockLivestreamAbilityUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockLivestreamAbilityUpdate not implemented"); + } + + /** + * Livestream ability update for dock + * @param request data + * @param headers The headers for a {@link Message}. + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_RC_LIVESTREAM_ABILITY_UPDATE) + public void rcLivestreamAbilityUpdate(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("rcLivestreamAbilityUpdate not implemented"); + } + + /** + * Start livestreaming + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse> liveStartPush(GatewayManager gateway, LiveStartPushRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + LiveStreamMethodEnum.LIVE_START_PUSH.getMethod(), + request, + DEFAULT_TIMEOUT); + } + + /** + * Stop livestreaming + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse liveStopPush(GatewayManager gateway, LiveStopPushRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + LiveStreamMethodEnum.LIVE_STOP_PUSH.getMethod(), + request, + DEFAULT_TIMEOUT); + } + + /** + * Set livestream quality + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse liveSetQuality(GatewayManager gateway, LiveSetQualityRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + LiveStreamMethodEnum.LIVE_SET_QUALITY.getMethod(), + request, + DEFAULT_TIMEOUT); + } + + /** + * Set livestream lens + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse liveLensChange(GatewayManager gateway, LiveLensChangeRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + LiveStreamMethodEnum.LIVE_LENS_CHANGE.getMethod(), + request, + DEFAULT_TIMEOUT); + } + + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadListFile.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadListFile.java new file mode 100644 index 0000000..696204d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadListFile.java @@ -0,0 +1,68 @@ +package org.dromara.common.sdk.cloudapi.log; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public class FileUploadListFile { + + private String deviceSn; + + private List list; + + private LogModuleEnum module; + + private Integer result; + + public FileUploadListFile() { + } + + @Override + public String toString() { + return "FileUploadListFile{" + + "deviceSn='" + deviceSn + '\'' + + ", list=" + list + + ", module=" + module + + ", result=" + result + + '}'; + } + + public String getDeviceSn() { + return deviceSn; + } + + public FileUploadListFile setDeviceSn(String deviceSn) { + this.deviceSn = deviceSn; + return this; + } + + public List getList() { + return list; + } + + public FileUploadListFile setList(List list) { + this.list = list; + return this; + } + + public LogModuleEnum getModule() { + return module; + } + + public FileUploadListFile setModule(LogModuleEnum module) { + this.module = module; + return this; + } + + public Integer getResult() { + return result; + } + + public FileUploadListFile setResult(Integer result) { + this.result = result; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadListRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadListRequest.java new file mode 100644 index 0000000..86958af --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadListRequest.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.log; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class FileUploadListRequest extends BaseModel { + + /** + * Filter list of file + **/ + @NotNull + @Size(min = 1, max = 2) + private List moduleList; + + public FileUploadListRequest() { + } + + @Override + public String toString() { + return "FileUploadListRequest{" + + "moduleList=" + moduleList + + '}'; + } + + public List getModuleList() { + return moduleList; + } + + public FileUploadListRequest setModuleList(List moduleList) { + this.moduleList = moduleList; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadListResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadListResponse.java new file mode 100644 index 0000000..07ce73b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadListResponse.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.cloudapi.log; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class FileUploadListResponse { + + private List files; + + public FileUploadListResponse() { + } + + @Override + public String toString() { + return "FileUploadListResponse{" + + "files=" + files + + '}'; + } + + public List getFiles() { + return files; + } + + public FileUploadListResponse setFiles(List files) { + this.files = files; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadProgress.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadProgress.java new file mode 100644 index 0000000..8bdec58 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadProgress.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.log; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +public class FileUploadProgress { + + private FileUploadProgressExt ext; + + private FileUploadStatusEnum status; + + public FileUploadProgress() { + } + + @Override + public String toString() { + return "FileUploadProgress{" + + "ext=" + ext + + ", status=" + status + + '}'; + } + + public FileUploadProgressExt getExt() { + return ext; + } + + public FileUploadProgress setExt(FileUploadProgressExt ext) { + this.ext = ext; + return this; + } + + public FileUploadStatusEnum getStatus() { + return status; + } + + public FileUploadProgress setStatus(FileUploadStatusEnum status) { + this.status = status; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadProgressExt.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadProgressExt.java new file mode 100644 index 0000000..c7cbd2b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadProgressExt.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.cloudapi.log; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +public class FileUploadProgressExt { + + private List files; + + public FileUploadProgressExt() { + } + + @Override + public String toString() { + return "FileUploadProgressExt{" + + "files=" + files + + '}'; + } + + public List getFiles() { + return files; + } + + public FileUploadProgressExt setFiles(List files) { + this.files = files; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadProgressFile.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadProgressFile.java new file mode 100644 index 0000000..441430c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadProgressFile.java @@ -0,0 +1,90 @@ +package org.dromara.common.sdk.cloudapi.log; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +public class FileUploadProgressFile { + + private LogModuleEnum module; + + private Long size; + + private String deviceSn; + + private String key; + + private String fingerprint; + + private LogFileProgress progress; + + public FileUploadProgressFile() { + } + + @Override + public String toString() { + return "FileUploadProgressFile{" + + "module=" + module + + ", size=" + size + + ", deviceSn='" + deviceSn + '\'' + + ", key='" + key + '\'' + + ", fingerprint='" + fingerprint + '\'' + + ", progress=" + progress + + '}'; + } + + public LogModuleEnum getModule() { + return module; + } + + public FileUploadProgressFile setModule(LogModuleEnum module) { + this.module = module; + return this; + } + + public Long getSize() { + return size; + } + + public FileUploadProgressFile setSize(Long size) { + this.size = size; + return this; + } + + public String getDeviceSn() { + return deviceSn; + } + + public FileUploadProgressFile setDeviceSn(String deviceSn) { + this.deviceSn = deviceSn; + return this; + } + + public String getKey() { + return key; + } + + public FileUploadProgressFile setKey(String key) { + this.key = key; + return this; + } + + public String getFingerprint() { + return fingerprint; + } + + public FileUploadProgressFile setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + return this; + } + + public LogFileProgress getProgress() { + return progress; + } + + public FileUploadProgressFile setProgress(LogFileProgress progress) { + this.progress = progress; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStartFile.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStartFile.java new file mode 100644 index 0000000..25df63a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStartFile.java @@ -0,0 +1,76 @@ +package org.dromara.common.sdk.cloudapi.log; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public class FileUploadStartFile { + + @NotNull + private String deviceSn; + + @NotNull + private List<@Valid LogFileIndex> list; + + @NotNull + private LogModuleEnum module; + + @NotNull + private String objectKey; + + public FileUploadStartFile() { + } + + @Override + public String toString() { + return "FileUploadStartFile{" + + "deviceSn='" + deviceSn + '\'' + + ", list=" + list + + ", module=" + module + + ", objectKey='" + objectKey + '\'' + + '}'; + } + + public String getDeviceSn() { + return deviceSn; + } + + public FileUploadStartFile setDeviceSn(String deviceSn) { + this.deviceSn = deviceSn; + return this; + } + + public List getList() { + return list; + } + + public FileUploadStartFile setList(List list) { + this.list = list; + return this; + } + + public LogModuleEnum getModule() { + return module; + } + + public FileUploadStartFile setModule(LogModuleEnum module) { + this.module = module; + return this; + } + + public String getObjectKey() { + return objectKey; + } + + public FileUploadStartFile setObjectKey(String objectKey) { + this.objectKey = objectKey; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStartParam.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStartParam.java new file mode 100644 index 0000000..c1d41c1 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStartParam.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.log; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public class FileUploadStartParam { + + @NotNull + @Size(min = 1, max = 2) + private List<@Valid FileUploadStartFile> files; + + public FileUploadStartParam() { + } + + @Override + public String toString() { + return "FileUploadStartParam{" + + "files=" + files + + '}'; + } + + public List getFiles() { + return files; + } + + public FileUploadStartParam setFiles(List files) { + this.files = files; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStartRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStartRequest.java new file mode 100644 index 0000000..aefc4b0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStartRequest.java @@ -0,0 +1,138 @@ +package org.dromara.common.sdk.cloudapi.log; + +import org.dromara.common.sdk.cloudapi.storage.CredentialsToken; +import org.dromara.common.sdk.cloudapi.storage.OssTypeEnum; +import org.dromara.common.sdk.cloudapi.storage.StsCredentialsResponse; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.2 + * @date 2022/9/8 + */ +public class FileUploadStartRequest extends BaseModel { + + @NotNull + private String bucket; + + @NotNull + @Valid + private CredentialsToken credentials; + + @NotNull + private String endpoint; + + @NotNull + private String fileStoreDir; + + @NotNull + private OssTypeEnum provider; + + @NotNull + private String fileType = "text_log"; + + @NotNull + @Valid + private FileUploadStartParam params; + + @NotNull + private String region; + + public FileUploadStartRequest(StsCredentialsResponse sts) { + this.bucket = sts.getBucket(); + long expire = sts.getCredentials().getExpire(); + sts.getCredentials().setExpire(System.currentTimeMillis() + (expire - 60) * 1000); + this.credentials = sts.getCredentials(); + this.endpoint = sts.getEndpoint(); + this.fileStoreDir = sts.getObjectKeyPrefix(); + this.provider = sts.getProvider(); + this.region = sts.getRegion(); + } + + public FileUploadStartRequest() { + } + + @Override + public String toString() { + return "FileUploadStartRequest{" + + "bucket='" + bucket + '\'' + + ", credentials=" + credentials + + ", endpoint='" + endpoint + '\'' + + ", fileStoreDir='" + fileStoreDir + '\'' + + ", provider=" + provider + + ", fileType='" + fileType + '\'' + + ", params=" + params + + ", region='" + region + '\'' + + '}'; + } + + public String getBucket() { + return bucket; + } + + public FileUploadStartRequest setBucket(String bucket) { + this.bucket = bucket; + return this; + } + + public CredentialsToken getCredentials() { + return credentials; + } + + public FileUploadStartRequest setCredentials(CredentialsToken credentials) { + this.credentials = credentials; + return this; + } + + public String getEndpoint() { + return endpoint; + } + + public FileUploadStartRequest setEndpoint(String endpoint) { + this.endpoint = endpoint; + return this; + } + + public String getFileStoreDir() { + return fileStoreDir; + } + + public FileUploadStartRequest setFileStoreDir(String fileStoreDir) { + this.fileStoreDir = fileStoreDir; + return this; + } + + public OssTypeEnum getProvider() { + return provider; + } + + public FileUploadStartRequest setProvider(OssTypeEnum provider) { + this.provider = provider; + return this; + } + + public String getFileType() { + return fileType; + } + + public FileUploadStartParam getParams() { + return params; + } + + public FileUploadStartRequest setParams(FileUploadStartParam params) { + this.params = params; + return this; + } + + public String getRegion() { + return region; + } + + public FileUploadStartRequest setRegion(String region) { + this.region = region; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStatusEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStatusEnum.java new file mode 100644 index 0000000..9f34327 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadStatusEnum.java @@ -0,0 +1,61 @@ +package org.dromara.common.sdk.cloudapi.log; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public enum FileUploadStatusEnum { + + FILE_PULL("file_pull", false), + + FILE_ZIP("file_zip", false), + + FILE_UPLOADING("file_uploading", false), + + SENT("sent", false), + + IN_PROGRESS("in_progress", false), + + OK("ok", true), + + PAUSED("paused", false), + + REJECTED("rejected", true), + + FAILED("failed", true), + + CANCELED("canceled", true), + + TIMEOUT("timeout", true); + + private final String status; + + private final boolean end; + + FileUploadStatusEnum(String status, boolean end) { + this.status = status; + this.end = end; + } + + public boolean isEnd() { + return end; + } + + @JsonValue + public String getStatus() { + return status; + } + + @JsonCreator + public static FileUploadStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(FileUploadStatusEnum.class, status)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadUpdateRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadUpdateRequest.java new file mode 100644 index 0000000..e604c5d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadUpdateRequest.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.log; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class FileUploadUpdateRequest extends BaseModel { + + /** + * Filter list of file + **/ + @NotNull + @Size(min = 1, max = 2) + private List moduleList; + + @NotNull + private FileUploadUpdateStatusEnum status; + + public FileUploadUpdateRequest() { + } + + @Override + public String toString() { + return "FileUploadUpdateRequest{" + + "moduleList=" + moduleList + + ", status=" + status + + '}'; + } + + public List getModuleList() { + return moduleList; + } + + public FileUploadUpdateRequest setModuleList(List moduleList) { + this.moduleList = moduleList; + return this; + } + + public FileUploadUpdateStatusEnum getStatus() { + return status; + } + + public FileUploadUpdateRequest setStatus(FileUploadUpdateStatusEnum status) { + this.status = status; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadUpdateStatusEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadUpdateStatusEnum.java new file mode 100644 index 0000000..303b919 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/FileUploadUpdateStatusEnum.java @@ -0,0 +1,34 @@ +package org.dromara.common.sdk.cloudapi.log; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public enum FileUploadUpdateStatusEnum { + + CANCEL("cancel"); + + private final String status; + + FileUploadUpdateStatusEnum(String status) { + this.status = status; + } + + @JsonValue + public String getStatus() { + return status; + } + + @JsonCreator + public static FileUploadUpdateStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(FileUploadUpdateStatusEnum.class, status)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogErrorCodeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogErrorCodeEnum.java new file mode 100644 index 0000000..2fad3a8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogErrorCodeEnum.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.cloudapi.log; + +import org.dromara.common.sdk.common.IErrorInfo; +import org.dromara.common.sdk.mqtt.events.IEventsErrorCode; +import org.dromara.common.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum LogErrorCodeEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + DEVICE_RESTART(324001, "设备重新启动会中断日志导出。"), + + EXPORT_TIMEOUT(324012, "压缩日志超时。选择的日志太多。取消选择一些日志,然后重试。"), + + PULL_FAILED(324013, "无法获取设备日志列表。请稍后再试。"), + + EMPTY_LOG_LIST(324014, "设备日志列表为空。刷新页面或重新启动dock,然后重试。"), + + AIRCRAFT_SHUTDOWN(324015, "飞机断电或未连接。无法获取日志列表。确保飞机在码头内。远程接通飞机电源,然后再试一次。"), + + INSUFFICIENT_STORAGE_SPACE(324016, "底座存储空间不足。无法压缩日志。请清除空间或稍后再试。"), + + NO_LOG(324017, "无法压缩日志。无法获取所选飞机的日志。刷新页面或重新启动dock,然后重试。"), + + COMPRESSION_FAILED(324018, "未能压缩日志并提交问题报告。请稍后再试,或者重新启动dock然后再试。"), + + UPLOAD_FAILED(324019, "由于机场网络异常,日志上传失败。请稍后重试。"), + + UNKNOWN(-1, "UNKNOWN"), + + ; + + + private final String msg; + + private final int code; + + LogErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + /** + * @param code error code + * @return enumeration object + */ + public static LogErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogFileIndex.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogFileIndex.java new file mode 100644 index 0000000..69d2980 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogFileIndex.java @@ -0,0 +1,73 @@ +package org.dromara.common.sdk.cloudapi.log; + + +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public class LogFileIndex { + + @NotNull + private Integer bootIndex; + + @NotNull + private Long endTime; + + @NotNull + private Long startTime; + + @NotNull + private Long size; + + public LogFileIndex() { + } + + @Override + public String toString() { + return "LogFileIndex{" + + "bootIndex=" + bootIndex + + ", endTime=" + endTime + + ", startTime=" + startTime + + ", size=" + size + + '}'; + } + + public Integer getBootIndex() { + return bootIndex; + } + + public LogFileIndex setBootIndex(Integer bootIndex) { + this.bootIndex = bootIndex; + return this; + } + + public Long getEndTime() { + return endTime; + } + + public LogFileIndex setEndTime(Long endTime) { + this.endTime = endTime; + return this; + } + + public Long getStartTime() { + return startTime; + } + + public LogFileIndex setStartTime(Long startTime) { + this.startTime = startTime; + return this; + } + + public Long getSize() { + return size; + } + + public LogFileIndex setSize(Long size) { + this.size = size; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogFileProgress.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogFileProgress.java new file mode 100644 index 0000000..31c7ad4 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogFileProgress.java @@ -0,0 +1,102 @@ +package org.dromara.common.sdk.cloudapi.log; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +public class LogFileProgress { + + private Integer currentStep; + + private Integer totalStep; + + private Integer progress; + + private Long finishTime; + + private Float uploadRate; + + private FileUploadStatusEnum status; + + private Integer result; + + public LogFileProgress() { + } + + @Override + public String toString() { + return "LogFileProgress{" + + "currentStep=" + currentStep + + ", totalStep=" + totalStep + + ", progress=" + progress + + ", finishTime=" + finishTime + + ", uploadRate=" + uploadRate + + ", status=" + status + + ", result=" + result + + '}'; + } + + public Integer getCurrentStep() { + return currentStep; + } + + public LogFileProgress setCurrentStep(Integer currentStep) { + this.currentStep = currentStep; + return this; + } + + public Integer getTotalStep() { + return totalStep; + } + + public LogFileProgress setTotalStep(Integer totalStep) { + this.totalStep = totalStep; + return this; + } + + public Integer getProgress() { + return progress; + } + + public LogFileProgress setProgress(Integer progress) { + this.progress = progress; + return this; + } + + public Long getFinishTime() { + return finishTime; + } + + public LogFileProgress setFinishTime(Long finishTime) { + this.finishTime = finishTime; + return this; + } + + public Float getUploadRate() { + return uploadRate; + } + + public LogFileProgress setUploadRate(Float uploadRate) { + this.uploadRate = uploadRate; + return this; + } + + public FileUploadStatusEnum getStatus() { + return status; + } + + public LogFileProgress setStatus(FileUploadStatusEnum status) { + this.status = status; + return this; + } + + public Integer getResult() { + return result; + } + + public LogFileProgress setResult(Integer result) { + this.result = result; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogMethodEnum.java new file mode 100644 index 0000000..8d87e39 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogMethodEnum.java @@ -0,0 +1,25 @@ +package org.dromara.common.sdk.cloudapi.log; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum LogMethodEnum { + + FILE_UPLOAD_LIST("fileupload_list"), + + FILE_UPLOAD_START("fileupload_start"), + + FILE_UPLOAD_UPDATE("fileupload_update"); + + private final String method; + + LogMethodEnum(String method) { + this.method = method; + } + + public String getMethod() { + return method; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogModuleEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogModuleEnum.java new file mode 100644 index 0000000..2b84bd4 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/LogModuleEnum.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.cloudapi.log; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/29 + */ +public enum LogModuleEnum { + + DRONE("0"), + + DOCK ("3"); + + private final String domain; + + LogModuleEnum(String domain) { + this.domain = domain; + } + + @JsonCreator + public static LogModuleEnum find(String domain) { + return Arrays.stream(values()).filter(domainEnum -> domainEnum.domain.equals(domain)).findAny() + .orElseThrow(() -> new CloudSDKException(LogModuleEnum.class, domain)); + } + + @JsonValue + public String getDomain() { + return domain; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/api/AbstractLogService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/api/AbstractLogService.java new file mode 100644 index 0000000..fff978c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/log/api/AbstractLogService.java @@ -0,0 +1,81 @@ +package org.dromara.common.sdk.cloudapi.log.api; + +import org.dromara.common.sdk.cloudapi.log.*; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.events.EventsDataRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsResponse; +import org.dromara.common.sdk.mqtt.services.ServicesPublish; +import org.dromara.common.sdk.mqtt.services.ServicesReplyData; +import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; +import com.fasterxml.jackson.core.type.TypeReference; +import jakarta.annotation.Resource; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + + +/** + * @author sean + * @version 1.7 + * @date 2023/6/28 + */ +public abstract class AbstractLogService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Inform of file uploading progress + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FILEUPLOAD_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse fileuploadProgress(TopicEventsRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("fileuploadProgress未实现"); + } + + /** + * Get file list of uploadable device + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse> fileuploadList(GatewayManager gateway, FileUploadListRequest request) { + return servicesPublish.publish( + new TypeReference() {}, + gateway.getGatewaySn(), + LogMethodEnum.FILE_UPLOAD_LIST.getMethod(), + request); + } + + /** + * Start the log file uploading + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse fileuploadStart(GatewayManager gateway, FileUploadStartRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + LogMethodEnum.FILE_UPLOAD_START.getMethod(), + request); + } + + /** + * Update the uploding state + * @param gateway + * @param request data + * @return services_reply + */ + public TopicServicesResponse fileuploadUpdate(GatewayManager gateway, FileUploadUpdateRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + LogMethodEnum.FILE_UPLOAD_UPDATE.getMethod(), + request); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/CreateMapElementRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/CreateMapElementRequest.java new file mode 100644 index 0000000..4867e8c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/CreateMapElementRequest.java @@ -0,0 +1,68 @@ +package org.dromara.common.sdk.cloudapi.map; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "Create element request data") +public class CreateMapElementRequest { + + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "element id", format = "uuid") + private String id; + + @Schema(description = "element name", example = "PILOT 1") + @NotNull + private String name; + + @NotNull + @Valid + private ElementResource resource; + + public CreateMapElementRequest() { + } + + @Override + public String toString() { + return "CreateMapElementRequest{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", resource=" + resource + + '}'; + } + + public String getId() { + return id; + } + + public CreateMapElementRequest setId(String id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public CreateMapElementRequest setName(String name) { + this.name = name; + return this; + } + + public ElementResource getResource() { + return resource; + } + + public CreateMapElementRequest setResource(ElementResource resource) { + this.resource = resource; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/CreateMapElementResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/CreateMapElementResponse.java new file mode 100644 index 0000000..690ddad --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/CreateMapElementResponse.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.map; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + + +/** + * @author sean + * @version 1.7 + * @date 2023/6/16 + */ +@Schema(description = "Create element response data") +public class CreateMapElementResponse { + + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "element id", format = "uuid") + private String id; + + public CreateMapElementResponse() { + } + + @Override + public String toString() { + return "CreateMapElementResponse{" + + "id='" + id + '\'' + + '}'; + } + + public String getId() { + return id; + } + + public CreateMapElementResponse setId(String id) { + this.id = id; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/DockDroneDongleInfos.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/DockDroneDongleInfos.java new file mode 100644 index 0000000..38a8106 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/DockDroneDongleInfos.java @@ -0,0 +1,9 @@ +package org.dromara.common.sdk.cloudapi.map; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/19 + */ +public class DockDroneDongleInfos { +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementCircleGeometry.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementCircleGeometry.java new file mode 100644 index 0000000..f4cba4b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementCircleGeometry.java @@ -0,0 +1,64 @@ +package org.dromara.common.sdk.cloudapi.map; + +import org.dromara.common.sdk.cloudapi.flightarea.GeometrySubTypeEnum; + +import java.util.List; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +public class ElementCircleGeometry extends ElementPointGeometry { + + private final String type = GeometrySubTypeEnum.CIRCLE.getSubType(); + + private Float radius; + + public ElementCircleGeometry() { + } + + @Override + public String toString() { + return "ElementCircleGeometry{" + + "type='" + type + '\'' + + ", radius=" + radius + + '}'; + } + + @Override + public List convertToList() { + return super.convertToList(); + } + + @Override + public void adapterCoordinateType(List coordinateList) { + super.adapterCoordinateType(coordinateList); + Double[] coordinates = this.getCoordinates(); + this.setCoordinates(new Double[]{coordinates[0], coordinates[1]}); + } + + @Override + public Double[] getCoordinates() { + return super.getCoordinates(); + } + + @Override + public ElementPointGeometry setCoordinates(Double[] coordinates) { + return super.setCoordinates(coordinates); + } + + @Override + public String getType() { + return type; + } + + public Float getRadius() { + return radius; + } + + public ElementCircleGeometry setRadius(Float radius) { + this.radius = radius; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementContent.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementContent.java new file mode 100644 index 0000000..25810d7 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementContent.java @@ -0,0 +1,61 @@ +package org.dromara.common.sdk.cloudapi.map; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "element content") +public class ElementContent { + + @Schema(defaultValue = "Feature", allowableValues = "Feature") + @NotNull + private final String type = "Feature"; + + @NotNull + @Valid + private ElementProperty properties; + + @Valid + @NotNull + private ElementGeometryType geometry; + + public ElementContent() { + } + + @Override + public String toString() { + return "ElementContent{" + + "type='" + type + '\'' + + ", properties=" + properties + + ", geometry=" + geometry + + '}'; + } + + public String getType() { + return type; + } + + public ElementProperty getProperties() { + return properties; + } + + public ElementContent setProperties(ElementProperty properties) { + this.properties = properties; + return this; + } + + public ElementGeometryType getGeometry() { + return geometry; + } + + public ElementContent setGeometry(ElementGeometryType geometry) { + this.geometry = geometry; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementCoordinate.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementCoordinate.java new file mode 100644 index 0000000..cece7f3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementCoordinate.java @@ -0,0 +1,65 @@ +package org.dromara.common.sdk.cloudapi.map; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "The coordinates of the element, the coordinate system is WGS84") +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ElementCoordinate { + + @Schema(description = "longitude") + @NotNull + private Double longitude; + + @Schema(description = "latitude") + @NotNull + private Double latitude; + + @Schema(description = "altitude") + private Double altitude; + + public ElementCoordinate() { + } + + @Override + public String toString() { + return "ElementCoordinate{" + + "longitude=" + longitude + + ", latitude=" + latitude + + ", altitude=" + altitude + + '}'; + } + + public Double getLongitude() { + return longitude; + } + + public ElementCoordinate setLongitude(Double longitude) { + this.longitude = longitude; + return this; + } + + public Double getLatitude() { + return latitude; + } + + public ElementCoordinate setLatitude(Double latitude) { + this.latitude = latitude; + return this; + } + + public Double getAltitude() { + return altitude; + } + + public ElementCoordinate setAltitude(Double altitude) { + this.altitude = altitude; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementGeometryType.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementGeometryType.java new file mode 100644 index 0000000..df60f73 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementGeometryType.java @@ -0,0 +1,49 @@ +package org.dromara.common.sdk.cloudapi.map; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", + include = JsonTypeInfo.As.EXISTING_PROPERTY, defaultImpl = ElementGeometryType.class) +@JsonSubTypes({ + @JsonSubTypes.Type(value = ElementCircleGeometry.class, name = "Circle"), + @JsonSubTypes.Type(value = ElementPointGeometry.class, name = "Point"), + @JsonSubTypes.Type(value = ElementLineStringGeometry.class, name = "LineString"), + @JsonSubTypes.Type(value = ElementPolygonGeometry.class, name = "Polygon") +}) +@Schema(oneOf = {ElementPointGeometry.class, ElementLineStringGeometry.class, ElementPolygonGeometry.class}) +public abstract class ElementGeometryType { + + private String type; + + ElementGeometryType(String type) { + this.type = type; + } + + public ElementGeometryType() { + } + + public String getType() { + return type; + } + + /** + * Convert coordinate data into objects and then add them to the collection. + * @return + */ + public abstract List convertToList(); + + /** + * Converts coordinates in a collection of objects to a specific type. + * @param coordinateList + */ + public abstract void adapterCoordinateType(List coordinateList); +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementLineStringGeometry.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementLineStringGeometry.java new file mode 100644 index 0000000..c621db3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementLineStringGeometry.java @@ -0,0 +1,81 @@ +package org.dromara.common.sdk.cloudapi.map; + +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "line geometry") +public class ElementLineStringGeometry extends ElementGeometryType { + + @Schema(example = "LineString") + @NotNull + private final String type = ElementResourceTypeEnum.LINE_STRING.getTypeName(); + + @Schema(example = "[[113.943109, 22.577378]]") + @NotNull + @Size(min = 2) + private Double[][] coordinates; + + public ElementLineStringGeometry() { + super(); + } + + @Override + public List convertToList() { + if (this.coordinates.length < 2) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + List coordinateList = new ArrayList<>(); + for (Double[] coordinate : this.coordinates) { + coordinateList.add(new ElementCoordinate() + .setLongitude(coordinate[0]) + .setLatitude(coordinate[1])); + } + return coordinateList; + } + + @Override + public void adapterCoordinateType(List coordinateList) { + if (CollectionUtils.isEmpty(coordinateList) || coordinateList.size() < 2) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + this.coordinates = new Double[coordinateList.size()][2]; + for (int i = 0; i < this.coordinates.length; i++) { + this.coordinates[i][0] = coordinateList.get(i).getLongitude(); + this.coordinates[i][1] = coordinateList.get(i).getLatitude(); + } + } + + @Override + public String toString() { + return "ElementLineStringGeometry{" + + "coordinates=" + Arrays.toString(coordinates) + + '}'; + } + + public Double[][] getCoordinates() { + return coordinates; + } + + public ElementLineStringGeometry setCoordinates(Double[][] coordinates) { + this.coordinates = coordinates; + return this; + } + + @Override + public String getType() { + return type; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementPointGeometry.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementPointGeometry.java new file mode 100644 index 0000000..dcc85df --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementPointGeometry.java @@ -0,0 +1,78 @@ +package org.dromara.common.sdk.cloudapi.map; + +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import org.springframework.util.CollectionUtils; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "point geometry") +public class ElementPointGeometry extends ElementGeometryType { + + @Schema(example = "Point") + @NotNull + private final String type = ElementResourceTypeEnum.POINT.getTypeName(); + + @Schema(example = "[113.943109, 22.577378]") + @NotNull + @Size(min = 2, max = 3) + private Double[] coordinates; + + public ElementPointGeometry() { + super(); + } + + @Override + public List convertToList() { + List coordinateList = new ArrayList<>(); + coordinateList.add(new ElementCoordinate() + .setLongitude(this.coordinates[0]) + .setLatitude(this.coordinates[1]) + .setAltitude(this.coordinates.length == 3 ? this.coordinates[2] : null)); + return coordinateList; + } + + @Override + public void adapterCoordinateType(List coordinateList) { + if (CollectionUtils.isEmpty(coordinateList)) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + this.coordinates = new Double[]{ + coordinateList.get(0).getLongitude(), + coordinateList.get(0).getLatitude(), + coordinateList.get(0).getAltitude() + }; + } + + @Override + public String toString() { + return "ElementPointGeometry{" + + "coordinates=" + Arrays.toString(coordinates) + + '}'; + } + + public Double[] getCoordinates() { + return coordinates; + } + + public ElementPointGeometry setCoordinates(Double[] coordinates) { + this.coordinates = coordinates; + return this; + } + + @Override + public String getType() { + return type; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementPolygonGeometry.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementPolygonGeometry.java new file mode 100644 index 0000000..a7c3923 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementPolygonGeometry.java @@ -0,0 +1,81 @@ +package org.dromara.common.sdk.cloudapi.map; + +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "polygon geometry") +public class ElementPolygonGeometry extends ElementGeometryType { + + @Schema(example = "Polygon") + @NotNull + private final String type = ElementTypeEnum.POLYGON.getDesc(); + + @Schema(example = "[[[113.943109, 22.577378]]]") + @NotNull + @Size(min = 1, max = 1) + private Double[][][] coordinates; + + public ElementPolygonGeometry() { + super(); + } + + @Override + public List convertToList() { + if (this.coordinates[0].length < 3) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + List coordinateList = new ArrayList<>(); + for (Double[] coordinate : this.coordinates[0]) { + coordinateList.add(new ElementCoordinate() + .setLongitude(coordinate[0]) + .setLatitude(coordinate[1])); + } + return coordinateList; + } + + @Override + public void adapterCoordinateType(List coordinateList) { + if (CollectionUtils.isEmpty(coordinateList) || coordinateList.size() < 3) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + this.coordinates = new Double[1][coordinateList.size()][2]; + for (int i = 0; i < this.coordinates[0].length; i++) { + this.coordinates[0][i][0] = coordinateList.get(i).getLongitude(); + this.coordinates[0][i][1] = coordinateList.get(i).getLatitude(); + } + } + + @Override + public String toString() { + return "ElementPolygonGeometry{" + + "coordinates=" + Arrays.toString(coordinates) + + '}'; + } + + public Double[][][] getCoordinates() { + return coordinates; + } + + public ElementPolygonGeometry setCoordinates(Double[][][] coordinates) { + this.coordinates = coordinates; + return this; + } + + @Override + public String getType() { + return type; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementProperty.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementProperty.java new file mode 100644 index 0000000..8fe17d5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementProperty.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.map; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(description = "properties of the element") +public class ElementProperty { + + @NotNull + @Schema(description = "element color", example = "#2D8CF0") + @Pattern(regexp = "^#[0-9a-fA-F]{6}$") + private String color; + + @JsonProperty("clampToGround") + @Schema(description = "Whether it is on the ground.") + private Boolean clampToGround; + + public ElementProperty() { + } + + @Override + public String toString() { + return "ElementProperty{" + + "color='" + color + '\'' + + ", clampToGround=" + clampToGround + + '}'; + } + + public String getColor() { + return color; + } + + public ElementProperty setColor(String color) { + this.color = color; + return this; + } + + public Boolean getClampToGround() { + return clampToGround; + } + + public ElementProperty setClampToGround(Boolean clampToGround) { + this.clampToGround = clampToGround; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementResource.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementResource.java new file mode 100644 index 0000000..11a0730 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementResource.java @@ -0,0 +1,67 @@ +package org.dromara.common.sdk.cloudapi.map; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Schema(description = "element resource") +public class ElementResource { + + @NotNull + @Schema(type = "int", enumAsRef = true) + private ElementResourceTypeEnum type; + + @Schema(description = "the user who created the element", example = "pilot") + @JsonProperty(value = "user_name") + private String username; + + @NotNull + @Valid + private ElementContent content; + + public ElementResource() { + } + + @Override + public String toString() { + return "ElementResource{" + + "type=" + type + + ", username='" + username + '\'' + + ", content=" + content + + '}'; + } + + public ElementResourceTypeEnum getType() { + return type; + } + + public ElementResource setType(ElementResourceTypeEnum type) { + this.type = type; + return this; + } + + public String getUsername() { + return username; + } + + public ElementResource setUsername(String username) { + this.username = username; + return this; + } + + public ElementContent getContent() { + return content; + } + + public ElementResource setContent(ElementContent content) { + this.content = content; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementResourceTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementResourceTypeEnum.java new file mode 100644 index 0000000..f0dc661 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/ElementResourceTypeEnum.java @@ -0,0 +1,53 @@ +package org.dromara.common.sdk.cloudapi.map; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Schema(enumAsRef = true, description = "

0: Point

1: LineString

2: Polygon

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

0: custom element group

1: default element group

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

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

Websocket response data when element is created.

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

Websocket response data when element is deleted.

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

Websocket response data when the element is updated.

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

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

") +public class MapGroupRefreshWsResponse extends BaseModel { + + @JsonProperty("ids") + @NotNull + @Size(min = 1) + @Schema(description = "group id collection", format = "uuid") + private List<@Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") String> ids; + + public MapGroupRefreshWsResponse() { + } + + @Override + public String toString() { + return "MapGroupRefreshWsResponse{" + + "ids=" + ids + + '}'; + } + + public List getIds() { + return ids; + } + + public MapGroupRefreshWsResponse setIds(List ids) { + this.ids = ids; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/MapMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/MapMethodEnum.java new file mode 100644 index 0000000..b252cf7 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/MapMethodEnum.java @@ -0,0 +1,26 @@ +package org.dromara.common.sdk.cloudapi.map; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public enum MapMethodEnum { + + OFFLINE_MAP_UPDATE("offline_map_update"), + + ; + + private final String method; + + MapMethodEnum(String method) { + this.method = method; + } + + @JsonValue + public String getMethod() { + return method; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapFile.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapFile.java new file mode 100644 index 0000000..8cc2af4 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapFile.java @@ -0,0 +1,85 @@ +package org.dromara.common.sdk.cloudapi.map; + + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class OfflineMapFile { + + /** + * The offline map file name will be used as a way to determine the version, and the format is: offline_map_{sync_method}_{version}. + * offline_map: is a fixed prefix, sync_method: data synchronization method - full (full), version: version number + */ + @NotNull + @Pattern(regexp = "^offline_map_full_\\w+\\.rocksdb\\.zip$") + private String name; + + @NotNull + private String url; + + /** + * Calculated using SHA256, this value can be used to confirm whether the file is complete. + */ + @NotNull + private String checksum; + + /** + * The size of this file in bytes. + */ + @NotNull + private Long size; + + public OfflineMapFile() { + } + + @Override + public String toString() { + return "OfflineMapFile{" + + "name='" + name + '\'' + + ", url='" + url + '\'' + + ", checksum='" + checksum + '\'' + + ", size=" + size + + '}'; + } + + public String getName() { + return name; + } + + public OfflineMapFile setName(String name) { + this.name = name; + return this; + } + + public String getUrl() { + return url; + } + + public OfflineMapFile setUrl(String url) { + this.url = url; + return this; + } + + public String getChecksum() { + return checksum; + } + + public OfflineMapFile setChecksum(String checksum) { + this.checksum = checksum; + return this; + } + + public Long getSize() { + return size; + } + + public OfflineMapFile setSize(Long size) { + this.size = size; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapGetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapGetRequest.java new file mode 100644 index 0000000..d33414b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapGetRequest.java @@ -0,0 +1,9 @@ +package org.dromara.common.sdk.cloudapi.map; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class OfflineMapGetRequest { +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapGetResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapGetResponse.java new file mode 100644 index 0000000..c732e1d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapGetResponse.java @@ -0,0 +1,56 @@ +package org.dromara.common.sdk.cloudapi.map; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class OfflineMapGetResponse extends BaseModel { + + /** + * This parameter allows the dock to turn off the offline map capability of the aircraft. + */ + @NotNull + private Boolean offlineMapEnable; + + /** + * Offline map file object list. + */ + @NotNull + private List<@Valid OfflineMapFile> files; + + public OfflineMapGetResponse() { + } + + @Override + public String toString() { + return "OfflineMapGetResponse{" + + "offlineMapEnable=" + offlineMapEnable + + ", files=" + files + + '}'; + } + + public Boolean getOfflineMapEnable() { + return offlineMapEnable; + } + + public OfflineMapGetResponse setOfflineMapEnable(Boolean offlineMapEnable) { + this.offlineMapEnable = offlineMapEnable; + return this; + } + + public List getFiles() { + return files; + } + + public OfflineMapGetResponse setFiles(List files) { + this.files = files; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncFile.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncFile.java new file mode 100644 index 0000000..babec65 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncFile.java @@ -0,0 +1,49 @@ +package org.dromara.common.sdk.cloudapi.map; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class OfflineMapSyncFile { + + /** + * The offline map file name will be used as a way to determine the version, and the format is: offline_map_{sync_method}_{version}. + * offline_map: is a fixed prefix, sync_method: data synchronization method - full (full), version: version number + */ + private String name; + + /** + * Calculated using SHA256, this value can be used to confirm whether the file is complete. + */ + private String checksum; + + public OfflineMapSyncFile() { + } + + @Override + public String toString() { + return "OfflineMapSyncFile{" + + "name='" + name + '\'' + + ", checksum='" + checksum + '\'' + + '}'; + } + + public String getName() { + return name; + } + + public OfflineMapSyncFile setName(String name) { + this.name = name; + return this; + } + + public String getChecksum() { + return checksum; + } + + public OfflineMapSyncFile setChecksum(String checksum) { + this.checksum = checksum; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncProgress.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncProgress.java new file mode 100644 index 0000000..0863f6d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncProgress.java @@ -0,0 +1,63 @@ +package org.dromara.common.sdk.cloudapi.map; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class OfflineMapSyncProgress { + + /** + * Sync status + */ + private OfflineMapSyncStatusEnum status; + + /** + * Result code + */ + private OfflineMapSyncReasonEnum reason; + + /** + * Offline map file information + */ + private OfflineMapSyncFile file; + + public OfflineMapSyncProgress() { + } + + @Override + public String toString() { + return "OfflineMapSyncProgress{" + + "status=" + status + + ", reason=" + reason + + ", file=" + file + + '}'; + } + + public OfflineMapSyncStatusEnum getStatus() { + return status; + } + + public OfflineMapSyncProgress setStatus(OfflineMapSyncStatusEnum status) { + this.status = status; + return this; + } + + public OfflineMapSyncReasonEnum getReason() { + return reason; + } + + public OfflineMapSyncProgress setReason(OfflineMapSyncReasonEnum reason) { + this.reason = reason; + return this; + } + + public OfflineMapSyncFile getFile() { + return file; + } + + public OfflineMapSyncProgress setFile(OfflineMapSyncFile file) { + this.file = file; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncReasonEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncReasonEnum.java new file mode 100644 index 0000000..636292b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncReasonEnum.java @@ -0,0 +1,62 @@ +package org.dromara.common.sdk.cloudapi.map; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public enum OfflineMapSyncReasonEnum { + + SUCCESS(0, "success"), + + PARSE_FILE_FAILED(1, "Failed to parse the file information returned by the cloud."), + + OBTAIN_DRONE_FILE_FAILED(2, "Failed to obtain aircraft file information."), + + DOWNLOAD_FILE_FAILED(3, "Failed to download file from cloud."), + + LINK_ROLLOVER_FAILED(4, "Failed to rollover the link."), + + FILE_TRANSFER_FAILED(5, "Failed to transfer file."), + + DISABLE_OFFLINE_MAP_FAILED(6, "Failed to disable offline map."), + + DELETE_FILE_FAILED(7, "Failed to delete file."), + + LOAD_FILE_FAILED(8, "Failed to load the file on the device side."), + + ENABLE_OFFLINE_MAP_FAILED(9, "Failed to enable offline map."), + + ; + + private final int reason; + + private final String msg; + + OfflineMapSyncReasonEnum(int reason, String msg) { + this.reason = reason; + this.msg = msg; + } + + @JsonValue + public int getReason() { + return reason; + } + + public String getMsg() { + return msg; + } + + @JsonCreator + public static OfflineMapSyncReasonEnum find(int reason) { + return Arrays.stream(values()).filter(reasonEnum -> reasonEnum.reason == reason).findAny() + .orElseThrow(() -> new CloudSDKException(OfflineMapSyncReasonEnum.class, reason)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncStatusEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncStatusEnum.java new file mode 100644 index 0000000..1e1ac8c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/OfflineMapSyncStatusEnum.java @@ -0,0 +1,45 @@ +package org.dromara.common.sdk.cloudapi.map; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public enum OfflineMapSyncStatusEnum { + + WAIT_SYNC("wait_sync"), + + SYNCHRONIZING("synchronizing"), + + SYNCHRONIZED("synchronized"), + + FAIL("fail"), + + SWITCH_FAIL("switch_fail"), + + ; + + + private final String status; + + OfflineMapSyncStatusEnum(String status) { + this.status = status; + } + + @JsonValue + public String getStatus() { + return status; + } + + @JsonCreator + public static OfflineMapSyncStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(OfflineMapSyncStatusEnum.class, status)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/UpdateMapElementRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/UpdateMapElementRequest.java new file mode 100644 index 0000000..ee66716 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/UpdateMapElementRequest.java @@ -0,0 +1,52 @@ +package org.dromara.common.sdk.cloudapi.map; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/1 + */ +@Schema(description = "Update element request data") +public class UpdateMapElementRequest { + + @Schema(description = "element name", example = "PILOT 1") + @NotNull + private String name; + + @NotNull + @Valid + private ElementContent content; + + public UpdateMapElementRequest() { + } + + @Override + public String toString() { + return "UpdateMapElementRequest{" + + "name='" + name + '\'' + + ", content=" + content + + '}'; + } + + public String getName() { + return name; + } + + public UpdateMapElementRequest setName(String name) { + this.name = name; + return this; + } + + public ElementContent getContent() { + return content; + } + + public UpdateMapElementRequest setContent(ElementContent content) { + this.content = content; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/api/AbstractOfflineMapService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/api/AbstractOfflineMapService.java new file mode 100644 index 0000000..19e3f97 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/api/AbstractOfflineMapService.java @@ -0,0 +1,87 @@ +package org.dromara.common.sdk.cloudapi.map.api; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.map.MapMethodEnum; +import org.dromara.common.sdk.cloudapi.map.OfflineMapGetRequest; +import org.dromara.common.sdk.cloudapi.map.OfflineMapGetResponse; +import org.dromara.common.sdk.cloudapi.map.OfflineMapSyncProgress; +import org.dromara.common.sdk.cloudapi.property.DockDroneOfflineMapEnable; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsRequest; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsResponse; +import org.dromara.common.sdk.mqtt.services.ServicesPublish; +import org.dromara.common.sdk.mqtt.services.ServicesReplyData; +import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; +import org.dromara.common.sdk.mqtt.state.TopicStateRequest; +import org.dromara.common.sdk.mqtt.state.TopicStateResponse; +import jakarta.annotation.Resource; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/19 + */ +public abstract class AbstractOfflineMapService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * When the offline map is closed, offline map synchronization will no longer automatically synchronize. + * @param request data + * @param headers The headers for a {@link Message}. + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_1, include = GatewayTypeEnum.DOCK2) + @ServiceActivator(inputChannel = ChannelName.INBOUND_STATE_DOCK_DRONE_OFFLINE_MAP_ENABLE, outputChannel = ChannelName.OUTBOUND_STATE) + public TopicStateResponse dockDroneOfflineMapEnable(TopicStateRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("dockDroneOfflineMapEnable not implemented"); + } + + /** + * Actively trigger offline map updates. + * After receiving the message, the airport will actively pull offline map information at the appropriate time and trigger the offline map synchronization mechanism. + * @param gateway gateway device + * @return services_reply + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_1, include = GatewayTypeEnum.DOCK2) + public TopicServicesResponse offlineMapUpdate(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + MapMethodEnum.OFFLINE_MAP_UPDATE.getMethod()); + } + + /** + * Offline map file synchronization status + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_OFFLINE_MAP_SYNC_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_1, include = GatewayTypeEnum.DOCK2) + public TopicRequestsResponse offlineMapSyncProgress(TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("offlineMapSyncProgress not implemented"); + } + + /** + * The dock will actively pull the latest offline map file information. + * From this information, it will check whether the aircraft's offline map file name or checksum has changed. + * Once a change is found, offline map synchronization will be triggered. + * Otherwise, synchronization will not be triggered. + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_OFFLINE_MAP_GET, outputChannel = ChannelName.OUTBOUND_REQUESTS) + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_1, include = GatewayTypeEnum.DOCK2) + public TopicRequestsResponse> offlineMapGet(TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("offlineMapGet not implemented"); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/api/IHttpMapService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/api/IHttpMapService.java new file mode 100644 index 0000000..4776e21 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/api/IHttpMapService.java @@ -0,0 +1,124 @@ +package org.dromara.common.sdk.cloudapi.map.api; + +import org.dromara.common.sdk.cloudapi.map.CreateMapElementRequest; +import org.dromara.common.sdk.cloudapi.map.CreateMapElementResponse; +import org.dromara.common.sdk.cloudapi.map.GetMapElementsResponse; +import org.dromara.common.sdk.cloudapi.map.UpdateMapElementRequest; +import org.dromara.common.sdk.common.HttpResultResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Tag(name = "map interface") +public interface IHttpMapService { + + String PREFIX = "map/api/v1"; + + /** + * In the first connection, pilot will send out this http request to get the group element list. + * Also, if pilot receives a group refresh instruction from WebSocket, + * it needs the same interface to request the group element list. + * @param workspaceId + * @param groupId + * @param isDistributed + * @param req + * @param rsp + * @return + */ + @Operation(summary = "get map elements", description = "In the first connection, pilot will send out this http " + + "request to get the group element list. Also, if pilot receives a group refresh instruction from " + + "WebSocket, it needs the same interface to request the group element list.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + @Parameter(name = "group_id", description = "element group id. The same element group can contain " + + "multiple map elements, which is equivalent to grouping map elements. " + + "When initiating the request, if the group id parameter is not included, " + + "the server needs to return all map elements. If the group id is specified, " + + "it only needs to return the set of elements in the specified element group", schema = @Schema(format = "uuid")), + @Parameter(name = "is_distributed", description = "Whether the element group is distributed.") + }) + @GetMapping(PREFIX + "/workspaces/{workspace_id}/element-groups") + HttpResultResponse> getMapElements( + @PathVariable(name = "workspace_id") String workspaceId, + @RequestParam(name = "group_id", required = false) String groupId, + @RequestParam(name = "is_distributed", required = false) Boolean isDistributed, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * When user draws a point, line or polygon on the PILOT/Web side. + * @param workspaceId + * @param groupId + * @param elementCreate + * @param req + * @param rsp + * @return + */ + @Operation(summary = "create map element", description = "When user draws a point, line or polygon on the PILOT/Web side.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + @Parameter(name = "group_id", description = "element group id. The same element group can contain " + + "multiple map elements, which is equivalent to grouping map elements. " + + "When initiating the request, if the group id parameter is not included, " + + "the server needs to return all map elements. If the group id is specified, " + + "it only needs to return the set of elements in the specified element group", schema = @Schema(format = "uuid")) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/element-groups/{group_id}/elements") + HttpResultResponse createMapElement( + @PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "group_id") String groupId, + @Valid @RequestBody CreateMapElementRequest elementCreate, + HttpServletRequest req, HttpServletResponse rsp); + + + /** + * When user edits a point, line or polygon on the PILOT/Web side. + * @param workspaceId + * @param elementId + * @param elementUpdate + * @param req + * @param rsp + * @return + */ + @Operation(summary = "update map element", description = "When user edits a point, line or polygon on the PILOT/Web side.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + @Parameter(name = "element_id", description = "element id", schema = @Schema(format = "uuid")) + }) + @PutMapping(PREFIX + "/workspaces/{workspace_id}/elements/{element_id}") + HttpResultResponse updateMapElement( + @PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "element_id") String elementId, + @Valid @RequestBody UpdateMapElementRequest elementUpdate, + HttpServletRequest req, HttpServletResponse rsp); + + + /** + * When user delete a point, line or polygon on the PILOT/Web side. + * @param workspaceId + * @param elementId + * @return + */ + @Operation(summary = "delete map element", description = "When user delete a point, line or polygon on the PILOT/Web side.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + @Parameter(name = "element_id", description = "element id", schema = @Schema(format = "uuid")) + }) + @DeleteMapping(PREFIX + "/workspaces/{workspace_id}/elements/{element_id}") + HttpResultResponse deleteMapElement( + @PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "element_id") String elementId, + HttpServletRequest req, HttpServletResponse rsp); + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FastUploadExtension.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FastUploadExtension.java new file mode 100644 index 0000000..e5b6cb3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FastUploadExtension.java @@ -0,0 +1,99 @@ +package org.dromara.common.sdk.cloudapi.media; + +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media file fast upload extension data") +public class FastUploadExtension { + + @NotNull + @JsonProperty("drone_model_key") + @Schema(description = "drone device product enum") + private DeviceEnum droneModelKey; + + @JsonProperty("is_original") + @NotNull + @Schema(description = "Whether the image is the original image.") + private Boolean original; + + @NotNull + @JsonProperty("payload_model_key") + @Schema(description = "payload device product enum", example = "1-42-0") + private DeviceEnum payloadModelKey; + + @NotNull + @JsonProperty("tinny_fingerprint") + @Schema(description = "tiny fingerprint of the file.", example = "297f490b0252690d3f93841818567cc6_2022_8_31_15_16_16") + private String tinnyFingerprint; + + @NotNull + @Schema(description = "drone sn", example = "1AD3CA2VL3LAD6") + private String sn; + + public FastUploadExtension() { + } + + @Override + public String toString() { + return "FastUploadExtension{" + + "droneModelKey=" + droneModelKey + + ", original=" + original + + ", payloadModelKey=" + payloadModelKey + + ", tinnyFingerprint='" + tinnyFingerprint + '\'' + + ", sn='" + sn + '\'' + + '}'; + } + + public DeviceEnum getDroneModelKey() { + return droneModelKey; + } + + public FastUploadExtension setDroneModelKey(DeviceEnum droneModelKey) { + this.droneModelKey = droneModelKey; + return this; + } + + public Boolean getOriginal() { + return original; + } + + public FastUploadExtension setOriginal(Boolean original) { + this.original = original; + return this; + } + + public DeviceEnum getPayloadModelKey() { + return payloadModelKey; + } + + public FastUploadExtension setPayloadModelKey(DeviceEnum payloadModelKey) { + this.payloadModelKey = payloadModelKey; + return this; + } + + public String getTinnyFingerprint() { + return tinnyFingerprint; + } + + public FastUploadExtension setTinnyFingerprint(String tinnyFingerprint) { + this.tinnyFingerprint = tinnyFingerprint; + return this; + } + + public String getSn() { + return sn; + } + + public FastUploadExtension setSn(String sn) { + this.sn = sn; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FileUploadCallback.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FileUploadCallback.java new file mode 100644 index 0000000..59a44a2 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FileUploadCallback.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.media; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +public class FileUploadCallback { + + private Integer result; + + private Integer progress; + + private FileUploadCallbackFile file; + + public FileUploadCallback() { + } + + @Override + public String toString() { + return "FileUploadCallback{" + + "result=" + result + + ", progress=" + progress + + ", file=" + file + + '}'; + } + + public Integer getResult() { + return result; + } + + public FileUploadCallback setResult(Integer result) { + this.result = result; + return this; + } + + public Integer getProgress() { + return progress; + } + + public FileUploadCallback setProgress(Integer progress) { + this.progress = progress; + return this; + } + + public FileUploadCallbackFile getFile() { + return file; + } + + public FileUploadCallback setFile(FileUploadCallbackFile file) { + this.file = file; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FileUploadCallbackFile.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FileUploadCallbackFile.java new file mode 100644 index 0000000..1062730 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FileUploadCallbackFile.java @@ -0,0 +1,78 @@ +package org.dromara.common.sdk.cloudapi.media; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +public class FileUploadCallbackFile { + + private UploadCallbackFileExtension ext; + + private String name; + + private String path; + + private String objectKey; + + private UploadCallbackFileMetadata metadata; + + public FileUploadCallbackFile() { + } + + @Override + public String toString() { + return "FileUploadCallbackFile{" + + "ext=" + ext + + ", name='" + name + '\'' + + ", path='" + path + '\'' + + ", objectKey='" + objectKey + '\'' + + ", metadata=" + metadata + + '}'; + } + + public UploadCallbackFileExtension getExt() { + return ext; + } + + public FileUploadCallbackFile setExt(UploadCallbackFileExtension ext) { + this.ext = ext; + return this; + } + + public String getName() { + return name; + } + + public FileUploadCallbackFile setName(String name) { + this.name = name; + return this; + } + + public String getPath() { + return path; + } + + public FileUploadCallbackFile setPath(String path) { + this.path = path; + return this; + } + + public String getObjectKey() { + return objectKey; + } + + public FileUploadCallbackFile setObjectKey(String objectKey) { + this.objectKey = objectKey; + return this; + } + + public UploadCallbackFileMetadata getMetadata() { + return metadata; + } + + public FileUploadCallbackFile setMetadata(UploadCallbackFileMetadata metadata) { + this.metadata = metadata; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FolderUploadCallbackRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FolderUploadCallbackRequest.java new file mode 100644 index 0000000..2fcbee4 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/FolderUploadCallbackRequest.java @@ -0,0 +1,69 @@ +package org.dromara.common.sdk.cloudapi.media; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/6/19 + */ +@Schema(description = "folder upload callback request data") +public class FolderUploadCallbackRequest { + + @NotNull + @JsonProperty("file_group_id") + @Schema(description = "file group id", format = "uuid") + private String fileGroupId; + + @NotNull + @JsonProperty("file_count") + @Schema(description = "total amount of media in the file group") + private Integer fileCount; + + @NotNull + @JsonProperty("file_uploaded_count") + @Schema(description = "the number of uploaded media in the file group") + private Integer fileUploadedCount; + + public FolderUploadCallbackRequest() { + } + + @Override + public String toString() { + return "FolderUploadCallbackRequest{" + + "fileGroupId='" + fileGroupId + '\'' + + ", fileCount=" + fileCount + + ", fileUploadedCount=" + fileUploadedCount + + '}'; + } + + public String getFileGroupId() { + return fileGroupId; + } + + public FolderUploadCallbackRequest setFileGroupId(String fileGroupId) { + this.fileGroupId = fileGroupId; + return this; + } + + public Integer getFileCount() { + return fileCount; + } + + public FolderUploadCallbackRequest setFileCount(Integer fileCount) { + this.fileCount = fileCount; + return this; + } + + public Integer getFileUploadedCount() { + return fileUploadedCount; + } + + public FolderUploadCallbackRequest setFileUploadedCount(Integer fileUploadedCount) { + this.fileUploadedCount = fileUploadedCount; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/GetFileFingerprintRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/GetFileFingerprintRequest.java new file mode 100644 index 0000000..b3c8c66 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/GetFileFingerprintRequest.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.media; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/16 + */ +@Schema(description = "get request data for tiny fingerprints of existing files") +public class GetFileFingerprintRequest { + + @NotNull + @Schema(description = "tiny fingerprints collection", example = "[\"297f490b0252690d3f93841818567cc6_2022_8_31_15_16_16\"]") + @JsonProperty("tiny_fingerprints") + private List tinyFingerprints; + + public GetFileFingerprintRequest() { + } + + @Override + public String toString() { + return "GetFileFingerprintRequest{" + + "tinyFingerprints=" + tinyFingerprints + + '}'; + } + + public List getTinyFingerprints() { + return tinyFingerprints; + } + + public GetFileFingerprintRequest setTinyFingerprints(List tinyFingerprints) { + this.tinyFingerprints = tinyFingerprints; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/GetFileFingerprintResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/GetFileFingerprintResponse.java new file mode 100644 index 0000000..2df8cd7 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/GetFileFingerprintResponse.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.media; + + +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/16 + */ +@Schema(description = "response data for tiny fingerprints of existing files") +public class GetFileFingerprintResponse extends BaseModel { + + @NotNull + @Schema(description = "tiny fingerprints collection", example = "[\"297f490b0252690d3f93841818567cc6_2022_8_31_15_16_16\"]") + @JsonProperty("tiny_fingerprints") + private List tinyFingerprints; + + public GetFileFingerprintResponse() { + } + + @Override + public String toString() { + return "GetFileFingerprintResponse{" + + "tinyFingerprints=" + tinyFingerprints + + '}'; + } + + public List getTinyFingerprints() { + return tinyFingerprints; + } + + public GetFileFingerprintResponse setTinyFingerprints(List tinyFingerprints) { + this.tinyFingerprints = tinyFingerprints; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/HighestPriorityUploadFlightTaskMedia.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/HighestPriorityUploadFlightTaskMedia.java new file mode 100644 index 0000000..4d63f0e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/HighestPriorityUploadFlightTaskMedia.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.media; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public class HighestPriorityUploadFlightTaskMedia { + + private String flightId; + + public HighestPriorityUploadFlightTaskMedia() { + } + + @Override + public String toString() { + return "HighestPriorityUploadFlightTaskMedia{" + + "flightId='" + flightId + '\'' + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public HighestPriorityUploadFlightTaskMedia setFlightId(String flightId) { + this.flightId = flightId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaFastUploadRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaFastUploadRequest.java new file mode 100644 index 0000000..317d579 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaFastUploadRequest.java @@ -0,0 +1,79 @@ +package org.dromara.common.sdk.cloudapi.media; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media fast upload request data") +public class MediaFastUploadRequest { + + @NotNull + @Valid + private FastUploadExtension ext; + + @NotNull + @Schema(description = "media file fingerprint", example = "7F78C9F1999425CB61F10E1FE206009E") + private String fingerprint; + + @NotNull + @Schema(description = "media file name", example = "DJI_20220831151616_0004_W_Waypoint4.JPG") + private String name; + + @Schema(description = "media file path. This value is empty if the photo was not taken in the wayline.", example = "DJI_202208311455_008_Waypoint1") + private String path; + + public MediaFastUploadRequest() { + } + + @Override + public String toString() { + return "MediaFastUploadRequest{" + + "ext=" + ext + + ", fingerprint='" + fingerprint + '\'' + + ", name='" + name + '\'' + + ", path='" + path + '\'' + + '}'; + } + + public FastUploadExtension getExt() { + return ext; + } + + public MediaFastUploadRequest setExt(FastUploadExtension ext) { + this.ext = ext; + return this; + } + + public String getFingerprint() { + return fingerprint; + } + + public MediaFastUploadRequest setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + return this; + } + + public String getName() { + return name; + } + + public MediaFastUploadRequest setName(String name) { + this.name = name; + return this; + } + + public String getPath() { + return path; + } + + public MediaFastUploadRequest setPath(String path) { + this.path = path; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaFileExtension.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaFileExtension.java new file mode 100644 index 0000000..1f2b168 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaFileExtension.java @@ -0,0 +1,114 @@ +package org.dromara.common.sdk.cloudapi.media; + +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media file upload callback extension data") +public class MediaFileExtension { + + @NotNull + @JsonProperty("drone_model_key") + @Schema(description = "drone device product enum") + private DeviceEnum droneModelKey; + + @NotNull + @JsonProperty("file_group_id") + @Schema(description = "If the media file was shot during the wayline, this value will not be null.", format = "uuid") + private String fileGroupId; + + @JsonProperty("is_original") + @NotNull + @Schema(description = "Whether the image is the original image.") + private Boolean original; + + @NotNull + @JsonProperty("payload_model_key") + @Schema(description = "payload device product enum", example = "1-42-0") + private DeviceEnum payloadModelKey; + + @NotNull + @JsonProperty("tinny_fingerprint") + @Schema(description = "tiny fingerprint of the file.", example = "297f490b0252690d3f93841818567cc6_2022_8_31_15_16_16") + private String tinnyFingerprint; + + @NotNull + @Schema(description = "drone sn", example = "1AD3CA2VL3LAD6") + private String sn; + + public MediaFileExtension() { + } + + @Override + public String toString() { + return "MediaFileExtension{" + + "droneModelKey=" + droneModelKey + + ", fileGroupId='" + fileGroupId + '\'' + + ", original=" + original + + ", payloadModelKey=" + payloadModelKey + + ", tinnyFingerprint='" + tinnyFingerprint + '\'' + + ", sn='" + sn + '\'' + + '}'; + } + + public DeviceEnum getDroneModelKey() { + return droneModelKey; + } + + public MediaFileExtension setDroneModelKey(DeviceEnum droneModelKey) { + this.droneModelKey = droneModelKey; + return this; + } + + public Boolean getOriginal() { + return original; + } + + public MediaFileExtension setOriginal(Boolean original) { + this.original = original; + return this; + } + + public DeviceEnum getPayloadModelKey() { + return payloadModelKey; + } + + public MediaFileExtension setPayloadModelKey(DeviceEnum payloadModelKey) { + this.payloadModelKey = payloadModelKey; + return this; + } + + public String getTinnyFingerprint() { + return tinnyFingerprint; + } + + public MediaFileExtension setTinnyFingerprint(String tinnyFingerprint) { + this.tinnyFingerprint = tinnyFingerprint; + return this; + } + + public String getSn() { + return sn; + } + + public MediaFileExtension setSn(String sn) { + this.sn = sn; + return this; + } + + public String getFileGroupId() { + return fileGroupId; + } + + public MediaFileExtension setFileGroupId(String fileGroupId) { + this.fileGroupId = fileGroupId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaFileMetadata.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaFileMetadata.java new file mode 100644 index 0000000..1d072aa --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaFileMetadata.java @@ -0,0 +1,104 @@ +package org.dromara.common.sdk.cloudapi.media; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.time.LocalDateTime; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media file metadata") +public class MediaFileMetadata { + + @JsonProperty("absolute_altitude") + @NotNull + @Schema(description = "absolute height", example = "-36.889") + private Double absoluteAltitude; + + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssVV") + @NotNull + @Schema(description = "media create time", example = "2023-01-01T20:00:00+08:00") + @JsonProperty("created_time") + private LocalDateTime createdTime; + + @NotNull + @JsonProperty("gimbal_yaw_degree") + @Schema(description = "gimbal yaw degree", example = "-4.3") + private Double gimbalYawDegree; + + @NotNull + @JsonProperty("shoot_position") + @Valid + @Schema(description = "The latitude and longitude of the drone when the photo was taken") + private Position shootPosition; + + @NotNull + @JsonProperty("relative_altitude") + @Schema(description = "relative altitude", example = "100.001") + private Double relativeAltitude; + + public MediaFileMetadata() { + } + + @Override + public String toString() { + return "MediaFileMetadata{" + + "absoluteAltitude=" + absoluteAltitude + + ", createdTime=" + createdTime + + ", gimbalYawDegree=" + gimbalYawDegree + + ", shootPosition=" + shootPosition + + ", relativeAltitude=" + relativeAltitude + + '}'; + } + + public Double getAbsoluteAltitude() { + return absoluteAltitude; + } + + public MediaFileMetadata setAbsoluteAltitude(Double absoluteAltitude) { + this.absoluteAltitude = absoluteAltitude; + return this; + } + + public LocalDateTime getCreatedTime() { + return createdTime; + } + + public MediaFileMetadata setCreatedTime(LocalDateTime createdTime) { + this.createdTime = createdTime; + return this; + } + + public Double getGimbalYawDegree() { + return gimbalYawDegree; + } + + public MediaFileMetadata setGimbalYawDegree(Double gimbalYawDegree) { + this.gimbalYawDegree = gimbalYawDegree; + return this; + } + + public Position getShootPosition() { + return shootPosition; + } + + public MediaFileMetadata setShootPosition(Position shootPosition) { + this.shootPosition = shootPosition; + return this; + } + + public Double getRelativeAltitude() { + return relativeAltitude; + } + + public MediaFileMetadata setRelativeAltitude(Double relativeAltitude) { + this.relativeAltitude = relativeAltitude; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaMethodEnum.java new file mode 100644 index 0000000..e20e65e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaMethodEnum.java @@ -0,0 +1,24 @@ +package org.dromara.common.sdk.cloudapi.media; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum MediaMethodEnum { + + UPLOAD_FLIGHTTASK_MEDIA_PRIORITIZE("upload_flighttask_media_prioritize"); + + private final String method; + + MediaMethodEnum(String method) { + this.method = method; + } + + @JsonValue + public String getMethod() { + return method; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaSubFileTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaSubFileTypeEnum.java new file mode 100644 index 0000000..abd1872 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaSubFileTypeEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.media; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/16 + */ +@Schema(description = "The type of image file.

0: normal picture;

1: panorama.

") +public enum MediaSubFileTypeEnum { + + NORMAL(0), + + PANORAMA(1); + + private final int type; + + MediaSubFileTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static MediaSubFileTypeEnum find(int type) { + return Arrays.stream(values()).filter(subFile -> subFile.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(MediaSubFileTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaUploadCallbackRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaUploadCallbackRequest.java new file mode 100644 index 0000000..eaab50e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/MediaUploadCallbackRequest.java @@ -0,0 +1,124 @@ +package org.dromara.common.sdk.cloudapi.media; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media fast upload request data") +public class MediaUploadCallbackRequest { + + @NotNull + @Valid + private MediaFileExtension ext; + + @NotNull + @Schema(description = "media file fingerprint", example = "7F78C9F1999425CB61F10E1FE206009E") + private String fingerprint; + + @NotNull + @Schema(description = "media file name", example = "DJI_20220831151616_0004_W_Waypoint4.JPG") + private String name; + + @Schema(description = "media file path. This value is empty if the photo was not taken in the wayline.", example = "DJI_202208311455_008_Waypoint1") + private String path; + + @JsonProperty("object_key") + @NotNull + @Schema(description = "The key of the object in the bucket", example = "media/DJI_20220831151616_0004_W_Waypoint4.JPG") + private String objectKey; + + @Schema(type = "int") + @JsonProperty("sub_file_type") + @NotNull + private MediaSubFileTypeEnum subFileType; + + @Valid + @NotNull + private MediaFileMetadata metadata; + + public MediaUploadCallbackRequest() { + } + + @Override + public String toString() { + return "MediaUploadCallbackRequest{" + + "ext=" + ext + + ", fingerprint='" + fingerprint + '\'' + + ", name='" + name + '\'' + + ", path='" + path + '\'' + + ", objectKey='" + objectKey + '\'' + + ", subFileType=" + subFileType + + ", metadata=" + metadata + + '}'; + } + + public MediaFileExtension getExt() { + return ext; + } + + public MediaUploadCallbackRequest setExt(MediaFileExtension ext) { + this.ext = ext; + return this; + } + + public String getFingerprint() { + return fingerprint; + } + + public MediaUploadCallbackRequest setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + return this; + } + + public String getName() { + return name; + } + + public MediaUploadCallbackRequest setName(String name) { + this.name = name; + return this; + } + + public String getPath() { + return path; + } + + public MediaUploadCallbackRequest setPath(String path) { + this.path = path; + return this; + } + + public String getObjectKey() { + return objectKey; + } + + public MediaUploadCallbackRequest setObjectKey(String objectKey) { + this.objectKey = objectKey; + return this; + } + + public MediaSubFileTypeEnum getSubFileType() { + return subFileType; + } + + public MediaUploadCallbackRequest setSubFileType(MediaSubFileTypeEnum subFileType) { + this.subFileType = subFileType; + return this; + } + + public MediaFileMetadata getMetadata() { + return metadata; + } + + public MediaUploadCallbackRequest setMetadata(MediaFileMetadata metadata) { + this.metadata = metadata; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/Position.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/Position.java new file mode 100644 index 0000000..7f0c37c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/Position.java @@ -0,0 +1,50 @@ +package org.dromara.common.sdk.cloudapi.media; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +public class Position { + + @Schema(description = "latitude", example = "22.577666000000001") + @NotNull + private Double lat; + + @Schema(description = "longitude", example = "113.9431940000000") + @NotNull + private Double lng; + + public Position() { + } + + @Override + public String toString() { + return "Position{" + + "lat=" + lat + + ", lng=" + lng + + '}'; + } + + public Double getLat() { + return lat; + } + + public Position setLat(Double lat) { + this.lat = lat; + return this; + } + + public Double getLng() { + return lng; + } + + public Position setLng(Double lng) { + this.lng = lng; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/StorageConfigGet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/StorageConfigGet.java new file mode 100644 index 0000000..5f7fbe6 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/StorageConfigGet.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.media; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public class StorageConfigGet { + + private StorageConfigGetModuleEnum module; + + public StorageConfigGet() { + } + + @Override + public String toString() { + return "StorageConfigGet{" + + "module=" + module + + '}'; + } + + public StorageConfigGetModuleEnum getModule() { + return module; + } + + public StorageConfigGet setModule(StorageConfigGetModuleEnum module) { + this.module = module; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/StorageConfigGetModuleEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/StorageConfigGetModuleEnum.java new file mode 100644 index 0000000..3f450e9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/StorageConfigGetModuleEnum.java @@ -0,0 +1,34 @@ +package org.dromara.common.sdk.cloudapi.media; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public enum StorageConfigGetModuleEnum { + + MEDIA(0); + + private final int module; + + StorageConfigGetModuleEnum(int module) { + this.module = module; + } + + @JsonValue + public int getModule() { + return module; + } + + @JsonCreator + public StorageConfigGetModuleEnum find(int module) { + return Arrays.stream(values()).filter(moduleEnum -> moduleEnum.module == module).findAny() + .orElseThrow(() -> new CloudSDKException(StorageConfigGetModuleEnum.class, module)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/UploadCallbackFileExtension.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/UploadCallbackFileExtension.java new file mode 100644 index 0000000..79318ce --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/UploadCallbackFileExtension.java @@ -0,0 +1,70 @@ +package org.dromara.common.sdk.cloudapi.media; + +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +public class UploadCallbackFileExtension { + + private DeviceEnum droneModelKey; + + @JsonProperty("is_original") + private Boolean original; + + private DeviceEnum payloadModelKey; + + private String flightId; + + public UploadCallbackFileExtension() { + } + + @Override + public String toString() { + return "UploadCallbackFileExtension{" + + "droneModelKey=" + droneModelKey + + ", original=" + original + + ", payloadModelKey=" + payloadModelKey + + ", flightId='" + flightId + '\'' + + '}'; + } + + public DeviceEnum getDroneModelKey() { + return droneModelKey; + } + + public UploadCallbackFileExtension setDroneModelKey(DeviceEnum droneModelKey) { + this.droneModelKey = droneModelKey; + return this; + } + + public Boolean getOriginal() { + return original; + } + + public UploadCallbackFileExtension setOriginal(Boolean original) { + this.original = original; + return this; + } + + public DeviceEnum getPayloadModelKey() { + return payloadModelKey; + } + + public UploadCallbackFileExtension setPayloadModelKey(DeviceEnum payloadModelKey) { + this.payloadModelKey = payloadModelKey; + return this; + } + + public String getFlightId() { + return flightId; + } + + public UploadCallbackFileExtension setFlightId(String flightId) { + this.flightId = flightId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/UploadCallbackFileMetadata.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/UploadCallbackFileMetadata.java new file mode 100644 index 0000000..4440af8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/UploadCallbackFileMetadata.java @@ -0,0 +1,85 @@ +package org.dromara.common.sdk.cloudapi.media; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.time.LocalDateTime; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "media file metadata") +public class UploadCallbackFileMetadata { + + private Double absoluteAltitude; + + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssVV") + private LocalDateTime createdTime; + + private Double gimbalYawDegree; + + private Position shootPosition; + + private Double relativeAltitude; + + public UploadCallbackFileMetadata() { + } + + @Override + public String toString() { + return "MediaFileMetadata{" + + "absoluteAltitude=" + absoluteAltitude + + ", createdTime=" + createdTime + + ", gimbalYawDegree=" + gimbalYawDegree + + ", shootPosition=" + shootPosition + + ", relativeAltitude=" + relativeAltitude + + '}'; + } + + public Double getAbsoluteAltitude() { + return absoluteAltitude; + } + + public UploadCallbackFileMetadata setAbsoluteAltitude(Double absoluteAltitude) { + this.absoluteAltitude = absoluteAltitude; + return this; + } + + public LocalDateTime getCreatedTime() { + return createdTime; + } + + public UploadCallbackFileMetadata setCreatedTime(LocalDateTime createdTime) { + this.createdTime = createdTime; + return this; + } + + public Double getGimbalYawDegree() { + return gimbalYawDegree; + } + + public UploadCallbackFileMetadata setGimbalYawDegree(Double gimbalYawDegree) { + this.gimbalYawDegree = gimbalYawDegree; + return this; + } + + public Position getShootPosition() { + return shootPosition; + } + + public UploadCallbackFileMetadata setShootPosition(Position shootPosition) { + this.shootPosition = shootPosition; + return this; + } + + public Double getRelativeAltitude() { + return relativeAltitude; + } + + public UploadCallbackFileMetadata setRelativeAltitude(Double relativeAltitude) { + this.relativeAltitude = relativeAltitude; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/UploadFlighttaskMediaPrioritize.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/UploadFlighttaskMediaPrioritize.java new file mode 100644 index 0000000..0d1d324 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/UploadFlighttaskMediaPrioritize.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.cloudapi.media; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + + +/** + * @author sean + * @version 1.7 + * @date 2023/6/27 + */ +public class UploadFlighttaskMediaPrioritize extends BaseModel { + + @NotNull + @Pattern(regexp = "^[^<>:\"/|?*._\\\\]+$") + private String flightId; + + public UploadFlighttaskMediaPrioritize() { + } + + @Override + public String toString() { + return "UploadFlighttaskMediaPrioritize{" + + "flightId='" + flightId + '\'' + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public UploadFlighttaskMediaPrioritize setFlightId(String flightId) { + this.flightId = flightId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/api/AbstractMediaService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/api/AbstractMediaService.java new file mode 100644 index 0000000..824ec5c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/api/AbstractMediaService.java @@ -0,0 +1,78 @@ +package org.dromara.common.sdk.cloudapi.media.api; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.media.*; +import org.dromara.common.sdk.cloudapi.storage.StsCredentialsResponse; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.events.TopicEventsRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsResponse; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsRequest; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsResponse; +import org.dromara.common.sdk.mqtt.services.ServicesPublish; +import org.dromara.common.sdk.mqtt.services.ServicesReplyData; +import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; +import jakarta.annotation.Resource; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.MessageHeaders; + + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public abstract class AbstractMediaService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Result reporting of media file uploading + * @param request + * @param headers + * @return + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FILE_UPLOAD_CALLBACK, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse fileUploadCallback(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("fileUploadCallback not implemented"); + } + + /** + * Priority report of the media file uploading + * @param request + * @param headers + * @return + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse highestPriorityUploadFlightTaskMedia(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("highestPriorityUploadFlightTaskMedia not implemented"); + } + + /** + * Set the uploading file to highest priority + * @param gateway + * @param request data + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse uploadFlighttaskMediaPrioritize(GatewayManager gateway, UploadFlighttaskMediaPrioritize request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + MediaMethodEnum.UPLOAD_FLIGHTTASK_MEDIA_PRIORITIZE.getMethod(), + request); + } + + /** + * Obtain upload temporary credentials + * @param request + * @param headers + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_STORAGE_CONFIG_GET, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse> storageConfigGet(TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("storageConfigGet not implemented"); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/api/IHttpMediaService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/api/IHttpMediaService.java new file mode 100644 index 0000000..d25ea85 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/media/api/IHttpMediaService.java @@ -0,0 +1,116 @@ +package org.dromara.common.sdk.cloudapi.media.api; + +import org.dromara.common.sdk.cloudapi.media.*; +import org.dromara.common.sdk.common.HttpResultResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +@Tag(name = "media interface") +public interface IHttpMediaService { + + String PREFIX = "media/api/v1"; + + /** + * Check if the file has been uploaded by the fingerprint. + * @param workspaceId + * @param request + * @param req + * @param rsp + * @return + */ + @Operation(summary = "media fast upload", description = "Check if the file has been uploaded by the fingerprint.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/fast-upload") + HttpResultResponse mediaFastUpload( + @PathVariable(name = "workspace_id") String workspaceId, + @Valid @RequestBody MediaFastUploadRequest request, + HttpServletRequest req, HttpServletResponse rsp); + + + /** + * When the file is uploaded to the storage server by pilot, + * the basic information of the file is reported through this interface. + * @param workspaceId + * @param request + * @param req + * @param rsp + * @return + */ + @Operation(summary = "app reports file upload result", description = "When the file is uploaded to the storage server by pilot, " + + "the basic information of the file is reported through this interface.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }, responses = @ApiResponse(responseCode = "200", description = "OK", + content = @Content(mediaType = "application/json", + examples = {@ExampleObject(name = "responseObjectKey", + summary = "response object key", + description = "response object key", + value = "{\"code\": 0, \"message\":\"success\", \"data\": \"media/DJI_20220831151616_0004_W_Waypoint4.JPG\"}" + )}))) + + @PostMapping(PREFIX + "/workspaces/{workspace_id}/upload-callback") + HttpResultResponse mediaUploadCallback( + @PathVariable(name = "workspace_id") String workspaceId, + @Valid @RequestBody MediaUploadCallbackRequest request, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Query the files that already exist in this workspace based on the workspace id and the collection of tiny fingerprints. + * @param workspaceId + * @param request There is only one tiny_fingerprint parameter in the body. + * @param req + * @param rsp + * @return + */ + @Operation(summary = "checks whether the file fingerprint exists", description = "Query the files that already exist in this " + + "workspace based on the workspace id and the collection of tiny fingerprints.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/files/tiny-fingerprints") + HttpResultResponse getExistFileTinyFingerprint( + @PathVariable(name = "workspace_id") String workspaceId, + @Valid @RequestBody GetFileFingerprintRequest request, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Report the upload status of the media files in the file group in real time. + * @param workspaceId + * @param request + * @param req + * @param rsp + * @return + */ + @Operation(summary = "callback after the file group upload complete", description = "Report the upload status of " + + "the media files in the file group in real time.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/group-upload-callback") + HttpResultResponse folderUploadCallback( + @PathVariable(name = "workspace_id") String workspaceId, + @Valid @RequestBody FolderUploadCallbackRequest request, + HttpServletRequest req, HttpServletResponse rsp); + + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportBindStatusRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportBindStatusRequest.java new file mode 100644 index 0000000..2c095f4 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportBindStatusRequest.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.cloudapi.organization; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AirportBindStatusRequest { + + private List devices; + + public AirportBindStatusRequest() { + } + + @Override + public String toString() { + return "AirportBindStatusRequest{" + + "devices=" + devices + + '}'; + } + + public List getDevices() { + return devices; + } + + public AirportBindStatusRequest setDevices(List devices) { + this.devices = devices; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportBindStatusResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportBindStatusResponse.java new file mode 100644 index 0000000..e133421 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportBindStatusResponse.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.organization; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AirportBindStatusResponse extends BaseModel { + + @NotNull + @Size(min = 1, max = 2) + private List<@Valid BindStatusRequestDevice> bindStatus; + + public AirportBindStatusResponse() { + } + + @Override + public String toString() { + return "AirportBindStatusResponse{" + + "bindStatus=" + bindStatus + + '}'; + } + + public List getBindStatus() { + return bindStatus; + } + + public AirportBindStatusResponse setBindStatus(List bindStatus) { + this.bindStatus = bindStatus; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationBindRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationBindRequest.java new file mode 100644 index 0000000..ee1ed3f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationBindRequest.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.cloudapi.organization; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AirportOrganizationBindRequest { + + private List bindDevices; + + public AirportOrganizationBindRequest() { + } + + @Override + public String toString() { + return "AirportOrganizationBindRequest{" + + "bindDevices=" + bindDevices + + '}'; + } + + public List getBindDevices() { + return bindDevices; + } + + public AirportOrganizationBindRequest setBindDevices(List bindDevices) { + this.bindDevices = bindDevices; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationBindResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationBindResponse.java new file mode 100644 index 0000000..7e24a6c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationBindResponse.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.organization; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class AirportOrganizationBindResponse extends BaseModel { + + @NotNull + @Size(min = 1, max = 2) + private List<@Valid OrganizationBindInfo> errInfos; + + public AirportOrganizationBindResponse() { + } + + @Override + public String toString() { + return "AirportOrganizationBindResponse{" + + "errInfos=" + errInfos + + '}'; + } + + public List getErrInfos() { + return errInfos; + } + + public AirportOrganizationBindResponse setErrInfos(List errInfos) { + this.errInfos = errInfos; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationGetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationGetRequest.java new file mode 100644 index 0000000..2c16fea --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationGetRequest.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.cloudapi.organization; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/13 + */ +public class AirportOrganizationGetRequest { + + private String deviceBindingCode; + + private String organizationId; + + public AirportOrganizationGetRequest() { + } + + @Override + public String toString() { + return "AirportOrganizationGetRequest{" + + "deviceBindingCode='" + deviceBindingCode + '\'' + + ", organizationId='" + organizationId + '\'' + + '}'; + } + + public String getDeviceBindingCode() { + return deviceBindingCode; + } + + public AirportOrganizationGetRequest setDeviceBindingCode(String deviceBindingCode) { + this.deviceBindingCode = deviceBindingCode; + return this; + } + + public String getOrganizationId() { + return organizationId; + } + + public AirportOrganizationGetRequest setOrganizationId(String organizationId) { + this.organizationId = organizationId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationGetResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationGetResponse.java new file mode 100644 index 0000000..a2e374d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/AirportOrganizationGetResponse.java @@ -0,0 +1,35 @@ +package org.dromara.common.sdk.cloudapi.organization; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.1 + * @date 2022/6/13 + */ +public class AirportOrganizationGetResponse extends BaseModel { + + @NotNull + private String organizationName; + + public AirportOrganizationGetResponse() { + } + + @Override + public String toString() { + return "AirportOrganizationGetResponse{" + + "organizationName='" + organizationName + '\'' + + '}'; + } + + public String getOrganizationName() { + return organizationName; + } + + public AirportOrganizationGetResponse setOrganizationName(String organizationName) { + this.organizationName = organizationName; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/BindStatusRequestDevice.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/BindStatusRequestDevice.java new file mode 100644 index 0000000..6c021b5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/BindStatusRequestDevice.java @@ -0,0 +1,88 @@ +package org.dromara.common.sdk.cloudapi.organization; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.1 + * @date 2022/6/14 + */ +public class BindStatusRequestDevice { + + @NotNull + private String sn; + + @NotNull + @JsonProperty("is_device_bind_organization") + private Boolean deviceBindOrganization; + + @NotNull + private String organizationId; + + @NotNull + private String organizationName; + + @NotNull + private String deviceCallsign; + + public BindStatusRequestDevice() { + } + + @Override + public String toString() { + return "BindStatusRequestDevice{" + + "sn='" + sn + '\'' + + ", deviceBindOrganization=" + deviceBindOrganization + + ", organizationId='" + organizationId + '\'' + + ", organizationName='" + organizationName + '\'' + + ", deviceCallsign='" + deviceCallsign + '\'' + + '}'; + } + + public String getSn() { + return sn; + } + + public BindStatusRequestDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public Boolean getDeviceBindOrganization() { + return deviceBindOrganization; + } + + public BindStatusRequestDevice setDeviceBindOrganization(Boolean deviceBindOrganization) { + this.deviceBindOrganization = deviceBindOrganization; + return this; + } + + public String getOrganizationId() { + return organizationId; + } + + public BindStatusRequestDevice setOrganizationId(String organizationId) { + this.organizationId = organizationId; + return this; + } + + public String getOrganizationName() { + return organizationName; + } + + public BindStatusRequestDevice setOrganizationName(String organizationName) { + this.organizationName = organizationName; + return this; + } + + public String getDeviceCallsign() { + return deviceCallsign; + } + + public BindStatusRequestDevice setDeviceCallsign(String deviceCallsign) { + this.deviceCallsign = deviceCallsign; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/BindStatusResponseDevice.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/BindStatusResponseDevice.java new file mode 100644 index 0000000..4255ece --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/BindStatusResponseDevice.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.organization; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class BindStatusResponseDevice { + + private String sn; + + public BindStatusResponseDevice() { + } + + @Override + public String toString() { + return "BindStatusResponseDevice{" + + "sn='" + sn + '\'' + + '}'; + } + + public String getSn() { + return sn; + } + + public BindStatusResponseDevice setSn(String sn) { + this.sn = sn; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/OrganizationBindDevice.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/OrganizationBindDevice.java new file mode 100644 index 0000000..d74b355 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/OrganizationBindDevice.java @@ -0,0 +1,80 @@ +package org.dromara.common.sdk.cloudapi.organization; + +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/13 + */ +public class OrganizationBindDevice { + + private String deviceBindingCode; + + private String organizationId; + + private String deviceCallsign; + + private String sn; + + private DeviceEnum deviceModelKey; + + public OrganizationBindDevice() { + } + + @Override + public String toString() { + return "OrganizationBindDevice{" + + "deviceBindingCode='" + deviceBindingCode + '\'' + + ", organizationId='" + organizationId + '\'' + + ", deviceCallsign='" + deviceCallsign + '\'' + + ", sn='" + sn + '\'' + + ", deviceModelKey=" + deviceModelKey + + '}'; + } + + public String getDeviceBindingCode() { + return deviceBindingCode; + } + + public OrganizationBindDevice setDeviceBindingCode(String deviceBindingCode) { + this.deviceBindingCode = deviceBindingCode; + return this; + } + + public String getOrganizationId() { + return organizationId; + } + + public OrganizationBindDevice setOrganizationId(String organizationId) { + this.organizationId = organizationId; + return this; + } + + public String getDeviceCallsign() { + return deviceCallsign; + } + + public OrganizationBindDevice setDeviceCallsign(String deviceCallsign) { + this.deviceCallsign = deviceCallsign; + return this; + } + + public String getSn() { + return sn; + } + + public OrganizationBindDevice setSn(String sn) { + this.sn = sn; + return this; + } + + public DeviceEnum getDeviceModelKey() { + return deviceModelKey; + } + + public OrganizationBindDevice setDeviceModelKey(DeviceEnum deviceModelKey) { + this.deviceModelKey = deviceModelKey; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/OrganizationBindInfo.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/OrganizationBindInfo.java new file mode 100644 index 0000000..542f214 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/OrganizationBindInfo.java @@ -0,0 +1,57 @@ +package org.dromara.common.sdk.cloudapi.organization; + +import org.dromara.common.sdk.mqtt.MqttReply; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.1 + * @date 2022/6/14 + */ +public class OrganizationBindInfo { + + @NotNull + private String sn; + + @NotNull + private Integer errCode; + + public OrganizationBindInfo() { + } + + public OrganizationBindInfo(String sn, Integer errCode) { + this.sn = sn; + this.errCode = errCode; + } + + public static OrganizationBindInfo success(String sn) { + return new OrganizationBindInfo(sn, MqttReply.CODE_SUCCESS); + } + + @Override + public String toString() { + return "OrganizationBindInfo{" + + "sn='" + sn + '\'' + + ", errCode=" + errCode + + '}'; + } + + public String getSn() { + return sn; + } + + public OrganizationBindInfo setSn(String sn) { + this.sn = sn; + return this; + } + + public Integer getErrCode() { + return errCode; + } + + public OrganizationBindInfo setErrCode(Integer errCode) { + this.errCode = errCode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/api/AbstractOrganizationService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/api/AbstractOrganizationService.java new file mode 100644 index 0000000..e66917a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/organization/api/AbstractOrganizationService.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.organization.api; + +import org.dromara.common.sdk.cloudapi.organization.*; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsRequest; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsResponse; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public abstract class AbstractOrganizationService { + + /** + * Obtain organization binding information + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_AIRPORT_BIND_STATUS, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse> airportBindStatus( + TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("airportBindStatus not implemented"); + } + + /** + * Search for the organization information that device bound to + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse> airportOrganizationGet( + TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("airportOrganizationGet not implemented"); + } + + /** + * Device bind to organization + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_BIND, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse> airportOrganizationBind( + TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("airportOrganizationBind not implemented"); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DistanceLimitStatusData.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DistanceLimitStatusData.java new file mode 100644 index 0000000..750b38f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DistanceLimitStatusData.java @@ -0,0 +1,51 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.SwitchActionEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; + +/** + * The state of the drone's limited distance + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class DistanceLimitStatusData { + + private SwitchActionEnum state; + + @Min(15) + @Max(8000) + @JsonProperty("distance_limit") + private Integer distanceLimit; + + public DistanceLimitStatusData() { + } + + @Override + public String toString() { + return "DistanceLimitStatusData{" + + "state=" + state + + ", distanceLimit=" + distanceLimit + + '}'; + } + + public SwitchActionEnum getState() { + return state; + } + + public DistanceLimitStatusData setState(SwitchActionEnum state) { + this.state = state; + return this; + } + + public Integer getDistanceLimit() { + return distanceLimit; + } + + public DistanceLimitStatusData setDistanceLimit(Integer distanceLimit) { + this.distanceLimit = distanceLimit; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DistanceLimitStatusSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DistanceLimitStatusSet.java new file mode 100644 index 0000000..0447b1d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DistanceLimitStatusSet.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +/** + * The state of the drone's limited distance + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class DistanceLimitStatusSet extends BaseModel { + + @Valid + @NotNull + private DistanceLimitStatusData distanceLimitStatus; + + public DistanceLimitStatusSet() { + } + + @Override + public String toString() { + return "DistanceLimitStatusSet{" + + "distanceLimitStatus=" + distanceLimitStatus + + '}'; + } + + public DistanceLimitStatusData getDistanceLimitStatus() { + return distanceLimitStatus; + } + + public DistanceLimitStatusSet setDistanceLimitStatus(DistanceLimitStatusData distanceLimitStatus) { + this.distanceLimitStatus = distanceLimitStatus; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneCommanderFlightHeight.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneCommanderFlightHeight.java new file mode 100644 index 0000000..b36c293 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneCommanderFlightHeight.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class DockDroneCommanderFlightHeight extends BaseModel { + + @JsonProperty("commander_flight_height") + @NotNull + @Min(2) + @Max(3000) + private Float commanderFlightHeight; + + public DockDroneCommanderFlightHeight() { + } + + @Override + public String toString() { + return "DockDroneCommanderFlightHeight{" + + "commanderFlightHeight=" + commanderFlightHeight + + '}'; + } + + public Float getCommanderFlightHeight() { + return commanderFlightHeight; + } + + public DockDroneCommanderFlightHeight setCommanderFlightHeight(Float commanderFlightHeight) { + this.commanderFlightHeight = commanderFlightHeight; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneCommanderModeLostAction.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneCommanderModeLostAction.java new file mode 100644 index 0000000..55f148d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneCommanderModeLostAction.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.control.CommanderModeLostActionEnum; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/19 + */ +public class DockDroneCommanderModeLostAction extends BaseModel { + + @JsonProperty("commander_mode_lost_action") + @NotNull + private CommanderModeLostActionEnum commanderModeLostAction; + + public DockDroneCommanderModeLostAction() { + } + + @Override + public String toString() { + return "DockDroneCommanderModeLostAction{" + + "commanderModeLostAction=" + commanderModeLostAction + + '}'; + } + + public CommanderModeLostActionEnum getCommanderModeLostAction() { + return commanderModeLostAction; + } + + public DockDroneCommanderModeLostAction setCommanderModeLostAction(CommanderModeLostActionEnum commanderModeLostAction) { + this.commanderModeLostAction = commanderModeLostAction; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneOfflineMapEnable.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneOfflineMapEnable.java new file mode 100644 index 0000000..41a50d0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneOfflineMapEnable.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/20 + */ +public class DockDroneOfflineMapEnable extends BaseModel { + + @JsonProperty("offline_map_enable") + @NotNull + private Boolean offlineMapEnable; + + public DockDroneOfflineMapEnable() { + } + + @Override + public String toString() { + return "DockDroneOfflineMapEnable{" + + "offlineMapEnable=" + offlineMapEnable + + '}'; + } + + public Boolean getOfflineMapEnable() { + return offlineMapEnable; + } + + public DockDroneOfflineMapEnable setOfflineMapEnable(Boolean offlineMapEnable) { + this.offlineMapEnable = offlineMapEnable; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneRthMode.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneRthMode.java new file mode 100644 index 0000000..a76f67f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/DockDroneRthMode.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.wayline.RthModeEnum; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/11 + */ +public class DockDroneRthMode extends BaseModel { + + @JsonProperty("rth_mode") + @NotNull + private RthModeEnum rthMode; + + public DockDroneRthMode() { + } + + @Override + public String toString() { + return "DockDroneRthMode{" + + "rthMode=" + rthMode + + '}'; + } + + public RthModeEnum getRthMode() { + return rthMode; + } + + public DockDroneRthMode setRthMode(RthModeEnum rthMode) { + this.rthMode = rthMode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ExitWaylineWhenRcLostSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ExitWaylineWhenRcLostSet.java new file mode 100644 index 0000000..8452cef --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ExitWaylineWhenRcLostSet.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public class ExitWaylineWhenRcLostSet extends BaseModel { + + @NotNull + @JsonProperty("exit_wayline_when_rc_lost") + private ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost; + + public ExitWaylineWhenRcLostSet() { + } + + @Override + public String toString() { + return "ExitWaylineWhenRcLostSet{" + + "exitWaylineWhenRcLost=" + exitWaylineWhenRcLost + + '}'; + } + + public ExitWaylineWhenRcLostEnum getExitWaylineWhenRcLost() { + return exitWaylineWhenRcLost; + } + + public ExitWaylineWhenRcLostSet setExitWaylineWhenRcLost(ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost) { + this.exitWaylineWhenRcLost = exitWaylineWhenRcLost; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/HeightLimitSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/HeightLimitSet.java new file mode 100644 index 0000000..8b3b1e1 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/HeightLimitSet.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.3 + * @date 2022/10/28 + */ +public class HeightLimitSet extends BaseModel { + + @NotNull + @Max(1500) + @Min(20) + @JsonProperty("height_limit") + private Integer heightLimit; + + public HeightLimitSet() { + } + + @Override + public String toString() { + return "HeightLimitSet{" + + "heightLimit=" + heightLimit + + '}'; + } + + public Integer getHeightLimit() { + return heightLimit; + } + + public HeightLimitSet setHeightLimit(Integer heightLimit) { + this.heightLimit = heightLimit; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/NightLightsStateSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/NightLightsStateSet.java new file mode 100644 index 0000000..8310dd9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/NightLightsStateSet.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.SwitchActionEnum; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class NightLightsStateSet extends BaseModel { + + @NotNull + @JsonProperty("night_lights_state") + private SwitchActionEnum nightLightsState; + + public NightLightsStateSet() { + } + + @Override + public String toString() { + return "NightLightsStateSet{" + + "nightLightsState=" + nightLightsState + + '}'; + } + + public SwitchActionEnum getNightLightsState() { + return nightLightsState; + } + + public NightLightsStateSet setNightLightsState(SwitchActionEnum nightLightsState) { + this.nightLightsState = nightLightsState; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ObstacleAvoidanceSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ObstacleAvoidanceSet.java new file mode 100644 index 0000000..aa54d9b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ObstacleAvoidanceSet.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.ObstacleAvoidance; +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class ObstacleAvoidanceSet extends BaseModel { + + @Valid + @NotNull + private ObstacleAvoidance obstacleAvoidance; + + public ObstacleAvoidanceSet() { + } + + @Override + public String toString() { + return "ObstacleAvoidanceSet{" + + "obstacleAvoidance=" + obstacleAvoidance + + '}'; + } + + public ObstacleAvoidance getObstacleAvoidance() { + return obstacleAvoidance; + } + + public ObstacleAvoidanceSet setObstacleAvoidance(ObstacleAvoidance obstacleAvoidance) { + this.obstacleAvoidance = obstacleAvoidance; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/PropertySetEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/PropertySetEnum.java new file mode 100644 index 0000000..6533267 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/PropertySetEnum.java @@ -0,0 +1,106 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.DockSilentMode; +import org.dromara.common.sdk.common.BaseModel; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.exception.CloudSDKException; + +import java.util.Arrays; +import java.util.Set; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public enum PropertySetEnum { + + NIGHT_LIGHTS_STATE("night_lights_state", NightLightsStateSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + HEIGHT_LIMIT("height_limit", HeightLimitSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + DISTANCE_LIMIT_STATUS("distance_limit_status", DistanceLimitStatusSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + OBSTACLE_AVOIDANCE("obstacle_avoidance", ObstacleAvoidanceSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + RTH_ALTITUDE("rth_altitude", RthAltitudeSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + OUT_OF_CONTROL_ACTION("rc_lost_action", RcLostActionSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + EXIT_WAYLINE_WHEN_RC_LOST("exit_wayline_when_rc_lost", ExitWaylineWhenRcLostSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2), true), + + THERMAL_CURRENT_PALETTE_STYLE("thermal_current_palette_style", ThermalCurrentPaletteStyleSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + THERMAL_GAIN_MODE("thermal_gain_mode", ThermalGainModeSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + THERMAL_ISOTHERM_STATE("thermal_isotherm_state", ThermalIsothermStateSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + THERMAL_ISOTHERM_UPPER_LIMIT("thermal_isotherm_upper_limit", ThermalIsothermUpperLimitSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + THERMAL_ISOTHERM_LOWER_LIMIT("thermal_isotherm_lower_limit", ThermalIsothermLowerLimitSet.class, CloudSDKVersionEnum.V0_0_1, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + RTH_MODE("rth_mode", DockDroneRthMode.class, CloudSDKVersionEnum.V1_0_0, Set.of(GatewayTypeEnum.DOCK2)), + + USER_EXPERIENCE_IMPROVEMENT("user_experience_improvement", UserExperienceImprovementSet.class, CloudSDKVersionEnum.V1_0_0, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + COMMANDER_MODE_LOST_ACTION("commander_mode_lost_action", DockDroneCommanderModeLostAction.class, CloudSDKVersionEnum.V1_0_0, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + COMMANDER_FLIGHT_HEIGHT("commander_flight_height", DockDroneCommanderFlightHeight.class, CloudSDKVersionEnum.V1_0_0, Set.of(GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2)), + + OFFLINE_MAP_ENABLE("offline_map_enable", DockDroneOfflineMapEnable.class, CloudSDKVersionEnum.V1_0_1, Set.of(GatewayTypeEnum.DOCK2)), + + SILENT_MODE("silent_mode", DockSilentMode.class, CloudSDKVersionEnum.V1_0_2, Set.of(GatewayTypeEnum.DOCK)), + + ; + + private final String property; + + private final Class clazz; + + private final CloudSDKVersionEnum since; + + private final Set supportedDevices; + + private boolean deprecated; + + PropertySetEnum(String property, Class clazz, CloudSDKVersionEnum since, Set supportedDevices) { + this.property = property; + this.clazz = clazz; + this.since = since; + this.supportedDevices = supportedDevices; + } + + PropertySetEnum(String property, Class clazz, CloudSDKVersionEnum since, Set supportedDevices, boolean deprecated) { + this.property = property; + this.clazz = clazz; + this.since = since; + this.supportedDevices = supportedDevices; + this.deprecated = deprecated; + } + + public String getProperty() { + return property; + } + + public Class getClazz() { + return clazz; + } + + public CloudSDKVersionEnum getSince() { + return since; + } + + public Set getSupportedDevices() { + return supportedDevices; + } + + public boolean isDeprecated() { + return deprecated; + } + + public static PropertySetEnum find(String property) { + return Arrays.stream(values()).filter(propertyEnum -> propertyEnum.property.equals(property)).findAny() + .orElseThrow(() -> new CloudSDKException(PropertySetEnum.class, property)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/RcLostActionSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/RcLostActionSet.java new file mode 100644 index 0000000..1177f7d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/RcLostActionSet.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.RcLostActionEnum; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public class RcLostActionSet extends BaseModel { + + @NotNull + @JsonProperty("rc_lost_action") + private RcLostActionEnum rcLostAction; + + public RcLostActionSet() { + } + + @Override + public String toString() { + return "RcLostActionSet{" + + "rcLostAction=" + rcLostAction + + '}'; + } + + public RcLostActionEnum getRcLostAction() { + return rcLostAction; + } + + public RcLostActionSet setRcLostAction(RcLostActionEnum rcLostAction) { + this.rcLostAction = rcLostAction; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/RthAltitudeSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/RthAltitudeSet.java new file mode 100644 index 0000000..272aacd --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/RthAltitudeSet.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public class RthAltitudeSet extends BaseModel { + + @NotNull + @Min(20) + @Max(50) + @JsonProperty("rth_altitude") + private Integer rthAltitude; + + public RthAltitudeSet() { + } + + @Override + public String toString() { + return "RthAltitudeSet{" + + "rthAltitude=" + rthAltitude + + '}'; + } + + public Integer getRthAltitude() { + return rthAltitude; + } + + public RthAltitudeSet setRthAltitude(Integer rthAltitude) { + this.rthAltitude = rthAltitude; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/SilentModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/SilentModeEnum.java new file mode 100644 index 0000000..55120ca --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/SilentModeEnum.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @date 2023/12/12 + * @version 1.9 + */ +public enum SilentModeEnum { + + RING(0), + + SILENT(1), + + ; + + private final int mode; + + SilentModeEnum(int mode) { + this.mode = mode; + } + + @JsonValue + public int getMode() { + return mode; + } + + @JsonCreator + public static SilentModeEnum find(int mode) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.mode == mode).findAny() + .orElseThrow(() -> new CloudSDKException(SilentModeEnum.class, mode)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalCurrentPaletteStyleSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalCurrentPaletteStyleSet.java new file mode 100644 index 0000000..e7e923a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalCurrentPaletteStyleSet.java @@ -0,0 +1,60 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.cloudapi.device.ThermalPaletteStyleEnum; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +import java.util.Map; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class ThermalCurrentPaletteStyleSet extends BaseModel { + + @NotNull + @Valid + private PayloadIndex payloadIndex; + + @NotNull + private ThermalPaletteStyleEnum thermalCurrentPaletteStyle; + + public ThermalCurrentPaletteStyleSet() { + } + + @Override + public String toString() { + return "ThermalCurrentPaletteStyleSet{" + + "payloadIndex=" + payloadIndex + + ", thermalCurrentPaletteStyle=" + thermalCurrentPaletteStyle + + '}'; + } + + @JsonValue + public Map toMap() { + return Map.of(payloadIndex.toString(), Map.of("thermal_current_palette_style", thermalCurrentPaletteStyle.getStyle())); + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public ThermalCurrentPaletteStyleSet setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ThermalPaletteStyleEnum getThermalCurrentPaletteStyle() { + return thermalCurrentPaletteStyle; + } + + public ThermalCurrentPaletteStyleSet setThermalCurrentPaletteStyle(ThermalPaletteStyleEnum thermalCurrentPaletteStyle) { + this.thermalCurrentPaletteStyle = thermalCurrentPaletteStyle; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalGainModeSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalGainModeSet.java new file mode 100644 index 0000000..6aed572 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalGainModeSet.java @@ -0,0 +1,59 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.cloudapi.device.ThermalGainModeEnum; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.util.Map; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class ThermalGainModeSet extends BaseModel { + + @NotNull + @Valid + private PayloadIndex payloadIndex; + + @NotNull + private ThermalGainModeEnum thermalGainMode; + + public ThermalGainModeSet() { + } + + @Override + public String toString() { + return "ThermalGainModeSet{" + + "payloadIndex=" + payloadIndex + + ", thermalGainMode=" + thermalGainMode + + '}'; + } + + @JsonValue + public Map toMap() { + return Map.of(payloadIndex.toString(), Map.of("thermal_gain_mode", thermalGainMode.getMode())); + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public ThermalGainModeSet setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public ThermalGainModeEnum getThermalGainMode() { + return thermalGainMode; + } + + public ThermalGainModeSet setThermalGainMode(ThermalGainModeEnum thermalGainMode) { + this.thermalGainMode = thermalGainMode; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalIsothermLowerLimitSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalIsothermLowerLimitSet.java new file mode 100644 index 0000000..61475fb --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalIsothermLowerLimitSet.java @@ -0,0 +1,58 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.util.Map; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class ThermalIsothermLowerLimitSet extends BaseModel { + + @NotNull + @Valid + private PayloadIndex payloadIndex; + + @NotNull + private Integer thermalIsothermLowerLimit; + + public ThermalIsothermLowerLimitSet() { + } + + @Override + public String toString() { + return "ThermalIsothermLowerLimitSet{" + + "payloadIndex=" + payloadIndex + + ", thermalIsothermLowerLimit=" + thermalIsothermLowerLimit + + '}'; + } + + @JsonValue + public Map toMap() { + return Map.of(payloadIndex.toString(), Map.of("thermal_isotherm_upper_limit", thermalIsothermLowerLimit)); + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public ThermalIsothermLowerLimitSet setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public Integer getThermalIsothermLowerLimit() { + return thermalIsothermLowerLimit; + } + + public ThermalIsothermLowerLimitSet setThermalIsothermLowerLimit(Integer thermalIsothermLowerLimit) { + this.thermalIsothermLowerLimit = thermalIsothermLowerLimit; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalIsothermStateSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalIsothermStateSet.java new file mode 100644 index 0000000..68b419e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalIsothermStateSet.java @@ -0,0 +1,60 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.cloudapi.device.SwitchActionEnum; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +import java.util.Map; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class ThermalIsothermStateSet extends BaseModel { + + @NotNull + @Valid + private PayloadIndex payloadIndex; + + @NotNull + private SwitchActionEnum thermalIsothermState; + + public ThermalIsothermStateSet() { + } + + @Override + public String toString() { + return "ThermalGainModeSet{" + + "payloadIndex=" + payloadIndex + + ", thermalIsothermState=" + thermalIsothermState + + '}'; + } + + @JsonValue + public Map toMap() { + return Map.of(payloadIndex.toString(), Map.of("thermal_isotherm_state", thermalIsothermState.getAction())); + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public ThermalIsothermStateSet setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public SwitchActionEnum getThermalIsothermState() { + return thermalIsothermState; + } + + public ThermalIsothermStateSet setThermalIsothermState(SwitchActionEnum thermalIsothermState) { + this.thermalIsothermState = thermalIsothermState; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalIsothermUpperLimitSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalIsothermUpperLimitSet.java new file mode 100644 index 0000000..616e949 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/ThermalIsothermUpperLimitSet.java @@ -0,0 +1,59 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.PayloadIndex; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +import java.util.Map; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public class ThermalIsothermUpperLimitSet extends BaseModel { + + @NotNull + @Valid + private PayloadIndex payloadIndex; + + @NotNull + private Integer thermalIsothermUpperLimit; + + public ThermalIsothermUpperLimitSet() { + } + + @Override + public String toString() { + return "ThermalIsothermUpperLimitSet{" + + "payloadIndex=" + payloadIndex + + ", thermalIsothermUpperLimit=" + thermalIsothermUpperLimit + + '}'; + } + + @JsonValue + public Map toMap() { + return Map.of(payloadIndex.toString(), Map.of("thermal_isotherm_upper_limit", thermalIsothermUpperLimit)); + } + + public PayloadIndex getPayloadIndex() { + return payloadIndex; + } + + public ThermalIsothermUpperLimitSet setPayloadIndex(PayloadIndex payloadIndex) { + this.payloadIndex = payloadIndex; + return this; + } + + public Integer getThermalIsothermUpperLimit() { + return thermalIsothermUpperLimit; + } + + public ThermalIsothermUpperLimitSet setThermalIsothermUpperLimit(Integer thermalIsothermUpperLimit) { + this.thermalIsothermUpperLimit = thermalIsothermUpperLimit; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/UserExperienceImprovementSet.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/UserExperienceImprovementSet.java new file mode 100644 index 0000000..31b8ea6 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/UserExperienceImprovementSet.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.property; + +import org.dromara.common.sdk.cloudapi.device.UserExperienceImprovementEnum; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 1.7 + * @date 2023/10/13 + */ +public class UserExperienceImprovementSet extends BaseModel { + + @NotNull + @JsonProperty("user_experience_improvement") + private UserExperienceImprovementEnum userExperienceImprovement; + + public UserExperienceImprovementSet() { + } + + @Override + public String toString() { + return "UserExperienceImprovementSet{" + + "userExperienceImprovement=" + userExperienceImprovement + + '}'; + } + + public UserExperienceImprovementEnum getUserExperienceImprovement() { + return userExperienceImprovement; + } + + public UserExperienceImprovementSet setUserExperienceImprovement(UserExperienceImprovementEnum userExperienceImprovement) { + this.userExperienceImprovement = userExperienceImprovement; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/api/AbstractPropertyService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/api/AbstractPropertyService.java new file mode 100644 index 0000000..2f14c18 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/property/api/AbstractPropertyService.java @@ -0,0 +1,89 @@ +package org.dromara.common.sdk.cloudapi.property.api; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.property.PropertySetEnum; +import org.dromara.common.sdk.common.BaseModel; +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.dromara.common.sdk.mqtt.property.PropertySetPublish; +import org.dromara.common.sdk.mqtt.property.PropertySetReplyResultEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/30 + */ +public abstract class AbstractPropertyService { + + @Resource + private PropertySetPublish propertySetPublish; + + /** + * Device property set + * @param gateway + * @param propertyEnum + * @param request + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public PropertySetReplyResultEnum propertySet(GatewayManager gateway, PropertySetEnum propertyEnum, BaseModel request) { + checkCondition(gateway, propertyEnum, request); + + Common.validateModel(request); + Field[] fields = request.getClass().getDeclaredFields(); + if (fields.length > 1 || null == fields[0].getDeclaredAnnotation(Valid.class)) { + return propertySetPublish.publish(gateway.getGatewaySn(), request); + } + + try { + Map map = new HashMap<>(); + fields[0].setAccessible(true); + Object child = fields[0].get(request); + for (Field field : ((Class) fields[0].getGenericType()).getDeclaredFields()) { + field.setAccessible(true); + Object value = field.get(child); + if (Objects.isNull(value)) { + continue; + } + map.put(Optional.ofNullable(field.getDeclaredAnnotation(JsonProperty.class)) + .map(JsonProperty::value).orElse(field.getName()), value); + field.setAccessible(false); + PropertySetReplyResultEnum result = propertySetPublish.publish( + gateway.getGatewaySn(), Map.of(propertyEnum.getProperty(), map)); + if (PropertySetReplyResultEnum.SUCCESS != result) { + return result; + } + map.clear(); + } + fields[0].setAccessible(false); + + } catch (IllegalAccessException e) { + throw new CloudSDKException(e); + } + return PropertySetReplyResultEnum.SUCCESS; + } + + private void checkCondition(GatewayManager gateway, PropertySetEnum propertyEnum, BaseModel request) { + if (Objects.isNull(request) || propertyEnum.getClazz() != request.getClass()) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + if (!propertyEnum.getSupportedDevices().contains(gateway.getType())) { + throw new CloudSDKException(CloudSDKErrorEnum.DEVICE_TYPE_NOT_SUPPORT); + } + if (propertyEnum.isDeprecated() || !gateway.getSdkVersion().isSupported(propertyEnum.getSince())) { + throw new CloudSDKException(CloudSDKErrorEnum.DEVICE_VERSION_NOT_SUPPORT); + } + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/CredentialsToken.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/CredentialsToken.java new file mode 100644 index 0000000..81cee25 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/CredentialsToken.java @@ -0,0 +1,94 @@ +package org.dromara.common.sdk.cloudapi.storage; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "The token data of the temporary credential") +public class CredentialsToken { + + private static final int DELAY = 300; + + @NotNull + @Schema(description = "access key id", example = "3POX6W77L1EF4C86L2RE") + @JsonProperty("access_key_id") + private String accessKeyId; + + @NotNull + @Schema(description = "access key secret", example = "9NG2P2yJaUrck576CkdRoRbchKssJiZygi5D93CBsduY") + @JsonProperty("access_key_secret") + private String accessKeySecret; + + @NotNull + @Min(1) + @Schema(description = "The valid time of the token, in seconds.", example = "3600") + private Long expire; + + @NotNull + @JsonProperty("security_token") + @Schema(description = "security token", example = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiIzUE9YNlc3N0wxRUY0Qzg2TDJSRSIsImV4cCI6MTY4NjgxOTgyOSwicGFyZW50IjoibWluaW8ifQ.cWJXI90UidrBOTD0gWxKt8PT5Qp_6dEK5wNfJuE6lR9dH6Us7jtSB8vcttRDwPhpCNrAGsv91ydw6NLMyjqAOw") + private String securityToken; + + public CredentialsToken(@NotNull String accessKeyId, @NotNull String accessKeySecret, @NotNull String securityToken, @NotNull @Min(1) Long expire) { + this.accessKeyId = accessKeyId; + this.accessKeySecret = accessKeySecret; + this.securityToken = securityToken; + this.expire = expire - DELAY; + } + + public CredentialsToken() { + } + + @Override + public String toString() { + return "CredentialsToken{" + + "accessKeyId='" + accessKeyId + '\'' + + ", accessKeySecret='" + accessKeySecret + '\'' + + ", expire=" + expire + + ", securityToken='" + securityToken + '\'' + + '}'; + } + + public String getAccessKeyId() { + return accessKeyId; + } + + public CredentialsToken setAccessKeyId(String accessKeyId) { + this.accessKeyId = accessKeyId; + return this; + } + + public String getAccessKeySecret() { + return accessKeySecret; + } + + public CredentialsToken setAccessKeySecret(String accessKeySecret) { + this.accessKeySecret = accessKeySecret; + return this; + } + + public Long getExpire() { + return expire; + } + + public CredentialsToken setExpire(Long expire) { + this.expire = expire; + return this; + } + + public String getSecurityToken() { + return securityToken; + } + + public CredentialsToken setSecurityToken(String securityToken) { + this.securityToken = securityToken; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/OssTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/OssTypeEnum.java new file mode 100644 index 0000000..29f266b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/OssTypeEnum.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.storage; + +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/30 + */ +@Schema(description = "oss type", example = "minio", enumAsRef = true) +public enum OssTypeEnum { + + ALIYUN("ali"), + + AWS("aws"), + + MINIO("minio"); + + private String type; + + OssTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/StsCredentialsResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/StsCredentialsResponse.java new file mode 100644 index 0000000..5fe6389 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/StsCredentialsResponse.java @@ -0,0 +1,113 @@ +package org.dromara.common.sdk.cloudapi.storage; + +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Schema(description = "Temporary credential data") +public class StsCredentialsResponse extends BaseModel { + + @Schema(description = "bucket name", example = "bucket-api") + @NotNull + private String bucket; + + @NotNull + @Valid + @Schema(description = "The token data of the temporary credential") + private CredentialsToken credentials; + + @NotNull + @Schema(description = "access domain name for external services", example = "https://oss-cn-hangzhou.aliyuncs.com") + @Pattern(regexp = "^http[s]?://.*$") + private String endpoint; + + @NotNull + @JsonProperty("object_key_prefix") + @Schema(description = "The folder path where the object needs to be stored.", example = "files/wayline") + private String objectKeyPrefix; + + @NotNull + private OssTypeEnum provider; + + @NotNull + @Schema(description = "The region where the bucket is located.", example = "us-east-1") + private String region; + + public StsCredentialsResponse() { + } + + @Override + public String toString() { + return "StsCredentialsResponse{" + + "bucket='" + bucket + '\'' + + ", credentials=" + credentials + + ", endpoint='" + endpoint + '\'' + + ", objectKeyPrefix='" + objectKeyPrefix + '\'' + + ", provider='" + provider + '\'' + + ", region='" + region + '\'' + + '}'; + } + + public String getBucket() { + return bucket; + } + + public StsCredentialsResponse setBucket(String bucket) { + this.bucket = bucket; + return this; + } + + public CredentialsToken getCredentials() { + return credentials; + } + + public StsCredentialsResponse setCredentials(CredentialsToken credentials) { + this.credentials = credentials; + return this; + } + + public String getEndpoint() { + return endpoint; + } + + public StsCredentialsResponse setEndpoint(String endpoint) { + this.endpoint = endpoint; + return this; + } + + public String getObjectKeyPrefix() { + return objectKeyPrefix; + } + + public StsCredentialsResponse setObjectKeyPrefix(String objectKeyPrefix) { + this.objectKeyPrefix = objectKeyPrefix; + return this; + } + + public OssTypeEnum getProvider() { + return provider; + } + + public StsCredentialsResponse setProvider(OssTypeEnum provider) { + this.provider = provider; + return this; + } + + public String getRegion() { + return region; + } + + public StsCredentialsResponse setRegion(String region) { + this.region = region; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/api/IHttpStorageService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/api/IHttpStorageService.java new file mode 100644 index 0000000..5005131 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/storage/api/IHttpStorageService.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.storage.api; + +import org.dromara.common.sdk.cloudapi.storage.StsCredentialsResponse; +import org.dromara.common.sdk.common.HttpResultResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; + + +/** + * @author sean + * @version 0.3 + * @date 2021/12/29 + */ +public interface IHttpStorageService { + + String PREFIX = "storage/api/v1"; + + /** + * Get temporary credentials for uploading the media and wayline in DJI Pilot. + * @param workspaceId workspace id + * @param req + * @param rsp + * @return + */ + @Operation(summary = "Get STS Token", description = "Get temporary credentials for uploading the media and wayline in DJI Pilot.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/sts") + HttpResultResponse getTemporaryCredential( + @PathVariable(name = "workspace_id") String workspaceId, + HttpServletRequest req, HttpServletResponse rsp); + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/DeviceIconUrl.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/DeviceIconUrl.java new file mode 100644 index 0000000..0fb48f0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/DeviceIconUrl.java @@ -0,0 +1,56 @@ +package org.dromara.common.sdk.cloudapi.tsa; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.3 + * @date 2022/1/5 + */ +@Schema(description = "device icon url.
You can use icons from the web, and the App internally downloads and caches these icons and" + + " loads them at a fixed size (28dp) to display on the map. Example: http://r56978dr7.hn-bkt.clouddn.com/tsa_equipment_normal.png", + anyOf = IconUrlEnum.class) +public class DeviceIconUrl { + + @JsonProperty("normal_icon_url") + @NotNull + @Schema(description = "icon displayed in normal state", example = "resource://pilot/drawable/tsa_car_normal") + private String normalIconUrl; + + @JsonProperty("selected_icon_url") + @NotNull + @Schema(description = "icon displayed in selected state", example = "resource://pilot/drawable/tsa_car_select") + private String selectIconUrl; + + public DeviceIconUrl() { + } + + @Override + public String toString() { + return "DeviceIconUrl{" + + "normalIconUrl='" + normalIconUrl + '\'' + + ", selectIconUrl='" + selectIconUrl + '\'' + + '}'; + } + + public String getNormalIconUrl() { + return normalIconUrl; + } + + public DeviceIconUrl setNormalIconUrl(String normalIconUrl) { + this.normalIconUrl = normalIconUrl; + return this; + } + + public String getSelectIconUrl() { + return selectIconUrl; + } + + public DeviceIconUrl setSelectIconUrl(String selectIconUrl) { + this.selectIconUrl = selectIconUrl; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/DeviceTopology.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/DeviceTopology.java new file mode 100644 index 0000000..0f760df --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/DeviceTopology.java @@ -0,0 +1,128 @@ +package org.dromara.common.sdk.cloudapi.tsa; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Schema(description = "device topology data") +public class DeviceTopology { + + @NotNull + @Schema(description = "device sn", example = "1AEC32CK4AD23R") + private String sn; + + @NotNull + @JsonProperty("device_callsign") + @Schema(description = "device nickname", example = "my M350") + private String deviceCallsign; + + @NotNull + @JsonProperty("device_model") + @Valid + private TopologyDeviceModel deviceModel; + + @NotNull + @Schema(description = "online status") + @JsonProperty("online_status") + private Boolean onlineStatus; + + @Schema(description = "the id of the person using the device", format = "uuid") + @JsonProperty("user_id") + private String userId; + + @NotNull + @Schema(description = "the nickname of the person using the device", example = "admin") + @JsonProperty("user_callsign") + private String userCallsign; + + @NotNull + @JsonProperty("icon_urls") + @Valid + private DeviceIconUrl iconUrls; + + public DeviceTopology() { + } + + @Override + public String toString() { + return "DeviceTopology{" + + "sn='" + sn + '\'' + + ", deviceCallsign='" + deviceCallsign + '\'' + + ", deviceModel=" + deviceModel + + ", onlineStatus=" + onlineStatus + + ", userId='" + userId + '\'' + + ", userCallsign='" + userCallsign + '\'' + + ", iconUrls=" + iconUrls + + '}'; + } + + public String getSn() { + return sn; + } + + public DeviceTopology setSn(String sn) { + this.sn = sn; + return this; + } + + public String getDeviceCallsign() { + return deviceCallsign; + } + + public DeviceTopology setDeviceCallsign(String deviceCallsign) { + this.deviceCallsign = deviceCallsign; + return this; + } + + public TopologyDeviceModel getDeviceModel() { + return deviceModel; + } + + public DeviceTopology setDeviceModel(TopologyDeviceModel deviceModel) { + this.deviceModel = deviceModel; + return this; + } + + public Boolean getOnlineStatus() { + return onlineStatus; + } + + public DeviceTopology setOnlineStatus(Boolean onlineStatus) { + this.onlineStatus = onlineStatus; + return this; + } + + public String getUserId() { + return userId; + } + + public DeviceTopology setUserId(String userId) { + this.userId = userId; + return this; + } + + public String getUserCallsign() { + return userCallsign; + } + + public DeviceTopology setUserCallsign(String userCallsign) { + this.userCallsign = userCallsign; + return this; + } + + public DeviceIconUrl getIconUrls() { + return iconUrls; + } + + public DeviceTopology setIconUrls(DeviceIconUrl iconUrls) { + this.iconUrls = iconUrls; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/IconUrlEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/IconUrlEnum.java new file mode 100644 index 0000000..8fb9a2a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/IconUrlEnum.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.cloudapi.tsa; + +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * The system icon that comes with the pilot. + * @author sean + * @version 0.3 + * @date 2022/1/5 + */ +@Schema(enumAsRef = true) +public enum IconUrlEnum { + + SELECT_CAR("resource://pilot/drawable/tsa_car_select"), + + NORMAL_CAR("resource://pilot/drawable/tsa_car_normal"), + + SELECT_PERSON("resource://pilot/drawable/tsa_person_select"), + + NORMAL_PERSON("resource://pilot/drawable/tsa_person_normal"), + + SELECT_EQUIPMENT("resource://pilot/drawable/tsa_equipment_select"), + + NORMAL_EQUIPMENT("resource://pilot/drawable/tsa_equipment_normal"); + + private final String url; + + IconUrlEnum(String url) { + this.url = url; + } + + @JsonValue + public String getUrl() { + return url; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/TopologyDeviceModel.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/TopologyDeviceModel.java new file mode 100644 index 0000000..cd40188 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/TopologyDeviceModel.java @@ -0,0 +1,82 @@ +package org.dromara.common.sdk.cloudapi.tsa; + +import org.dromara.common.sdk.cloudapi.device.DeviceDomainEnum; +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; +import org.dromara.common.sdk.cloudapi.device.DeviceSubTypeEnum; +import org.dromara.common.sdk.cloudapi.device.DeviceTypeEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Schema(description = "topology device model") +public class TopologyDeviceModel { + + @NotNull + @JsonProperty("device_model_key") + private DeviceEnum deviceModelKey; + + @NotNull + private DeviceDomainEnum domain; + + @NotNull + private DeviceTypeEnum type; + + @NotNull + @JsonProperty("sub_type") + private DeviceSubTypeEnum subType; + + public TopologyDeviceModel() { + } + + @Override + public String toString() { + return "TopologyDeviceModel{" + + "deviceModelKey=" + deviceModelKey + + ", domain=" + domain + + ", type=" + type + + ", subType=" + subType + + '}'; + } + + public DeviceEnum getDeviceModelKey() { + return deviceModelKey; + } + + public TopologyDeviceModel setDeviceModelKey(DeviceEnum deviceModelKey) { + this.deviceModelKey = deviceModelKey; + return this; + } + + public DeviceDomainEnum getDomain() { + return domain; + } + + public TopologyDeviceModel setDomain(DeviceDomainEnum domain) { + this.domain = domain; + return this; + } + + public DeviceTypeEnum getType() { + return type; + } + + public TopologyDeviceModel setType(DeviceTypeEnum type) { + this.type = type; + return this; + } + + public DeviceSubTypeEnum getSubType() { + return subType; + } + + public TopologyDeviceModel setSubType(DeviceSubTypeEnum subType) { + this.subType = subType; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/TopologyList.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/TopologyList.java new file mode 100644 index 0000000..c704576 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/TopologyList.java @@ -0,0 +1,53 @@ +package org.dromara.common.sdk.cloudapi.tsa; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Schema(description = "device topology list") +public class TopologyList { + + @Schema(description = "drone device topology collection") + @NotNull + private List<@Valid DeviceTopology> hosts; + + @Schema(description = "gateway device topology collection") + @NotNull + private List<@Valid DeviceTopology> parents; + + public TopologyList() { + } + + @Override + public String toString() { + return "TopologyList{" + + "hosts=" + hosts + + ", parents=" + parents + + '}'; + } + + public List getHosts() { + return hosts; + } + + public TopologyList setHosts(List hosts) { + this.hosts = hosts; + return this; + } + + public List getParents() { + return parents; + } + + public TopologyList setParents(List parents) { + this.parents = parents; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/TopologyResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/TopologyResponse.java new file mode 100644 index 0000000..254c469 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/TopologyResponse.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.tsa; + +import org.dromara.common.sdk.common.BaseModel; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/16 + */ +@Schema(description = "topology response data") +public class TopologyResponse extends BaseModel { + + @NotNull + private List<@Valid TopologyList> list; + + public TopologyResponse() { + } + + @Override + public String toString() { + return "TopologyResponse{" + + "list=" + list + + '}'; + } + + public List getList() { + return list; + } + + public TopologyResponse setList(List list) { + this.list = list; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/api/IHttpTsaService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/api/IHttpTsaService.java new file mode 100644 index 0000000..d54de4a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/tsa/api/IHttpTsaService.java @@ -0,0 +1,43 @@ +package org.dromara.common.sdk.cloudapi.tsa.api; + +import org.dromara.common.sdk.cloudapi.tsa.TopologyResponse; +import org.dromara.common.sdk.common.HttpResultResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Tag(name = "tsa interface") +public interface IHttpTsaService { + + String PREFIX = "manage/api/v1"; + + /** + * Get the topology list of all devices in the current user workspace for pilot display. + * @param workspaceId + * @param req + * @param rsp + * @return + */ + @Operation(summary = "obtain device topology list", description = "Get the topology list of all devices in the current user workspace for pilot display." + + "In the first connection, DJI Pilot 2 will call this interface to obtain the list topology of all devices." + + "Also, when Pilot receives a websocket command to notify the device of online, offline, and update, " + + "it will also call this interface to request the device topology list to be updated.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + }) + @GetMapping(PREFIX + "/workspaces/{workspace_id}/devices/topologies") + HttpResultResponse obtainDeviceTopologyList( + @PathVariable(name = "workspace_id") String workspaceId, + HttpServletRequest req, HttpServletResponse rsp); + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ActionTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ActionTypeEnum.java new file mode 100644 index 0000000..7f0c268 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ActionTypeEnum.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/23 + */ +public enum ActionTypeEnum { + + SPOT_CHECK(1), + + ; + + private final int type; + + ActionTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static ActionTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(ActionTypeEnum.class, type)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/BreakpointStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/BreakpointStateEnum.java new file mode 100644 index 0000000..e43919b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/BreakpointStateEnum.java @@ -0,0 +1,43 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum BreakpointStateEnum { + + WAYLINE_SEGMENT(0, "On the wayline segment"), + + WAYPOINT(1, "On the waypoint"); + + private final int state; + + private final String msg; + + BreakpointStateEnum(int state, String msg) { + this.state = state; + this.msg = msg; + } + + @JsonValue + public int getState() { + return state; + } + + public String getMsg() { + return msg; + } + + @JsonCreator + public static BreakpointStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(BreakpointStateEnum.class, state)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/DeviceExitHomingNotify.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/DeviceExitHomingNotify.java new file mode 100644 index 0000000..1548329 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/DeviceExitHomingNotify.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class DeviceExitHomingNotify { + + private ExitingRTHActionEnum action; + + private String sn; + + private ExitingRTHReasonEnum reason; + + public DeviceExitHomingNotify() { + } + + @Override + public String toString() { + return "DeviceExitHomingNotify{" + + "action=" + action + + ", sn='" + sn + '\'' + + ", reason=" + reason + + '}'; + } + + public ExitingRTHActionEnum getAction() { + return action; + } + + public DeviceExitHomingNotify setAction(ExitingRTHActionEnum action) { + this.action = action; + return this; + } + + public String getSn() { + return sn; + } + + public DeviceExitHomingNotify setSn(String sn) { + this.sn = sn; + return this; + } + + public ExitingRTHReasonEnum getReason() { + return reason; + } + + public DeviceExitHomingNotify setReason(ExitingRTHReasonEnum reason) { + this.reason = reason; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExecutableConditions.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExecutableConditions.java new file mode 100644 index 0000000..334f96e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExecutableConditions.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.wayline; + + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class ExecutableConditions { + + /** + * Storage capacity + * The minimum storage capacity of DJI dock or aircraft that can execute a task. Unit: MB. + * If the storage capacity doesn't satisfy the `storage_capacity`, task execution will fail. + */ + @NotNull + @Min(0) + private Integer storageCapacity; + + public ExecutableConditions() {} + + @Override + public String toString() { + return "ExecutableConditions{" + + "storageCapacity=" + storageCapacity + + '}'; + } + + public Integer getStorageCapacity() { + return storageCapacity; + } + + public ExecutableConditions setStorageCapacity(Integer storageCapacity) { + this.storageCapacity = storageCapacity; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExecutionStepEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExecutionStepEnum.java new file mode 100644 index 0000000..ba476f7 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExecutionStepEnum.java @@ -0,0 +1,131 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum ExecutionStepEnum { + + INITIAL(0, "Initial state"), + + PRE_CHECK(1, "Pre-launch check: Is the spacecraft executing the route?"), + + CHECK_WORK_MODE(2, "Pre-launch check: Is the airport exiting work mode?"), + + CHECK_EXECUTION(3, "Pre-launch check: Route execution in progress"), + + CHECK_RETURN(4, "Pre-launch check: Return in progress"), + + PREPARATION(5, "Route execution entering preparation state, waiting for task issuance to begin"), + + OPERATIONAL(6, "Airport entering operational state"), + + OPEN_COVER_PREPARATION(7, "Entering startup check preparation and hatch opening preparation"), + + WAITING_FOR_FLIGHT_SYSTEM_READINESS(8, "Waiting for flight system readiness, push connection establishment"), + + WAITING_FOR_RTK(9, "Waiting for RTK source monitoring with reported values"), + + CHECK_RTK_SOURCE(10, "Check if RTK source is from the airport; if not, reset"), + + WAITING_FOR_FLIGHT_CONTROL(11, "Waiting for flight control notification"), + + WRESTING_FLIGHT_CONTROL(12, "Airport has no control; wresting control from the aircraft"), + + GET_KMZ(13, "Get the latest KMZ URL"), + + DOWNLOAD_KMZ(14, "Download KMZ"), + + KMZ_UPLOADING(15, "KMZ uploading"), + + DYE_CONFIGURATION(16, "Dye configuration"), + + SET_DRONE_PARAMETER(17, "Aircraft takeoff parameter settings, alternate landing point settings, takeoff altitude settings, dye settings"), + + SET_TAKEOFF_PARAMETER(18, "Aircraft 'flyto' takeoff parameter settings"), + + SET_HOME_POINT(19, "Home point settings"), + + WAYLINE_EXECUTION(20, "Trigger route execution"), + + IN_PROGRESS(21, "Route execution in progress"), + + RETURN_CHECK_PREPARATION(22, "Entering return check preparation"), + + LADING(23, "Aircraft landing at the airport"), + + CLOSE_COVER(24, "Hatch closure after landing"), + + EXIT_WORK_MODE(25, "Airport exiting work mode"), + + DRONE_ABNORMAL_RECOVERY(26, "Airport abnormal recovery"), + + UPLOADING_FLIGHT_SYSTEM_LOGS(27, "Airport uploading flight system logs"), + + CHECK_RECORDING_STATUS(28, "Camera recording status check"), + + GET_MEDIA_FILES(29, "Get the number of media files"), + + DOCK_ABNORMAL_RECOVERY(30, "Abnormal recovery of airport takeoff hatch opening"), + + NOTIFY_TASK_RESULTS(31, "Notify task results"), + + TASK_COMPLETED(32, "Task execution completed; whether to initiate log retrieval based on configuration file"), + + RETRIEVAL_DRONE_LOG_LIST(33, "Log list retrieval - Aircraft list"), + + RETRIEVAL_DOCK_LOG_LIST(34, "Log list retrieval - Airport list retrieval"), + + UPLOAD_LOG_LIST_RESULTS(35, "Log list retrieval - Upload log list results"), + + RETRIEVAL_DRONE_LOG(36, "Log retrieval - Retrieve aircraft logs"), + + RETRIEVAL_DOCK_LOG(37, "Log retrieval - Retrieve airport logs"), + + COMPRESS_DRONE_LOG(38, "Log retrieval - Compress aircraft logs"), + + COMPRESS_DOCK_LOG(39, "Log retrieval - Compress airport logs"), + + UPLOAD_DRONE_LOG(40, "Log retrieval - Upload aircraft logs"), + + UPLOAD_DOCK_LOG(41, "Log retrieval - Upload airport logs"), + + NOTIFY_LOG_RESULTS(42, "Log retrieval - Notify results"), + + WAITING_FOR_SERVICE_RESPONSE(65533, "Waiting for service response after completion"), + + NO_SPECIFIC_STATUS(65534, "No specific status"), + + UNKNOWN(65535, "UNKNOWN"); + + private final int step; + + private final String msg; + + ExecutionStepEnum(int step, String msg) { + this.step = step; + this.msg = msg; + } + + @JsonValue + public int getStep() { + return step; + } + + public String getMsg() { + return msg; + } + + @JsonCreator + public static ExecutionStepEnum find(int step) { + return Arrays.stream(values()).filter(stepEnum -> stepEnum.step == step).findAny() + .orElseThrow(() -> new CloudSDKException(ExecutionStepEnum.class, step)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExitingRTHActionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExitingRTHActionEnum.java new file mode 100644 index 0000000..38bc1d4 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExitingRTHActionEnum.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum ExitingRTHActionEnum { + + EXIT(0, "退出 退出RTH状态"), + + Enter(1, "进入 退出RTH状态"); + + private final int action; + + private final String msg; + + ExitingRTHActionEnum(int action, String msg) { + this.action = action; + this.msg = msg; + } + + @JsonValue + public int getAction() { + return action; + } + + public String getMsg() { + return msg; + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static ExitingRTHActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(ExitWaylineWhenRcLostEnum.class, action)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExitingRTHReasonEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExitingRTHReasonEnum.java new file mode 100644 index 0000000..78255df --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ExitingRTHReasonEnum.java @@ -0,0 +1,61 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum ExitingRTHReasonEnum { + + ADD_JOYSTICK_THROTTLE(0, "添加操纵手柄油门"), + + ADD_JOYSTICK_PITCH(1, "添加操纵杆俯仰"), + + INITIALIZATION_FAILED(2, "行为初始化失败"), + + SURROUNDED_BY_OBSTACLES(3, "被障碍物包围"), + + FLIGHT_RESTRICTION(4, "触发飞行限制"), + + OBSTACLE_IS_TOO_CLOSED(5, "障碍物太近"), + + NO_GPS(6, "无GPS信号"), + + GPS_AND_VIO_ARE_FALSE(7, "GPS和VIO位置的输出标志为flase"), + + ERROR_OF_GPS_AND_VIO(8, "GPS与VIO融合位置误差过大"), + + SHORT_DISTANCE_BACKTRACKING(9, "短距离回溯"), + + TRIGGER_RTH(10, "短距离触发RTH"); + + private final int reason; + + private final String msg; + + ExitingRTHReasonEnum(int reason, String msg) { + this.reason = reason; + this.msg = msg; + } + + @JsonValue + public int getReason() { + return reason; + } + + public String getMsg() { + return msg; + } + + @JsonCreator + public static ExitingRTHReasonEnum find(int reason) { + return Arrays.stream(values()).filter(reasonEnum -> reasonEnum.reason == reason).findAny() + .orElseThrow(() -> new CloudSDKException(ExitingRTHReasonEnum.class, reason)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskBreakPoint.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskBreakPoint.java new file mode 100644 index 0000000..31fef6d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskBreakPoint.java @@ -0,0 +1,89 @@ +package org.dromara.common.sdk.cloudapi.wayline; + + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskBreakPoint { + + /** + * Breakpoint index + */ + @NotNull + @Min(0) + private Integer index; + + /** + * Breakpoint state + */ + @NotNull + private BreakpointStateEnum state; + + /** + * Current wayline segment process + */ + @NotNull + @Min(0) + @Max(1) + private Float progress; + + /** + * Wayline ID + */ + @NotNull + private Integer waylineId; + + public FlighttaskBreakPoint() {} + + @Override + public String toString() { + return "FlighttaskBreakPoint{" + + "index=" + index + + ", state=" + state + + ", progress=" + progress + + ", waylineId=" + waylineId + + '}'; + } + + public Integer getIndex() { + return index; + } + + public FlighttaskBreakPoint setIndex(Integer index) { + this.index = index; + return this; + } + + public BreakpointStateEnum getState() { + return state; + } + + public FlighttaskBreakPoint setState(BreakpointStateEnum state) { + this.state = state; + return this; + } + + public Float getProgress() { + return progress; + } + + public FlighttaskBreakPoint setProgress(Float progress) { + this.progress = progress; + return this; + } + + public Integer getWaylineId() { + return waylineId; + } + + public FlighttaskBreakPoint setWaylineId(Integer waylineId) { + this.waylineId = waylineId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskBreakReasonEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskBreakReasonEnum.java new file mode 100644 index 0000000..d6acd16 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskBreakReasonEnum.java @@ -0,0 +1,201 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum FlighttaskBreakReasonEnum { + + NORMAL(0, "无异常"), + + NOT_ID(1, "任务ID不存在。路线任务尚未执行。"), + + UNCOMMON_ERROR(2, "异常错误,请联系技术支持。"), + + ERROR_LOADING_FILE(4, "请求启动/恢复路线任务时加载路线文件时出错,请尝试再次上传文件或联系技术支持。"), + + ERROR_BREAKPOINT_FILE(5, "请求断点信息时查询断点文件失败。请求恢复路线任务时,无法分析断点类型。"), + + INCORRECT_PARAMETER(6, "请求启动/结束路线任务时cmd参数不正确,请求中的协议命令不正确。请求恢复路线任务时,无法分析断点类型。"), + + PARSING_FILE_TIMEOUT(7, "请求启动/恢复路线任务时,解析WPMZ文件超时,请重试。"), + + ALREADY_STARTED(257, "路线已启动,无法重新启动。"), + + UNABLE_TO_INTERRUPT_WAYLINE(258, "在此状态下无法中断路线,只允许在执行状态下暂停路线。"), + + NOT_STARTED(259, "路线尚未开始,无法结束路线。"), + + FLIGHT_MISSION_CONFLICT(261, "飞行任务冲突,无法获得对飞机的控制,在降落和返回期间不允许启动路线。"), + + UNABLE_TO_RESUME_WAYLINE(262, "无法在此状态下恢复路线,只有当路线暂停时才允许。"), + + MAXIMUM_ALTITUDE_LIMIT(513, "飞机超过了最高高度限制。"), + + MAXIMUM_DISTANCE_LIMIT(514, "飞机超过了最大距离限制。"), + + TOO_LOW_HEIGHT(516, "无人机的高度太低。"), + + OBSTACLE_AVOIDANCE(517, "飞机触发障碍物感应。"), + + POOR_RTK(518, "RTK信号差"), + + BOUNDARY_OF_RESTRICTED_ZONE(519, "接近禁区边界。"), + + GEO_ALTITUDE_LIMIT(521, "超过了码头的GEO区域高度限制。"), + + TAKEOFF_REQUEST_FAILED(522, "请求航线起飞失败。"), + + TAKEOFF_EXECUTION_FAILED(523, "起飞任务执行失败。"), + + WAYLINE_MISSION_REQUEST_FAILED(524, "请求路线任务失败。"), + + RTK_FIXING_REQUEST_FAILED(526, "未能请求路线RTK修复任务。"), + + RTK_FIXING_EXECUTION_FAILED(527, "线路RTK修复任务未能运行。"), + + WEAK_GPS(769, "GPS信号微弱。"), + + ERROR_RC_MODE(770, "遥控器未处于N模式,无法启动任务。"), + + HOME_POINT_NOT_REFRESHED(771, "原点未刷新。"), + + LOW_BATTERY(772, "由于电池电量不足,无法启动任务。"), + + LOW_BATTERY_RTH(773, "线路因电池电量不足而中断,导致返回家中。"), + + RC_DISCONNECTION(775, "遥控器和飞机之间的断开连接。"), + + ON_THE_GROUND(778, "飞机在地面上螺旋桨旋转,不允许启动航线。"), + + ABNORMAL_VISUAL_STATUS(779, "实时地形跟随过程中的异常视觉状态(例如,太亮、太暗、两侧亮度不一致)。"), + + INVALID_ALTITUDE(780, "用户设置的实时地形跟随高度无效(大于200米或小于30米)。"), + + CALCULATION_ERROR(781, "实时地形跟踪过程中的全局地图计算错误。"), + + STRONG_WINDS_RTH(784, "由于强风导致线路中断,导致返回机场。"), + + USER_EXIT(1281, "用户退出。"), + + USER_INTERRUPTION(1282, "用户中断。"), + + USER_TRIGGERED_RTH(1283, "用户触发返回机场"), + + INCORRECT_START_INFORMATION(1539, "起始信息不正确(航路点索引或进度)。"), + + UNSUPPORTED_COORDINATE_SYSTEM(1540, "使用不受支持的坐标系。"), + + UNSUPPORTED_ALTITUDE_MODE(1541, "使用不受支持的海拔模式。"), + + UNSUPPORTED_TRANSITIONAL_WAYLINE_MODE(1542, "使用不受支持的过渡路线模式。"), + + UNSUPPORTED_YAW_MODE(1543, "使用不受支持的偏航模式。"), + + UNSUPPORTED_YAW_DIRECTION_REVERSAL_MODE(1544, "使用不受支持的偏航方向反转模式。"), + + UNSUPPORTED_WAYPOINT_TYPE(1545, "使用不支持的航路点类型。"), + + INVALID_COORDINATED_TURNING_TYPE(1546, "协调转弯类型不能用于起点和终点。"), + + INVALID_GLOBAL_SPEED(1547, "路线全球速度超过合理范围。"), + + WAYPOINT_NUMBER_ABNORMAL(1548, "航路点编号异常。"), + + INVALID_LATITUDE_AND_LONGITUDE(1549, "经纬度数据异常。"), + + ABNORMAL_TURNING_INTERCEPT(1550, "转弯截距异常。"), + + INVALID_SEGMENT_MAXIMUM_SPEED(1551, "路线线段的最大速度超过合理范围。"), + + INVALID_TARGET_SPEED(1552, "线路段目标速度超过合理范围。"), + + INVALID_YAW_ANGLE(1553, "航点偏航角超出合理范围。"), + + BREAKPOINT_INVALID_MISSION_ID(1555, "从断点恢复的输入mission_id错误。"), + + BREAKPOINT_INVALID_PROGRESS_INFORMATION(1556, "从断点输入错误恢复的进度信息。"), + + BREAKPOINT_ERROR_MISSION_STATE(1557, "从断点恢复的任务状态异常。"), + + BREAKPOINT_INVALID_INDEX_INFORMATION(1558, "断点恢复的Wapoint索引信息输入错误。"), + + BREAKPOINT_INCORRECT_LATITUDE_AND_LONGITUDE(1559, "用于从断点恢复的纬度和经度信息不正确。"), + + BREAKPOINT_INVALID_YAW(1560, "从断点恢复期间,航路点的偏航输入错误。"), + + BREAKPOINT_INCORRECT_FLAG_SETTING(1561, "从断点恢复的标志设置不正确。"), + + WAYLINE_GENERATION_FAILED(1563, "路线生成失败。"), + + WAYLINE_EXECUTION_FAILED(1564, "路线执行失败。"), + + WAYLINE_OBSTACLE_SENSING(1565, "线路障碍物感应导致紧急停止。"), + + UNRECOGNIZED_ACTION_TYPE(1588, "无法识别的操作类型。"), + + DUPLICATE_ACTION_ID(1595, "同一操作组的操作ID不能相同。"), + + ACTION_ID_NOT_65535(1598, "操作ID值不能为65535。"), + + INVALID_NUMBER_OF_ACTION_GROUPS(1602, "操作组的数量超出了合理范围。"), + + ERROR_EFFECTIVE_RANGE(1603, "操作组有效范围错误。"), + + BREAKPOINT_INVALID_ACTION_INDEX(1606, "从断点恢复期间,操作索引超出了合理范围。"), + + BREAKPOINT_TRIGGER_RUNNING_ABNORMAL(1608, "断点信息触发运行结果异常。"), + + BREAKPOINT_DUPLICATE_ACTION_GROUP_ID(1609, "在从断点恢复的过程中,操作组ID信息不能重复。"), + + BREAKPOINT_DUPLICATE_ACTION_GROUP_POSITION(1610, "从断点恢复期间,不能重复操作组位置。"), + + BREAKPOINT_INVALID_ACTION_GROUP_POSITION(1611, "在从断点恢复的过程中,操作组位置超出了合理范围。"), + + BREAKPOINT_INVALID_ACTION_ID(1612, "在恢复过程中,操作ID不在断点信息中。"), + + BREAKPOINT_UNABLE_TO_INTERRUPT(1613, "无法将操作状态修改为在恢复过程中中断。"), + + INCORRECT_BREAKPOINT_INFORMATION(1614, "由于断点信息不正确,恢复失败。"), + + BREAKPOINT_UNRECOGNIZED_ACTION_TYPE(1634, "无法识别的操作类型。"), + + BREAKPOINT_UNRECOGNIZED_TRIGGER_TYPE(1649, "无法识别的触发器类型。"), + + UNKNOWN_ERROR_1(65534, "未知错误。"), + + UNKNOWN_ERROR_2(65535, "未知错误。"), + + ; + + private final int reason; + + private final String msg; + + FlighttaskBreakReasonEnum(int reason, String msg) { + this.reason = reason; + this.msg = msg; + } + + @JsonValue + public int getReason() { + return reason; + } + + public String getMsg() { + return msg; + } + + @JsonCreator + public static FlighttaskBreakReasonEnum find(int reason) { + return Arrays.stream(values()).filter(reasonEnum -> reasonEnum.reason == reason).findAny() + .orElseThrow(() -> new CloudSDKException(FlighttaskBreakReasonEnum.class, reason)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskCreateFile.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskCreateFile.java new file mode 100644 index 0000000..176bde6 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskCreateFile.java @@ -0,0 +1,52 @@ +package org.dromara.common.sdk.cloudapi.wayline; + + +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskCreateFile { + + /** + * File URL + */ + @NotNull + private String url; + + /** + * MD5 signature + */ + @NotNull + private String sign; + + public FlighttaskCreateFile() {} + + @Override + public String toString() { + return "FlighttaskCreateFile{" + + "url='" + url + '\'' + + ", sign='" + sign + '\'' + + '}'; + } + + public String getUrl() { + return url; + } + + public FlighttaskCreateFile setUrl(String url) { + this.url = url; + return this; + } + + public String getSign() { + return sign; + } + + public FlighttaskCreateFile setSign(String sign) { + this.sign = sign; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskCreateRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskCreateRequest.java new file mode 100644 index 0000000..9c208e8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskCreateRequest.java @@ -0,0 +1,73 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class FlighttaskCreateRequest extends BaseModel { + + /** + * Task ID + */ + @NotNull + private String flightId; + + /** + * Task type + */ + @NotNull + @Pattern(regexp = "^wayline$") + private String type = "wayline"; + + /** + * Wayline flighttaskFile object + */ + @NotNull + @Valid + private FlighttaskCreateFile file; + + public FlighttaskCreateRequest() {} + + @Override + public String toString() { + return "FlighttaskCreateRequest{" + + "flightId='" + flightId + '\'' + + ", type='" + type + '\'' + + ", file=" + file + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public FlighttaskCreateRequest setFlightId(String flightId) { + this.flightId = flightId; + return this; + } + + public String getType() { + return type; + } + + public FlighttaskCreateRequest setType(String type) { + this.type = type; + return this; + } + + public FlighttaskCreateFile getFile() { + return file; + } + + public FlighttaskCreateRequest setFile(FlighttaskCreateFile file) { + this.file = file; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskExecuteRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskExecuteRequest.java new file mode 100644 index 0000000..c82d11b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskExecuteRequest.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.common.BaseModel; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +public class FlighttaskExecuteRequest extends BaseModel { + + @NotNull + @Pattern(regexp = "^[^<>:\"/|?*._\\\\]+$") + private String flightId; + + public FlighttaskExecuteRequest() { + } + + @Override + public String toString() { + return "FlighttaskExecuteRequest{" + + "flightId='" + flightId + '\'' + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public FlighttaskExecuteRequest setFlightId(String flightId) { + this.flightId = flightId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskFile.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskFile.java new file mode 100644 index 0000000..d459dc7 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskFile.java @@ -0,0 +1,53 @@ +package org.dromara.common.sdk.cloudapi.wayline; + + +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskFile { + + /** + * File URL + */ + @NotNull + private String url; + + /** + * File signature + */ + @NotNull + private String fingerprint; + + public FlighttaskFile() { + } + + @Override + public String toString() { + return "FlighttaskFile{" + + "url='" + url + '\'' + + ", fingerprint='" + fingerprint + '\'' + + '}'; + } + + public String getUrl() { + return url; + } + + public FlighttaskFile setUrl(String url) { + this.url = url; + return this; + } + + public String getFingerprint() { + return fingerprint; + } + + public FlighttaskFile setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskPrepareRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskPrepareRequest.java new file mode 100644 index 0000000..ed91c8f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskPrepareRequest.java @@ -0,0 +1,260 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum; +import org.dromara.common.sdk.common.BaseModel; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskPrepareRequest extends BaseModel { + + /** + * Task ID + */ + @NotNull + @Pattern(regexp = "^[^<>:\"/|?*._\\\\]+$") + private String flightId; + + /** + * Time to execute + * Millisecond timestamp of task execution time. Optional field. + * When the `task_type` is 0 or 1, it is required. When the `task_type` is 2, it is not required. + */ + @Min(123456789012L) + private Long executeTime; + + /** + * Task type + * The execution time of immediate task and timed task are defined by `execute_time`. + * The conditional task supports the task readiness condition defined by `ready_conditions`. + * The task can be executed if conditions are satisfied within a specified period. + * Immediate task has the highest priority. Timed task and conditional task have the same priority. + */ + @NotNull + private TaskTypeEnum taskType; + + /** + * Wayline type + */ + @NotNull + private WaylineTypeEnum waylineType; + + /** + * Wayline file object + */ + @NotNull + @Valid + private FlighttaskFile file; + + /** + * Task readiness condition + */ + @Valid + private ReadyConditions readyConditions; + + /** + * Task executable condition + */ + @Valid + private ExecutableConditions executableConditions; + + /** + * Wayline breakpoint information + */ + @Valid + private FlighttaskBreakPoint breakPoint; + + /** + * Height for RTH + */ + @NotNull + @Min(20) + @Max(1500) + private Integer rthAltitude; + + /** + * Remote controller out of control action + * Out of control action: the current fixed transmitted value is 0, meaning Return-to-Home (RTH). + * Note that this enumeration value definition is inconsistent with the flight control and dock definitions, + * and a conversion exists at the dock end. + */ + @NotNull + private OutOfControlActionEnum outOfControlAction; + + /** + * wayline out of control action + * consistent with the KMZ file + */ + @NotNull + private ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost; + + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private RthModeEnum rthMode = RthModeEnum.PRESET_HEIGHT; + + @Valid + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private SimulateMission simulateMission; + + @NotNull + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_1, include = GatewayTypeEnum.DOCK2) + private WaylinePrecisionTypeEnum waylinePrecisionType; + + public FlighttaskPrepareRequest() {} + + @Override + public String toString() { + return "FlighttaskPrepareRequest{" + + "flightId='" + flightId + '\'' + + ", executeTime=" + executeTime + + ", taskType=" + taskType + + ", waylineType=" + waylineType + + ", file=" + file + + ", readyConditions=" + readyConditions + + ", executableConditions=" + executableConditions + + ", breakPoint=" + breakPoint + + ", rthAltitude=" + rthAltitude + + ", outOfControlAction=" + outOfControlAction + + ", exitWaylineWhenRcLost=" + exitWaylineWhenRcLost + + ", rthMode=" + rthMode + + ", simulateMission=" + simulateMission + + ", waylinePrecisionType=" + waylinePrecisionType + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public FlighttaskPrepareRequest setFlightId(String flightId) { + this.flightId = flightId; + return this; + } + + public Long getExecuteTime() { + return executeTime; + } + + public FlighttaskPrepareRequest setExecuteTime(Long executeTime) { + this.executeTime = executeTime; + return this; + } + + public TaskTypeEnum getTaskType() { + return taskType; + } + + public FlighttaskPrepareRequest setTaskType(TaskTypeEnum taskType) { + this.taskType = taskType; + return this; + } + + public WaylineTypeEnum getWaylineType() { + return waylineType; + } + + public FlighttaskPrepareRequest setWaylineType(WaylineTypeEnum waylineType) { + this.waylineType = waylineType; + return this; + } + + public FlighttaskFile getFile() { + return file; + } + + public FlighttaskPrepareRequest setFile(FlighttaskFile file) { + this.file = file; + return this; + } + + public ReadyConditions getReadyConditions() { + return readyConditions; + } + + public FlighttaskPrepareRequest setReadyConditions(ReadyConditions readyConditions) { + this.readyConditions = readyConditions; + return this; + } + + public ExecutableConditions getExecutableConditions() { + return executableConditions; + } + + public FlighttaskPrepareRequest setExecutableConditions(ExecutableConditions executableConditions) { + this.executableConditions = executableConditions; + return this; + } + + public FlighttaskBreakPoint getBreakPoint() { + return breakPoint; + } + + public FlighttaskPrepareRequest setBreakPoint(FlighttaskBreakPoint breakPoint) { + this.breakPoint = breakPoint; + return this; + } + + public Integer getRthAltitude() { + return rthAltitude; + } + + public FlighttaskPrepareRequest setRthAltitude(Integer rthAltitude) { + this.rthAltitude = rthAltitude; + return this; + } + + public OutOfControlActionEnum getOutOfControlAction() { + return outOfControlAction; + } + + public FlighttaskPrepareRequest setOutOfControlAction(OutOfControlActionEnum outOfControlAction) { + this.outOfControlAction = outOfControlAction; + return this; + } + + public ExitWaylineWhenRcLostEnum getExitWaylineWhenRcLost() { + return exitWaylineWhenRcLost; + } + + public FlighttaskPrepareRequest setExitWaylineWhenRcLost(ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost) { + this.exitWaylineWhenRcLost = exitWaylineWhenRcLost; + return this; + } + + public RthModeEnum getRthMode() { + return rthMode; + } + + public FlighttaskPrepareRequest setRthMode(RthModeEnum rthMode) { + this.rthMode = rthMode; + return this; + } + + public SimulateMission getSimulateMission() { + return simulateMission; + } + + public FlighttaskPrepareRequest setSimulateMission(SimulateMission simulateMission) { + this.simulateMission = simulateMission; + return this; + } + + public WaylinePrecisionTypeEnum getWaylinePrecisionType() { + return waylinePrecisionType; + } + + public FlighttaskPrepareRequest setWaylinePrecisionType(WaylinePrecisionTypeEnum waylinePrecisionType) { + this.waylinePrecisionType = waylinePrecisionType; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskProgress.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskProgress.java new file mode 100644 index 0000000..ab6bb0d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskProgress.java @@ -0,0 +1,54 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +public class FlighttaskProgress { + + private FlighttaskProgressExt ext; + + private FlighttaskProgressData progress; + + private FlighttaskStatusEnum status; + + public FlighttaskProgress() { + } + + @Override + public String toString() { + return "FlighttaskProgress{" + + "ext=" + ext + + ", progress=" + progress + + ", status=" + status + + '}'; + } + + public FlighttaskProgressExt getExt() { + return ext; + } + + public FlighttaskProgress setExt(FlighttaskProgressExt ext) { + this.ext = ext; + return this; + } + + public FlighttaskProgressData getProgress() { + return progress; + } + + public FlighttaskProgress setProgress(FlighttaskProgressData progress) { + this.progress = progress; + return this; + } + + public FlighttaskStatusEnum getStatus() { + return status; + } + + public FlighttaskProgress setStatus(FlighttaskStatusEnum status) { + this.status = status; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskProgressData.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskProgressData.java new file mode 100644 index 0000000..5e58f1b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskProgressData.java @@ -0,0 +1,48 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +public class FlighttaskProgressData { + + /** + * Execution step + */ + private ExecutionStepEnum currentStep; + + /** + * Progress value + */ + private Integer percent; + + public FlighttaskProgressData() { + } + + @Override + public String toString() { + return "FlighttaskProgressData{" + + "currentStep=" + currentStep + + ", percent=" + percent + + '}'; + } + + public ExecutionStepEnum getCurrentStep() { + return currentStep; + } + + public FlighttaskProgressData setCurrentStep(ExecutionStepEnum currentStep) { + this.currentStep = currentStep; + return this; + } + + public Integer getPercent() { + return percent; + } + + public FlighttaskProgressData setPercent(Integer percent) { + this.percent = percent; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskProgressExt.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskProgressExt.java new file mode 100644 index 0000000..8c19e63 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskProgressExt.java @@ -0,0 +1,116 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +public class FlighttaskProgressExt { + + private Integer currentWaypointIndex; + + private Integer mediaCount; + + private String flightId; + + private String trackId; + + private ProgressExtBreakPoint breakPoint; + + /** + * Wayline mission state + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private WaylineMissionStateEnum waylineMissionState; + + /** + * This includes the transitional phase of entering the flight path. + * For example, 0 indicates that the spacecraft is entering or already executing the first route. + */ + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + private Integer waylineId; + + public FlighttaskProgressExt() { + } + + @Override + public String toString() { + return "FlighttaskProgressExt{" + + "currentWaypointIndex=" + currentWaypointIndex + + ", mediaCount=" + mediaCount + + ", flightId='" + flightId + '\'' + + ", trackId='" + trackId + '\'' + + ", breakPoint=" + breakPoint + + ", waylineMissionState=" + waylineMissionState + + ", waylineId=" + waylineId + + '}'; + } + + public Integer getCurrentWaypointIndex() { + return currentWaypointIndex; + } + + public FlighttaskProgressExt setCurrentWaypointIndex(Integer currentWaypointIndex) { + this.currentWaypointIndex = currentWaypointIndex; + return this; + } + + public Integer getMediaCount() { + return mediaCount; + } + + public FlighttaskProgressExt setMediaCount(Integer mediaCount) { + this.mediaCount = mediaCount; + return this; + } + + public String getFlightId() { + return flightId; + } + + public FlighttaskProgressExt setFlightId(String flightId) { + this.flightId = flightId; + return this; + } + + public String getTrackId() { + return trackId; + } + + public FlighttaskProgressExt setTrackId(String trackId) { + this.trackId = trackId; + return this; + } + + public ProgressExtBreakPoint getBreakPoint() { + return breakPoint; + } + + public FlighttaskProgressExt setBreakPoint(ProgressExtBreakPoint breakPoint) { + this.breakPoint = breakPoint; + return this; + } + + public WaylineMissionStateEnum getWaylineMissionState() { + return waylineMissionState; + } + + public FlighttaskProgressExt setWaylineMissionState(WaylineMissionStateEnum waylineMissionState) { + this.waylineMissionState = waylineMissionState; + return this; + } + + public Integer getWaylineId() { + return waylineId; + } + + public FlighttaskProgressExt setWaylineId(Integer waylineId) { + this.waylineId = waylineId; + return this; + } +} + + diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskReady.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskReady.java new file mode 100644 index 0000000..1f1bead --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskReady.java @@ -0,0 +1,35 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskReady { + + /** + * The task ID set that currently satisfies the task readiness conditions + */ + private List flightIds; + + public FlighttaskReady() { + } + + @Override + public String toString() { + return "FlighttaskReady{" + + "flightIds=" + flightIds + + '}'; + } + + public List getFlightIds() { + return flightIds; + } + + public FlighttaskReady setFlightIds(List flightIds) { + this.flightIds = flightIds; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskResourceGetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskResourceGetRequest.java new file mode 100644 index 0000000..43c3d95 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskResourceGetRequest.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/25 + */ +public class FlighttaskResourceGetRequest { + + private String flightId; + + public FlighttaskResourceGetRequest() { + } + + @Override + public String toString() { + return "FlighttaskResourceGetRequest{" + + "flightId='" + flightId + '\'' + + '}'; + } + + public String getFlightId() { + return flightId; + } + + public FlighttaskResourceGetRequest setFlightId(String flightId) { + this.flightId = flightId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskResourceGetResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskResourceGetResponse.java new file mode 100644 index 0000000..9c7026b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskResourceGetResponse.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.common.BaseModel; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class FlighttaskResourceGetResponse extends BaseModel { + + /** + * Wayline file object + */ + @NotNull + @Valid + private FlighttaskFile file; + + public FlighttaskResourceGetResponse() {} + + @Override + public String toString() { + return "FlighttaskResourceGetResponse{" + + "file=" + file + + '}'; + } + + public FlighttaskFile getFile() { + return file; + } + + public FlighttaskResourceGetResponse setFile(FlighttaskFile file) { + this.file = file; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskStatusEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskStatusEnum.java new file mode 100644 index 0000000..08e0f03 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskStatusEnum.java @@ -0,0 +1,59 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/17 + */ +public enum FlighttaskStatusEnum { + + SENT("sent", false), + + IN_PROGRESS("in_progress", false), + + OK("ok", true), + + PAUSED("paused", false), + + REJECTED("rejected", true), + + FAILED("failed", true), + + CANCELED("canceled", true), + + TIMEOUT("timeout", true), + + PARTIALLY_DONE("partially_done", true); + + private final String status; + + private final boolean end; + + FlighttaskStatusEnum(String status, boolean end) { + this.status = status; + this.end = end; + } + + @JsonValue + public String getStatus() { + return status; + } + + public boolean isEnd() { + return end; + } + + @JsonCreator + public static FlighttaskStatusEnum find(String status) { + return Arrays.stream(values()).filter(statusEnum -> statusEnum.status.equals(status)).findAny() + .orElseThrow(() -> new CloudSDKException(FlighttaskStatusEnum.class, status)); + } +} + + diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskUndoRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskUndoRequest.java new file mode 100644 index 0000000..eb0bf25 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/FlighttaskUndoRequest.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.common.BaseModel; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/7 + */ +public class FlighttaskUndoRequest extends BaseModel { + + @NotNull + @Size(min = 1) + private List<@Pattern(regexp = "^[^<>:\"/|?*._\\\\]+$") String> flightIds; + + public FlighttaskUndoRequest() { + } + + @Override + public String toString() { + return "FlighttaskUndoRequest{" + + "flightIds=" + flightIds + + '}'; + } + + public List getFlightIds() { + return flightIds; + } + + public FlighttaskUndoRequest setFlightIds(List flightIds) { + this.flightIds = flightIds; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/GetWaylineListOrderBy.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/GetWaylineListOrderBy.java new file mode 100644 index 0000000..317d82d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/GetWaylineListOrderBy.java @@ -0,0 +1,50 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/25 + */ +public class GetWaylineListOrderBy { + + @NotNull + private OrderByColumnEnum column; + + private boolean desc; + + @JsonCreator + public GetWaylineListOrderBy(String orderBy) { + String[] arr = orderBy.split(" "); + this.column = OrderByColumnEnum.find(arr[0]); + this.desc = arr.length > 1 && arr[1].contains("desc"); + } + + @Override + @JsonValue + public String toString() { + return column.getColumn() + (desc ? " desc" : " asc"); + } + + public OrderByColumnEnum getColumn() { + return column; + } + + public GetWaylineListOrderBy setColumn(OrderByColumnEnum column) { + this.column = column; + return this; + } + + public boolean isDesc() { + return desc; + } + + public GetWaylineListOrderBy setDesc(boolean desc) { + this.desc = desc; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/GetWaylineListRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/GetWaylineListRequest.java new file mode 100644 index 0000000..4624ebd --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/GetWaylineListRequest.java @@ -0,0 +1,188 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/8 + */ +@Schema(description = "Query parameter to get list of wayline files") +public class GetWaylineListRequest { + + /** + * Is the wayline file favorited? + */ + @Parameter(name = "favorited", description = "Is the wayline file favorited?") + private Boolean favorited; + + /** + * order(xxx_column desc or xxx_column asc) + * Pilot2 optional value: nameupdate_timecreate_time + */ + @NotNull + @JsonProperty("order_by") + @Parameter(name = "order_by", description = "sort field name", example = "update_time desc", + schema = @Schema(allowableValues = {"name desc", "name asc", "update_time desc", "update_time asc", "create_time desc", "create_time asc"})) + @Valid + private GetWaylineListOrderBy orderBy; + + /** + * current page + */ + @Min(1) + @Parameter(name = "page", description = "current page", schema = @Schema(defaultValue = "1", type = "int")) + private int page = 1; + + /** + * page size + */ + @Min(1) + @JsonProperty("page_size") + @Parameter(name = "page_size", description = "page size", schema = @Schema(defaultValue = "10", type = "int")) + private int pageSize = 10; + + /** + * wayline template type collection + */ + @Size(min = 1) + @JsonProperty("template_type") + @Parameter(name = "template_type", description = "wayline template type collection", example = "[0]") + private List templateType; + + /** + * 1: Enable AI Spot-Check wayline. Without this field means all waylines. + */ + @JsonProperty("action_type") + @Parameter(name = "action_type", description = "wayline template type collection", example = "1") + private ActionTypeEnum actionType; + + /** + * Selected aircraft models + */ + @JsonProperty("drone_model_keys") + @Schema(name = "drone_model_keys", description = "drone device product enum", example = "[\"0-67-0\"]") + private List droneModelKeys; + + /** + * Selected payload models + */ + @JsonProperty("payload_model_key") + @Schema(name = "payload_model_key", description = "payload device product enum", example = "[\"1-53-0\"]") + private List payloadModelKey; + + /** + * Filter by wayline name + */ + @JsonProperty("key") + @Schema(name = "key", description = "wayline file name", example = "waypoint") + private String key; + + public GetWaylineListRequest() { + } + + @Override + public String toString() { + return "GetWaylineListRequest{" + + "favorited=" + favorited + + ", orderBy='" + orderBy + '\'' + + ", page=" + page + + ", pageSize=" + pageSize + + ", templateType=" + templateType + + ", actionType=" + actionType + + ", droneModelKeys=" + droneModelKeys + + ", payloadModelKey=" + payloadModelKey + + ", key='" + key + '\'' + + '}'; + } + + public Boolean getFavorited() { + return favorited; + } + + public GetWaylineListRequest setFavorited(Boolean favorited) { + this.favorited = favorited; + return this; + } + + public GetWaylineListOrderBy getOrderBy() { + return orderBy; + } + + public GetWaylineListRequest setOrderBy(GetWaylineListOrderBy orderBy) { + this.orderBy = orderBy; + return this; + } + + public int getPage() { + return page; + } + + public GetWaylineListRequest setPage(int page) { + this.page = page; + return this; + } + + public int getPageSize() { + return pageSize; + } + + public GetWaylineListRequest setPageSize(int pageSize) { + this.pageSize = pageSize; + return this; + } + + public List getTemplateType() { + return templateType; + } + + public GetWaylineListRequest setTemplateType(List templateType) { + this.templateType = templateType; + return this; + } + + public ActionTypeEnum getActionType() { + return actionType; + } + + public GetWaylineListRequest setActionType(ActionTypeEnum actionType) { + this.actionType = actionType; + return this; + } + + public List getDroneModelKeys() { + return droneModelKeys; + } + + public GetWaylineListRequest setDroneModelKeys(List droneModelKeys) { + this.droneModelKeys = droneModelKeys; + return this; + } + + public List getPayloadModelKey() { + return payloadModelKey; + } + + public GetWaylineListRequest setPayloadModelKey(List payloadModelKey) { + this.payloadModelKey = payloadModelKey; + return this; + } + + public String getKey() { + return key; + } + + public GetWaylineListRequest setKey(String key) { + this.key = key; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/GetWaylineListResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/GetWaylineListResponse.java new file mode 100644 index 0000000..da69f9e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/GetWaylineListResponse.java @@ -0,0 +1,237 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; +import org.dromara.common.sdk.common.BaseModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Schema(description = "The data of the wayline file.") +public class GetWaylineListResponse extends BaseModel { + + /** + * wayline file name + */ + @NotNull + @Schema(description = "wayline file name", example = "waylineFile") + @Pattern(regexp = "^[^<>:\"/|?*._\\\\]+$") + private String name; + + /** + * wayline file id + */ + @NotNull + @Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + @Schema(description = "wayline file id", format = "uuid") + private String id; + + /** + * drone device product enum + */ + @NotNull + @JsonProperty("drone_model_key") + @Schema(description = "drone device product enum", example = "0-67-0") + private DeviceEnum droneModelKey; + + private String sign; + + /** + * payload device product enum + */ + @NotNull + @Size(min = 1) + @JsonProperty("payload_model_keys") + @Schema(description = "payload device product enum", example = "[\"1-53-0\"]") + private List payloadModelKeys; + + /** + * Is the wayline file favorited? + */ + @NotNull + @Schema(description = "Is the wayline file favorited?") + private Boolean favorited; + + /** + * wayline template collection + */ + @NotNull + @Size(min = 1) + @Schema(description = "wayline template collection", example = "[0]") + @JsonProperty("template_types") + private List templateTypes; + + @NotNull + @Schema(description = "The key of the object in the bucket", example = "wayline/waylineFile.kmz") + @JsonProperty("object_key") + private String objectKey; + + /** + * uploader + */ + @NotNull + @JsonProperty("user_name") + @Schema(description = "uploader's username", example = "admin") + private String username; + + /** + * update time (millisecond) + */ + @NotNull + @Min(123456789012L) + @Schema(description = "update time (millisecond). The field named `update time` must exist in the table.", example = "123456789012") + @JsonProperty("update_time") + private Long updateTime; + + /** + * create time (millisecond) + */ + @NotNull + @Min(123456789012L) + @Schema(description = "create time (millisecond). The field named `create time` must exist in the table.", example = "123456789012") + @JsonProperty("create_time") + private Long createTime; + + @JsonProperty("action_type") + @Parameter(name = "action_type", description = "wayline template type collection", example = "1") + private ActionTypeEnum actionType; + + public GetWaylineListResponse() { + } + + @Override + public String toString() { + return "GetWaylineListResponse{" + + "name='" + name + '\'' + + ", id='" + id + '\'' + + ", droneModelKey=" + droneModelKey + + ", sign='" + sign + '\'' + + ", payloadModelKeys=" + payloadModelKeys + + ", favorited=" + favorited + + ", templateTypes=" + templateTypes + + ", objectKey='" + objectKey + '\'' + + ", username='" + username + '\'' + + ", updateTime=" + updateTime + + ", createTime=" + createTime + + ", actionType=" + actionType + + '}'; + } + + public String getName() { + return name; + } + + public GetWaylineListResponse setName(String name) { + this.name = name; + return this; + } + + public String getId() { + return id; + } + + public GetWaylineListResponse setId(String id) { + this.id = id; + return this; + } + + public DeviceEnum getDroneModelKey() { + return droneModelKey; + } + + public GetWaylineListResponse setDroneModelKey(DeviceEnum droneModelKey) { + this.droneModelKey = droneModelKey; + return this; + } + + public String getSign() { + return sign; + } + + public GetWaylineListResponse setSign(String sign) { + this.sign = sign; + return this; + } + + public List getPayloadModelKeys() { + return payloadModelKeys; + } + + public GetWaylineListResponse setPayloadModelKeys(List payloadModelKeys) { + this.payloadModelKeys = payloadModelKeys; + return this; + } + + public Boolean getFavorited() { + return favorited; + } + + public GetWaylineListResponse setFavorited(Boolean favorited) { + this.favorited = favorited; + return this; + } + + public List getTemplateTypes() { + return templateTypes; + } + + public GetWaylineListResponse setTemplateTypes(List templateTypes) { + this.templateTypes = templateTypes; + return this; + } + + public String getObjectKey() { + return objectKey; + } + + public GetWaylineListResponse setObjectKey(String objectKey) { + this.objectKey = objectKey; + return this; + } + + public String getUsername() { + return username; + } + + public GetWaylineListResponse setUsername(String username) { + this.username = username; + return this; + } + + public Long getUpdateTime() { + return updateTime; + } + + public GetWaylineListResponse setUpdateTime(Long updateTime) { + this.updateTime = updateTime; + return this; + } + + public Long getCreateTime() { + return createTime; + } + + public GetWaylineListResponse setCreateTime(Long createTime) { + this.createTime = createTime; + return this; + } + + public ActionTypeEnum getActionType() { + return actionType; + } + + public GetWaylineListResponse setActionType(ActionTypeEnum actionType) { + this.actionType = actionType; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/LastPointTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/LastPointTypeEnum.java new file mode 100644 index 0000000..2de1543 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/LastPointTypeEnum.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/11 + */ +public enum LastPointTypeEnum { + + OVER_THE_HOME_POINT(0), + + NOT_OVER_THE_HOME_POINT(1), + + ; + + private final int type; + + LastPointTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static LastPointTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(LastPointTypeEnum.class, type)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/OrderByColumnEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/OrderByColumnEnum.java new file mode 100644 index 0000000..d407b17 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/OrderByColumnEnum.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/25 + */ +public enum OrderByColumnEnum { + + NAME("name"), + + UPDATE_TIME("update_time"), + + CREATE_TIME("create_time"), + + ; + + private final String column; + + OrderByColumnEnum(String column) { + this.column = column; + } + + @JsonValue + public String getColumn() { + return column; + } + + @JsonCreator + public static OrderByColumnEnum find(String column) { + return Arrays.stream(values()).filter(columnEnum -> columnEnum.column.equals(column)).findAny() + .orElseThrow(() -> new CloudSDKException(OrderByColumnEnum.class, column)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/OutOfControlActionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/OutOfControlActionEnum.java new file mode 100644 index 0000000..55fe77f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/OutOfControlActionEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public enum OutOfControlActionEnum { + + RETURN_TO_HOME(0), + + HOVERING(1), + + LANDING(2); + + private final int action; + + OutOfControlActionEnum(int action) { + this.action = action; + } + + @JsonValue + public int getAction() { + return action; + } + + @JsonCreator + public static OutOfControlActionEnum find(int action) { + return Arrays.stream(values()).filter(actionEnum -> actionEnum.action == action).findAny() + .orElseThrow(() -> new CloudSDKException(OutOfControlActionEnum.class, action)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ProgressExtBreakPoint.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ProgressExtBreakPoint.java new file mode 100644 index 0000000..6ab8884 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ProgressExtBreakPoint.java @@ -0,0 +1,153 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/6 + */ +public class ProgressExtBreakPoint { + + /** + * Breakpoint index + */ + private Integer index; + + /** + * Breakpoint state + */ + private BreakpointStateEnum state; + + /** + * Current wayline segment process + */ + private Float progress; + + /** + * Wayline ID + */ + private Integer waylineId; + + /** + * Break reason + */ + private FlighttaskBreakReasonEnum breakReason; + + /** + * Breakpoint latitude + */ + private Float latitude; + + /** + * Breakpoint longitude + */ + private Float longitude; + + /** + * Breakpoint altitude relative to the Earth's ellipsoid surface + * + */ + private Float height; + + /** + * Yaw angle relative to true north (meridian), with positive values from 0 to 6 o'clock direction and negative values from 6 to 12 o'clock direction + */ + private Integer attitudeHead; + + public ProgressExtBreakPoint() {} + + @Override + public String toString() { + return "FlighttaskBreakPoint{" + + "index=" + index + + ", state=" + state + + ", progress=" + progress + + ", waylineId=" + waylineId + + ", breakReason=" + breakReason + + ", latitude=" + latitude + + ", longitude=" + longitude + + ", height=" + height + + ", attitudeHead=" + attitudeHead + + '}'; + } + + public Integer getIndex() { + return index; + } + + public ProgressExtBreakPoint setIndex(Integer index) { + this.index = index; + return this; + } + + public BreakpointStateEnum getState() { + return state; + } + + public ProgressExtBreakPoint setState(BreakpointStateEnum state) { + this.state = state; + return this; + } + + public Float getProgress() { + return progress; + } + + public ProgressExtBreakPoint setProgress(Float progress) { + this.progress = progress; + return this; + } + + public Integer getWaylineId() { + return waylineId; + } + + public ProgressExtBreakPoint setWaylineId(Integer waylineId) { + this.waylineId = waylineId; + return this; + } + + public FlighttaskBreakReasonEnum getBreakReason() { + return breakReason; + } + + public ProgressExtBreakPoint setBreakReason(FlighttaskBreakReasonEnum breakReason) { + this.breakReason = breakReason; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public ProgressExtBreakPoint setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public ProgressExtBreakPoint setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } + + public Float getHeight() { + return height; + } + + public ProgressExtBreakPoint setHeight(Float height) { + this.height = height; + return this; + } + + public Integer getAttitudeHead() { + return attitudeHead; + } + + public ProgressExtBreakPoint setAttitudeHead(Integer attitudeHead) { + this.attitudeHead = attitudeHead; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ReadyConditions.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ReadyConditions.java new file mode 100644 index 0000000..5932c5b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ReadyConditions.java @@ -0,0 +1,77 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.common.BaseModel; + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class ReadyConditions extends BaseModel { + + /** + * Battery capacity + * The aircraft battery percentage threshold of the executable task. + * The aircraft battery must be greater than the `battery_capacity` when the task starts. + */ + @NotNull + @Min(0) + @Max(100) + private Integer batteryCapacity; + + /** + * Start time of the task executable period + * Start millisecond timestamp of the task executable period. The task execution time should be later than the `begin_time`. + */ + @NotNull + private Long beginTime; + + /** + * End time of the task executable period + * End millisecond timestamp of the task executable period. The task execution time should be earlier than the `end_time`. + */ + @NotNull + private Long endTime; + + public ReadyConditions() {} + + @Override + public String toString() { + return "ReadyConditions{" + + "batteryCapacity=" + batteryCapacity + + ", beginTime=" + beginTime + + ", endTime=" + endTime + + '}'; + } + + public Integer getBatteryCapacity() { + return batteryCapacity; + } + + public ReadyConditions setBatteryCapacity(Integer batteryCapacity) { + this.batteryCapacity = batteryCapacity; + return this; + } + + public Long getBeginTime() { + return beginTime; + } + + public ReadyConditions setBeginTime(Long beginTime) { + this.beginTime = beginTime; + return this; + } + + public Long getEndTime() { + return endTime; + } + + public ReadyConditions setEndTime(Long endTime) { + this.endTime = endTime; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ReturnHomeInfo.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ReturnHomeInfo.java new file mode 100644 index 0000000..53ccc6a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/ReturnHomeInfo.java @@ -0,0 +1,74 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.cloudapi.control.Point; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/11 + */ +public class ReturnHomeInfo { + + /** + * The real-time planned return route for the aircraft. + * Each push is a complete update of the route. + * There is an complete return path in the array. + */ + private List plannedPathPoints; + + /** + * You can use this field to determine the display mode of the last point in the trajectory. + * 0 means the last point of the trajectory is located above the return point on the ground. + * The terminal can display a line connecting the last point of the trajectory to the return point. + * 1 means the last point of the trajectory is not the return point. + * The terminal should not display a line connecting the last point of the trajectory to the return point. + * The reason for not being able to reach the return point could be that the return point is in a restricted zones or inside an obstacle. + */ + private LastPointTypeEnum lastPointType; + + /** + * Currently working wayline mission ID + */ + private String flightId; + + public ReturnHomeInfo() { + } + + @Override + public String toString() { + return "ReturnHomeInfo{" + + "plannedPathPoints=" + plannedPathPoints + + ", lastPointType=" + lastPointType + + ", flightId='" + flightId + '\'' + + '}'; + } + + public List getPlannedPathPoints() { + return plannedPathPoints; + } + + public ReturnHomeInfo setPlannedPathPoints(List plannedPathPoints) { + this.plannedPathPoints = plannedPathPoints; + return this; + } + + public LastPointTypeEnum getLastPointType() { + return lastPointType; + } + + public ReturnHomeInfo setLastPointType(LastPointTypeEnum lastPointType) { + this.lastPointType = lastPointType; + return this; + } + + public String getFlightId() { + return flightId; + } + + public ReturnHomeInfo setFlightId(String flightId) { + this.flightId = flightId; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/RthModeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/RthModeEnum.java new file mode 100644 index 0000000..98d17d7 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/RthModeEnum.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/8/4 + */ +public enum RthModeEnum { + + OPTIMAL_HEIGHT(0), + + PRESET_HEIGHT(1); + + private final int rthMode; + + RthModeEnum(int rthMode) { + this.rthMode = rthMode; + } + + @JsonValue + public int getRthMode() { + return rthMode; + } + + @JsonCreator + public static RthModeEnum find(int rthMode) { + return Arrays.stream(values()).filter(rthModeEnum -> rthModeEnum.rthMode == rthMode).findAny() + .orElseThrow(() -> new CloudSDKException(RthModeEnum.class, rthMode)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/SimulateMission.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/SimulateMission.java new file mode 100644 index 0000000..866fbe2 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/SimulateMission.java @@ -0,0 +1,65 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.7 + * @date 2023/8/4 + */ +public class SimulateMission { + + @NotNull + private SimulateSwitchEnum isEnable; + + @NotNull + @Min(-90) + @Max(90) + private Float latitude; + + @NotNull + @Min(-180) + @Max(180) + private Float longitude; + + public SimulateMission() { + } + + @Override + public String toString() { + return "SimulateMission{" + + "isEnable=" + isEnable + + ", latitude=" + latitude + + ", longitude=" + longitude + + '}'; + } + + public SimulateSwitchEnum getIsEnable() { + return isEnable; + } + + public SimulateMission setIsEnable(SimulateSwitchEnum isEnable) { + this.isEnable = isEnable; + return this; + } + + public Float getLatitude() { + return latitude; + } + + public SimulateMission setLatitude(Float latitude) { + this.latitude = latitude; + return this; + } + + public Float getLongitude() { + return longitude; + } + + public SimulateMission setLongitude(Float longitude) { + this.longitude = longitude; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/SimulateSwitchEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/SimulateSwitchEnum.java new file mode 100644 index 0000000..631ceca --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/SimulateSwitchEnum.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/8/4 + */ +public enum SimulateSwitchEnum { + + DISABLE(0), + + ENABLE(1); + + private final int state; + + SimulateSwitchEnum(int state) { + this.state = state; + } + + @JsonValue + public int getState() { + return state; + } + + @JsonCreator + public static SimulateSwitchEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(SimulateSwitchEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/TaskTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/TaskTypeEnum.java new file mode 100644 index 0000000..59334dc --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/TaskTypeEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum TaskTypeEnum { + + IMMEDIATE(0), + + TIMED(1), + + CONDITIONAL(2); + + private final int type; + + TaskTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return this.type; + } + + @JsonCreator + public static TaskTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(TaskTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineErrorCodeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineErrorCodeEnum.java new file mode 100644 index 0000000..d83f701 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineErrorCodeEnum.java @@ -0,0 +1,322 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.common.IErrorInfo; +import org.dromara.common.sdk.mqtt.events.IEventsErrorCode; +import org.dromara.common.sdk.mqtt.services.IServicesErrorCode; +import com.fasterxml.jackson.annotation.JsonCreator; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum WaylineErrorCodeEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + SUCCESS(0, "success"), + + WRONG_PARAM(314001, "未能分发任务。稍后再试"), + + MD5_EMPTY(314002, "发出的路线任务md5为空。"), + + WRONG_WAYLINE_FILE(314003, "不支持路线文件格式。检查文件。"), + + DISTRIBUTE_TASK_FAILED_1(314004, "未能分发任务。"), + + MD5_CHECK_FAILED(314005, "路线MD5检查失败。"), + + INITIATE_AIRCRAFT_FAILED_1(314006, "未能启动飞机。重新启动dock,然后重试。"), + + TRANSFER_KMZ_FILE_FAILED(314007, "无法将路线文件从码头分发到飞机。"), + + PREPARATION_TIMED_OUT(314008, "飞机任务准备超时。重新启动dock,然后重试。"), + + INITIATE_AIRCRAFT_FAILED_2(314009, "未能启动飞机。重新启动dock,然后重试。"), + + PERFORM_TASK_FAILED(314010, "无法执行任务。"), + + QUERY_TIMEOUT(314011, "路线执行结果查询超时。"), + + PREPARATION_FAILED_1(314012, "飞机任务准备失败。无法执行任务。重新启动dock,然后重试。"), + + WRONG_KMZ_URL(314013, "获取KMZ下载地址失败。"), + + DOCK_SYSTEM_ERROR_1(314014, "Dock系统错误。无法执行任务。请稍后再试。"), + + CLOSE_FOURTH_GENERATION_FAILED(314015, "未能将AI抽查路线从码头分配到飞机。无法执行任务。请稍后再试,或者重新启动dock然后再试。"), + + PROCESS_KMZ_FILE_FAILED_1(314016, "无法处理飞行路线文件。无法执行任务。检查文件。"), + + MODIFY_KMZ_FILE_FAILED(314017, "修改AI抽查的KMZ文件失败。"), + + AIRCRAFT_RTK_ERROR(314018, "飞机RTK定位错误。无法执行任务。请稍后再试,或者重新启动dock然后再试。"), + + CONVERGE_RTK_FAILED_1(314019, "未能汇聚飞机RTK数据。无法执行任务。请稍后再试,或者重新启动dock然后再试。"), + + AIRCRAFT_POSITION_ERROR(314020, "飞机不在停机坪中间或飞机航向不正确。无法执行任务。检查飞机的位置和航向。"), + + AIRCRAFT_RTK_POSITIONING_ERROR(314021, "飞机RTK定位错误。无法执行任务。请稍后再试,或者重新启动dock然后再试。"), + + MODIFY_KMZ_BREAKPOINT_FILE_FAILED(314022, "修改断点恢复飞行的KMZ文件失败"), + + SETTING_BACKUP_LANDING_POINT_FAILED(316001, "备份着陆点设置失败"), + + SETTING_BACKUP_SAFE_HEIGHT_FAILED(316002, "传输的备份安全高度设置失败"), + + SETTING_TAKEOFF_HEIGHT_FAILED(316003, "起飞高度设置失败。注:飞机的默认安全起飞高度按码头设置为1.8米。飞机起飞后将飞到1.8米,在0-1.8米的起飞过程中不能中断,其他动作只能在起飞后进行。默认情况下,此高度由码头使用,不支持修改。其目的是防止人身伤害。"), + + SETTING_OUT_OF_CONTROL_ACTION_FAILED(316004, "失控操作设置失败。"), + + CONVERGE_RTK_FAILED_2(316005, "未能汇聚飞机RTK数据。无法执行任务。重新启动dock,然后重试。"), + + DOCK_PREPARATION_FAILED(316006, "飞机无法降落在码头上。坞盖关闭或驱动杆推入到位。在码头部署现场检查飞机状态。"), + + INITIATE_AIRCRAFT_FAILED(316007, "未能启动飞机。重新启动dock,然后重试。"), + + OBTAIN_FLIGHT_CONTROL_FAILED(316008, "Dock未能获得飞机飞行控制。无法执行任务。确保飞行控制未被遥控器锁定。"), + + LOW_POWER(316009, "飞机电池电量低。无法执行任务。等待飞机充电至50%,然后重试"), + + AIRCRAFT_NOT_DETECTED(316010, "未检测到飞机。无法执行任务。检查飞机是否在码头内并连接到码头,或者重新启动码头并重试。"), + + LANDED_ON_INCORRECT_LOCATION(316011, "飞机降落在错误的位置。检查飞机是否应手动放置在码头部署现场。"), + + FOLDER_COLORING_FAILED(316012, "飞机任务准备失败。文件夹着色失败。"), + + OBTAIN_BATTERY_POWER_FAILED(316013, "查询电池电量失败。"), + + FLIGHT_CONTROL_PUSHING_TIMED_OUT(316014, "飞行控制推送接收超时。"), + + AIRCRAFT_LOCATION_TOO_FAR(316015, "RTK设备校准的飞机位置远离码头。无法执行任务。重新启动dock,然后重试。"), + + LANDING_TIMEOUT(316016, "飞机在码头降落超时。飞机和码头可能会断开连接。查看直播视图,查看飞机是否降落在码头上"), + + OBTAIN_MEDIA_TIMEOUT(316017, "获取飞机媒体文件的数量超时。飞机和码头可能会断开连接。查看直播视图,查看飞机是否降落在码头上"), + + TASK_PERFORMANCE_TIMED_OUT(316018, "任务执行超时。飞机和码头可能会断开连接。查看直播视图,查看飞机是否降落在码头上"), + + CAMERA_COLORING_TIMED_OUT(316019, "相机着色超时"), + + RTK_SOURCE_ERROR(316020, "飞机RTK信号源错误。"), + + RTK_SOURCE_TIMEOUT(316021, "检查飞机RTK信号源超时。"), + + AIRCRAFT_NOT_CONNECTED(316022, "飞机无法回国。检查飞机是否已通电,飞机和码头是否已连接,然后重试"), + + NO_FLIGHT_CONTROL_1(316023, "飞机由管制员B控制,无法返航。从控制器B控制飞机或关闭遥控器电源,然后重试。"), + + WRONG_COMMAND(316024, "飞机未能返航。检查飞机是否已起飞,然后再试一次。"), + + SETTING_AIRCRAFT_PARAMETERS_FAILED(316025, "未能配置飞机参数。请稍后再试,或者重新启动dock然后再试。"), + + EMERGENCY_BUTTON_PRESSED_DOWN(316026, "码头紧急停止按钮按下。无法执行任务。松开按钮,然后重试。"), + + SETTING_AIRCRAFT_PARAMETERS_TIMEOUT(316027, "设置飞机参数超时。请稍后再试,或者重新启动dock然后再试。"), + + FLYING_TO_BACKUP_POINT_1(316029, "码头紧急停止按钮按下。飞往备用着陆点的飞机。确保飞机安全降落,并将飞机放置在码头内"), + + REFRESH_HOME_POINT_FAILED(316030, "刷新原点失败。请再试一次。"), + + SETTING_RTH_MODE_FAILED(316031, "设置返回模式失败。请重试。"), + + LOW_POWER_LANDING_OUTSIDE(316050, "由于电池电量不足,飞机已降落在码头外。请立即检查飞机是否安全降落,并将飞机送回码头。"), + + TASK_ABNORMAL_LANDING_OUTSIDE(316051, "航路任务异常,飞机降落在码头外,请立即检查飞机是否已安全降落,并将飞机送回码头。"), + + FLYING_TO_BACKUP_POINT_2(316052, "航路任务异常,飞机将飞往备用着陆点,请立即检查飞机是否已安全着陆,并将飞机送回码头。"), + + USER_CONTROL_LANDING(316053, "用户控制飞机着陆。"), + + OBTAIN_MEDIA_FAILED(317001, "无法获取飞机媒体文件的数量。"), + + CAMERA_NOT_CONNECTED(317002, "无法格式化飞机存储。确保飞机已通电并连接到码头,并且可以检测到摄像头。或者重新启动飞机,然后再试一次。"), + + FORMAT_AIRCRAFT_STORAGE_FAILED(317003, "无法格式化飞机存储。"), + + FORMAT_MEDIA_FILES_FAILED(317004, "格式化媒体文件失败。"), + + STOP_RECORDING_FAILED(317005, "飞机视频录制终止失败,本次飞行任务的媒体文件可能无法上传。"), + + NOT_IDLE(319001, "无法执行任务。Dock正在执行任务或上载问题日志。请等待任务完成或上载日志,然后重试。"), + + DOCK_SYSTEM_ERROR_2(319002, "Dock系统错误。重新启动dock,然后重试。"), + + TASK_ID_NOT_EXIST(319003, "dock中不存在任务ID"), + + TASK_EXPIRE(319004, "任务已过期。"), + + FLIGHTTASK_EXECUTE_COMMAND_TIMEOUT(319005, "执行命令传递超时。无法执行任务。"), + + CANCEL_TASK_FAILED_1(319006, "无法取消任务。任务正在进行中。"), + + EDIT_TASK_FAILED(319007, "无法编辑任务。任务正在进行中。"), + + TIME_NOT_SYNCED(319008, "停靠和云时间未同步。Dock无法执行任务。"), + + DISTRIBUTE_TASK_FAILED_2(319009, "未能分发任务。请稍后再试,或者重新启动dock然后再试。"), + + VERSION_TOO_EARLY(319010, "对接固件版本太早。无法执行任务。请将dock更新到最新版本,然后重试。"), + + INITIALIZING_DOCK(319015, "正在初始化dock。无法执行任务。等待初始化完成。"), + + PERFORMING_OTHER_TASK(319016, "停靠执行其他任务。无法执行当前任务。"), + + PROCESSING_MEDIA_FILE(319017, "停靠处理上次任务中捕获的媒体文件。无法执行当前任务。请稍后再试。"), + + EXPORTING_LOGS(319018, "无法执行任务。停靠上载问题日志。请稍后再试。"), + + PULLING_LOGS(319019, "无法执行任务。Dock获取问题日志。请稍后再试。"), + + PAUSE_TASK_FAILED(319020, "暂停飞行任务失败。"), + + DISABLE_FLIGHT_CONTROL_FAILED(319021, "无法禁用实时飞行控制。"), + + FLYTO_TASK_FAILED(319022, "FlyTo任务文件。"), + + STOP_FLYTO_TASK_FAILED(319023, "无法停止FlyTo任务。"), + + TAKING_OFF_TASK_FAILED(319024, "一键起飞失败"), + + TASK_IN_PREPARATION(319025, "准备中的任务。Dock无法执行从云中分发的任务。稍后再试"), + + LOW_POWER_THAN_SET_VALUE(319026, "飞机电池电量低于设定值。无法执行任务。等待充电完成,然后重试。"), + + INSUFFICIENT_STORAGE(319027, "码头或飞机上的存储空间不足。无法执行任务。请等待媒体文件上载到云中,然后重试。"), + + NO_FLIGHT_CONTROL_2(319030, "码头没有飞行控制权。"), + + NO_PAYLOAD_CONTROL(319031, "Dock没有有效载荷控制权限"), + + WRONG_POINT_NUMBER(319032, "飞到目标点,点编号错误。"), + + SEQ_NUMBER_SMALLER_THAN_LAST(319033, "DRC—飞行控制失败。程序包序列号小于最后一个。"), + + DELAY_TIME_SMALLER_THAN_SET(319034, "DRC—飞行控制失败。收到的包超时。"), + + EMERGENCY_STOP_FAILED(319035, "紧急停止失败,请重试。"), + + REMOTE_DEBUGGING_MODE(319036, "设备处于远程调试模式。"), + + ONSITE_DEBUGGING_MODE(319037, "设备处于现场调试模式。"), + + UPDATING(319038, "正在更新设备。请稍后再试。"), + + RESUME_TASK_FAILED(319042, "未能恢复飞行。"), + + CANCEL_TASK_FAILED_2(319043, "无法取消RTH。"), + + NO_BREAKPOINT(319044, "任务已完成。无法继续。"), + + EMERGENCY_STOP_STATUS(319045, "DRC—飞行控制失败。飞机暂停。"), + + NOT_IN_WAYLINE(319046, "任务已完成或暂停。无法暂停。"), + + DOCK_SYSTEM_ERROR_3(319999, "Dock系统错误。重新启动dock,然后重试。"), + + TASK_ERROR(321000, "任务错误。请稍后再试,或者重新启动dock然后再试。"), + + PROCESS_KMZ_FILE_FAILED_2(321004, "无法处理飞行路线文件。无法执行任务。检查文件。"), + + MISSING_BREAKPOINT(321005, "路线中缺少断点信息。"), + + TASK_IN_PROGRESS(321257, "任务正在进行中。无法再次启动任务。"), + + STATUS_NOT_SUPPORTED(321258, "无法停止任务。检查飞机状态。"), + + NOT_STARTED_CANNOT_STOP(321259, "任务未启动。无法停止任务。"), + + NOT_STARTED_CANNOT_INTERRUPT(321260, "任务未启动。无法暂停任务。"), + + HEIGHT_LIMIT(321513, "无法执行任务。飞行路线高度大于飞机最大飞行高度。"), + + DISTANCE_LIMIT(321514, "无法执行任务。航线起点或终点在缓冲区或超过距离限制。"), + + GEO_ZONE(321515, "无法执行任务。飞机将飞越地球同步轨道区域。"), + + HEIGHT_TOO_LOW(321516, "飞行高度过低。任务已停止。"), + + OBSTACLE_SENSED(321517, "感应到障碍物。任务已停止。"), + + APPROACHED_GEO_ZONE(321519, "飞机接近地球同步轨道区域或达到最大距离后自动返航。无法完成任务。"), + + PROPELLER_CHECK_FAILED(321523, "飞机螺旋桨检查失败。螺旋桨可能损坏。请稍后再试。如果问题仍然存在,请联系DJI支持部门更换螺旋桨。"), + + PREPARATION_FAILED_2(321524, "飞机起飞前的准备工作失败,可能是由于飞机无法定位或齿轮错误。请检查飞机的状态。"), + + WEAK_GPS(321769, "飞机卫星定位信号微弱。无法执行任务。重新启动dock,然后重试。"), + + WRONG_GEAR_MODE(321770, "飞机飞行模式错误。无法执行任务。重新启动dock,然后重试。"), + + HOME_POINT_NOT_SET(321771, "未设置飞机原点。无法执行任务。重新启动dock,然后重试。"), + + LOW_POWER_PERFORM_TASK(321772, "飞机电池电量低。无法执行任务。等待飞机充电至50%,然后重试。"), + + LOW_POWER_RTH(321773, "飞机电池电量低,返回家中。无法完成任务。"), + + AIRCRAFT_SIGNAL_LOST(321775, "执行任务时飞机信号丢失。"), + + RTK_NOT_READY(321776, "未能汇聚飞机RTK数据。无法执行任务。重新启动dock,然后重试。"), + + NOT_HOVERING(321777, "飞机没有悬停。无法启动任务。"), + + B_CONTROL_PROPELLERS(321778, "无法执行任务。飞机由管制员B控制,螺旋桨启动。"), + + USER_CONTROL(322282, "任务已停止。云用户或控制器B获得的飞机控制。"), + + USER_SEND_RTH(322283, "用户发送的RTH命令。飞机无法完成任务。"), + + WRONG_BREAKPOINT(322539, "断点信息错误。Dock无法执行任务"), + + EMPTY_ACTION_LAYER(322594, "动作树的层不能为空。"), + + WRONG_TASK(386535, "任务错误。请稍后再试,或者重新启动dock然后再试。"), + + SET_MEDIA_PRIORITY_FAILED(324030, "设置媒体上传优先级失败,上传队列中不存在该任务。"), + + MEDIA_PRIORITY_COMMAND_TOO_FAST(324031, "设置媒体上传优先级失败,发出命令的动作过快,对上一个命令的响应尚未结束。"), + + MEDIA_PRIORITY_WRONG_PARAMETER(324032, "设置媒体上传优先级失败,参数不正确。"), + + UNKNOWN(-1, "UNKNOWN"), + + ; + + + private final String msg; + + private final int code; + + WaylineErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + @Override + public String toString() { + return "{" + + "code='" + code + '\'' + + ", message=" + msg + + '}'; + } + + /** + * @param code error code + * @return enumeration object + */ + @JsonCreator + public static WaylineErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineMethodEnum.java new file mode 100644 index 0000000..db59a23 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineMethodEnum.java @@ -0,0 +1,39 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +public enum WaylineMethodEnum { + + FLIGHTTASK_CREATE("flighttask_create"), + + FLIGHTTASK_PREPARE("flighttask_prepare"), + + FLIGHTTASK_EXECUTE("flighttask_execute"), + + FLIGHTTASK_UNDO("flighttask_undo"), + + FLIGHTTASK_PAUSE("flighttask_pause"), + + FLIGHTTASK_RECOVERY("flighttask_recovery"), + + RETURN_HOME("return_home"), + + RETURN_HOME_CANCEL("return_home_cancel"); + + private final String method; + + WaylineMethodEnum(String method) { + this.method = method; + } + + @JsonValue + public String getMethod() { + return this.method; + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineMissionStateEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineMissionStateEnum.java new file mode 100644 index 0000000..c4fe6f6 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineMissionStateEnum.java @@ -0,0 +1,62 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/11 + */ +public enum WaylineMissionStateEnum { + + DISCONNECT(0, "Disconnect"), + + NOT_SUPPORTED_WAYPOINT(1, "Do not support this waypoint"), + + WAYLINE_PREPARING(2, "Wayline is ready. File can be uploaded and uploaded file can be executed."), + + WAYLINE_UPLOADING(3, "Wayline file is uploading"), + + DRONE_PREPARING(4, "Trigger start command. Trgger aircraft reading wayline. Not start. Under preparation."), + + ARRIVE_FIRST_WAYPOINT(5, "Enter wayline and arrive first waypoint"), + + WAYLINE_EXECUTING(6, "Execute wayline"), + + WAYLINE_BROKEN(7, "Wayline is broken. Trigger reason: 1. User pauses the wayline. 2. Flight control is abnormal."), + + WAYLINE_RECOVER(8, "Wayline recover"), + + WAYLINE_END(9, "Wayline stop"), + + ; + + private final int state; + + private final String msg; + + WaylineMissionStateEnum(int state, String msg) { + this.state = state; + this.msg = msg; + } + + @JsonValue + public int getState() { + return state; + } + + public String getMsg() { + return msg; + } + + @JsonCreator + public static WaylineMissionStateEnum find(int state) { + return Arrays.stream(values()).filter(stateEnum -> stateEnum.state == state).findAny() + .orElseThrow(() -> new CloudSDKException(WaylineMissionStateEnum.class, state)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylinePrecisionTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylinePrecisionTypeEnum.java new file mode 100644 index 0000000..77b2424 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylinePrecisionTypeEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/19 + */ +public enum WaylinePrecisionTypeEnum { + + GPS(0), + + RTK(1), + ; + + private final int type; + + WaylinePrecisionTypeEnum(int type) { + this.type = type; + } + + @JsonValue + public int getType() { + return type; + } + + @JsonCreator + public static WaylinePrecisionTypeEnum find(int type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type == type).findAny() + .orElseThrow(() -> new CloudSDKException(WaylinePrecisionTypeEnum.class, type)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineTypeEnum.java new file mode 100644 index 0000000..7e753d8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineTypeEnum.java @@ -0,0 +1,51 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/9/26 + */ +@Schema(enumAsRef = true, type = "int", allowableValues = {"0", "1", "2", "3"}, + description = "

0: waypoint

1: mapping2d

2: mapping3d

3: mappingStrip

") +public enum WaylineTypeEnum { + + WAYPOINT(0, "waypoint"), + + MAPPING_2D(1, "mapping2d"), + + MAPPING_3D(2, "mapping3d"), + + MAPPING_STRIP(3, "mappingStrip"); + + private final int value; + + private final String type; + + WaylineTypeEnum(int value, String type) { + this.value = value; + this.type = type; + } + + @JsonValue + public int getValue() { + return value; + } + + @JsonCreator + public static WaylineTypeEnum find(int value) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.value == value).findAny() + .orElseThrow(() -> new CloudSDKException(WaylineTypeEnum.class, value)); + } + + public static WaylineTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new CloudSDKException(WaylineTypeEnum.class, type)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineUploadCallbackMetadata.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineUploadCallbackMetadata.java new file mode 100644 index 0000000..ecf738f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineUploadCallbackMetadata.java @@ -0,0 +1,83 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/12 + */ +@Schema(description = "Wayline file metadata") +public class WaylineUploadCallbackMetadata { + + /** + * drone device product enum + */ + @NotNull + @Schema(description = "drone device product enum", example = "0-67-0") + @JsonProperty("drone_model_key") + private DeviceEnum droneModelKey; + + /** + * payload device product enum + */ + @NotNull + @Size(min = 1) + @JsonProperty("payload_model_keys") + @Schema(description = "payload device product enum", example = "[\"1-53-0\"]") + private List payloadModelKeys; + + /** + * wayline template collection + */ + @NotNull + @Size(min = 1) + @Schema(description = "wayline template collection", example = "[0]") + @JsonProperty("template_types") + private List templateTypes; + + public WaylineUploadCallbackMetadata() { + } + + @Override + public String toString() { + return "WaylineUploadCallbackMetadata{" + + "droneModelKey='" + droneModelKey + '\'' + + ", payloadModelKeys=" + payloadModelKeys + + ", templateTypes=" + templateTypes + + '}'; + } + + public DeviceEnum getDroneModelKey() { + return droneModelKey; + } + + public WaylineUploadCallbackMetadata setDroneModelKey(DeviceEnum droneModelKey) { + this.droneModelKey = droneModelKey; + return this; + } + + public List getPayloadModelKeys() { + return payloadModelKeys; + } + + public WaylineUploadCallbackMetadata setPayloadModelKeys(List payloadModelKeys) { + this.payloadModelKeys = payloadModelKeys; + return this; + } + + public List getTemplateTypes() { + return templateTypes; + } + + public WaylineUploadCallbackMetadata setTemplateTypes(List templateTypes) { + this.templateTypes = templateTypes; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineUploadCallbackRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineUploadCallbackRequest.java new file mode 100644 index 0000000..8744462 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/WaylineUploadCallbackRequest.java @@ -0,0 +1,69 @@ +package org.dromara.common.sdk.cloudapi.wayline; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/23 + */ +@Schema(description = "The data class of the upload result callback") +public class WaylineUploadCallbackRequest { + + @NotNull + @Schema(description = "The key of the object in the bucket", example = "wayline/waylineFile.kmz") + @JsonProperty("object_key") + private String objectKey; + + @NotNull + @Schema(description = "wayline file name", example = "waylineFile") + private String name; + + @Valid + @NotNull + @Schema(description = "wayline file metadata") + private WaylineUploadCallbackMetadata metadata; + + public WaylineUploadCallbackRequest() { + } + + @Override + public String toString() { + return "WaylineUploadCallbackRequest{" + + "objectKey='" + objectKey + '\'' + + ", name='" + name + '\'' + + ", metadata=" + metadata + + '}'; + } + + public String getObjectKey() { + return objectKey; + } + + public WaylineUploadCallbackRequest setObjectKey(String objectKey) { + this.objectKey = objectKey; + return this; + } + + public String getName() { + return name; + } + + public WaylineUploadCallbackRequest setName(String name) { + this.name = name; + return this; + } + + public WaylineUploadCallbackMetadata getMetadata() { + return metadata; + } + + public WaylineUploadCallbackRequest setMetadata(WaylineUploadCallbackMetadata metadata) { + this.metadata = metadata; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/api/AbstractWaylineService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/api/AbstractWaylineService.java new file mode 100644 index 0000000..1ea8229 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/api/AbstractWaylineService.java @@ -0,0 +1,206 @@ +package org.dromara.common.sdk.cloudapi.wayline.api; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.cloudapi.wayline.*; +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.events.EventsDataRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsResponse; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsRequest; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsResponse; +import org.dromara.common.sdk.mqtt.services.ServicesPublish; +import org.dromara.common.sdk.mqtt.services.ServicesReplyData; +import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; +import jakarta.annotation.Resource; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public abstract class AbstractWaylineService { + + @Resource + private ServicesPublish servicesPublish; + + /** + * Notification of device exits the Return to Home (RTH) state + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_DEVICE_EXIT_HOMING_NOTIFY, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse deviceExitHomingNotify(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("deviceExitHomingNotify not implemented"); + } + + /** + * Report wayline task progress + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHTTASK_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse flighttaskProgress(TopicEventsRequest> request, MessageHeaders headers) { + throw new UnsupportedOperationException("flighttaskProgress not implemented"); + } + + /** + * Notification of task readiness + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLIGHTTASK_READY, outputChannel = ChannelName.OUTBOUND_EVENTS) + public TopicEventsResponse flighttaskReady(TopicEventsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("flighttaskReady not implemented"); + } + + /** + * Create wayline task (Deprecated) + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(deprecated = CloudSDKVersionEnum.V0_0_1, exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskCreate(GatewayManager gateway, FlighttaskCreateRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_CREATE.getMethod(), + request); + } + + /** + * Issue wayline task + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskPrepare(GatewayManager gateway, FlighttaskPrepareRequest request) { + validPrepareParam(request); + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_PREPARE.getMethod(), + request, + request.getFlightId()); + } + + /** + * Execute wayline task + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskExecute(GatewayManager gateway, FlighttaskExecuteRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_EXECUTE.getMethod(), + request, + request.getFlightId()); + } + + /** + * Cancel wayline task + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskUndo(GatewayManager gateway, FlighttaskUndoRequest request) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_UNDO.getMethod(), + request); + } + + /** + * Pause wayline task + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskPause(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_PAUSE.getMethod()); + } + + /** + * Resume wayline task + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse flighttaskRecovery(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.FLIGHTTASK_RECOVERY.getMethod()); + } + + /** + * Return to Home (RTH) + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse returnHome(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.RETURN_HOME.getMethod()); + } + + /** + * Cancel return to home + * @param gateway + * @return services_reply + */ + @CloudSDKVersion(exclude = GatewayTypeEnum.RC) + public TopicServicesResponse returnHomeCancel(GatewayManager gateway) { + return servicesPublish.publish( + gateway.getGatewaySn(), + WaylineMethodEnum.RETURN_HOME_CANCEL.getMethod()); + } + + /** + * Get the wayline task resource + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_FLIGHTTASK_RESOURCE_GET, outputChannel = ChannelName.OUTBOUND_REQUESTS) + public TopicRequestsResponse> flighttaskResourceGet(TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("flighttaskResourceGet not implemented"); + } + + /** + * Return-to-home information + * @param request data + * @param headers The headers for a {@link Message}. + * @return events_reply + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_RETURN_HOME_INFO, outputChannel = ChannelName.OUTBOUND_EVENTS) + @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_0) + public TopicRequestsResponse returnHomeInfo(TopicRequestsRequest request, MessageHeaders headers) { + throw new UnsupportedOperationException("returnHomeInfo not implemented"); + } + + private void validPrepareParam(FlighttaskPrepareRequest request) { + if (null == request.getExecuteTime() + && (TaskTypeEnum.IMMEDIATE == request.getTaskType() || TaskTypeEnum.TIMED == request.getTaskType())) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, "Execute time must not be null."); + } + if (TaskTypeEnum.CONDITIONAL == request.getTaskType()) { + Common.validateModel(request.getReadyConditions()); + } + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/api/IHttpWaylineService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/api/IHttpWaylineService.java new file mode 100644 index 0000000..195f464 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/wayline/api/IHttpWaylineService.java @@ -0,0 +1,152 @@ +package org.dromara.common.sdk.cloudapi.wayline.api; + +import org.dromara.common.sdk.cloudapi.wayline.GetWaylineListRequest; +import org.dromara.common.sdk.cloudapi.wayline.GetWaylineListResponse; +import org.dromara.common.sdk.cloudapi.wayline.WaylineUploadCallbackRequest; +import org.dromara.common.sdk.common.HttpResultResponse; +import org.dromara.common.sdk.common.PaginationData; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import org.springdoc.api.annotations.ParameterObject; +import org.springframework.web.bind.annotation.*; + + +import java.util.List; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Tag(name = "wayline interface") +public interface IHttpWaylineService { + + String PREFIX = "wayline/api/v1"; + + /** + * Query the basic data of the wayline file according to the query conditions. + * The query condition field in pilot is fixed. + * @param workspaceId workspace id + * @param request get waylines params + * @param req + * @param rsp + * @return wayline list + */ + @Operation(summary = "get wayline list", description = "Query the basic data of the wayline file according to " + + "the query conditions. The query condition field in pilot is fixed.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")) + }) + @GetMapping(PREFIX + "/workspaces/{workspace_id}/waylines") + HttpResultResponse> getWaylineList( + @Valid @ParameterObject GetWaylineListRequest request, + @PathVariable(name = "workspace_id") String workspaceId, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Query the download address of the file according to the wayline file id, + * and redirect to this address directly for download. + * @param workspaceId workspace id + * @param waylineId wayline file id + * @param req + * @param rsp + */ + @Operation(summary = "get wayline file download address", description = "Query the download address of the file " + + "according to the wayline file id, and redirect to this address directly for download.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", schema = @Schema(format = "uuid")), + @Parameter(name = "wayline_id", description = "wayline id", schema = @Schema(format = "uuid")) + }) + @GetMapping(PREFIX + "/workspaces/{workspace_id}/waylines/{wayline_id}/url") + void getWaylineFileDownloadAddress( + @PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "wayline_id") String waylineId, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Checking whether the name already exists according to the wayline name must ensure the uniqueness of the wayline name. + * This interface will be called when uploading waylines and must be available. + * @param workspaceId workspace id + * @param names wayline file name collection + * @param req + * @param rsp + * @return already existing wayline name + */ + @Operation(summary = "get duplicated wayline name", description = "Checking whether the name already exists " + + "according to the wayline name must ensure the uniqueness of the wayline name. " + + "This interface will be called when uploading waylines and must be available.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", required = true), + @Parameter(name = "name", description = "wayline file name", required = true) + }) + @GetMapping(PREFIX + "/workspaces/{workspace_id}/waylines/duplicate-names") + HttpResultResponse> getDuplicatedWaylineName( + @PathVariable(name = "workspace_id") String workspaceId, + @NotNull @Size(min = 1) @RequestParam(name = "name") List names, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * When the wayline file is uploaded to the storage server by pilot, + * the basic information of the file is reported through this interface. + * @param workspaceId workspace id + * @param request upload callback params + * @param req + * @param rsp + * @return success + */ + @Operation(summary = "file upload result report", description = "When the wayline file is uploaded to the " + + "storage server by pilot, the basic information of the file is reported through this interface.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", required = true) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/upload-callback") + HttpResultResponse fileUploadResultReport( + @PathVariable(name = "workspace_id") String workspaceId, + @Valid @RequestBody WaylineUploadCallbackRequest request, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Favorite the wayline file according to the wayline file id. + * @param workspaceId workspace id + * @param ids wayline file id + * @param req + * @param rsp + * @return success + */ + @Operation(summary = "batch favorites wayline", description = "Favorite the wayline file according to the wayline file id.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", required = true), + @Parameter(name = "id", description = "wayline id", required = true) + }) + @PostMapping(PREFIX + "/workspaces/{workspace_id}/favorites") + HttpResultResponse batchFavoritesWayline( + @PathVariable(name = "workspace_id") String workspaceId, + @NotNull @Size(min = 1) @RequestParam(name = "id") List ids, + HttpServletRequest req, HttpServletResponse rsp); + + /** + * Delete the favorites of this wayline file based on the wayline file id. + * @param workspaceId workspace id + * @param ids wayline file id + * @param req + * @param rsp + * @return success + */ + @Operation(summary = "batch unfavorites wayline", description = "Delete the favorites of this wayline file based on the wayline file id.", + parameters = { + @Parameter(name = "workspace_id", description = "workspace id", required = true), + @Parameter(name = "id", description = "wayline id", required = true) + }) + @DeleteMapping(PREFIX + "/workspaces/{workspace_id}/favorites") + HttpResultResponse batchUnfavoritesWayline( + @PathVariable(name = "workspace_id") String workspaceId, + @NotNull @Size(min = 1) @RequestParam(name = "id") List ids, + HttpServletRequest req, HttpServletResponse rsp); +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/BaseModel.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/BaseModel.java new file mode 100644 index 0000000..d0678f2 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/BaseModel.java @@ -0,0 +1,82 @@ +package org.dromara.common.sdk.common; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.springframework.util.CollectionUtils; + +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class BaseModel { + + private final static Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator(); + + public void valid() { + this.valid(null); + } + + public void checkProperty(String fieldName, GatewayManager gateway) { + try { + Field field = this.getClass().getDeclaredField(fieldName); + CloudSDKVersion annotation = field.getDeclaredAnnotation(CloudSDKVersion.class); + if (!gateway.isTypeSupport(annotation) || !gateway.isVersionSupport(annotation)) { + throw new CloudSDKException(CloudSDKErrorEnum.DEVICE_PROPERTY_NOT_SUPPORT, fieldName); + } + } catch (NoSuchFieldException e) { + throw new CloudSDKException(e); + } + } + + public void valid(GatewayManager gateway) { + Set> violations = VALIDATOR.validate(this); + if (null != gateway) { + Set names = new HashSet<>(); + violations = violations.stream().filter(violation -> + filterProperty(gateway, violation.getRootBeanClass(), + violation.getPropertyPath().toString().split("\\."), 0, true, names)) + .collect(Collectors.toSet()); + } + + if (CollectionUtils.isEmpty(violations)) { + return; + } + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, violations.stream() + .map(violation -> violation.getPropertyPath().toString() + violation.getMessage() + + ", Current value is: " + violation.getInvalidValue()) + .collect(Collectors.joining("; "))); + + } + + private boolean filterProperty(GatewayManager gateway, Class clazz, String[] fields, int index, boolean isValid, Set names) { + if (!isValid || index == fields.length) { + return isValid; + } + String name = String.join(".", Arrays.copyOf(fields, index + 1)); + if (names.contains(name)) { + return false; + } + try { + Field field = clazz.getDeclaredField(fields[index]); + isValid = gateway.isPropertyValid(field.getAnnotation(CloudSDKVersion.class)); + if (!isValid) { + names.add(name); + } + return filterProperty(gateway, field.getType(), fields, index + 1, isValid, names); + } catch (NoSuchFieldException e) { + throw new CloudSDKException(e); + } + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/Common.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/Common.java new file mode 100644 index 0000000..6cc1733 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/Common.java @@ -0,0 +1,79 @@ +package org.dromara.common.sdk.common; + +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public class Common { + + private static final JsonMapper.Builder MAPPER_BUILDER = JsonMapper.builder(); + + static { + JavaTimeModule timeModule = new JavaTimeModule(); + timeModule.addDeserializer(LocalDateTime.class, + new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + timeModule.addSerializer(LocalDateTime.class, + new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + + MAPPER_BUILDER.propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE) + .serializationInclusion(JsonInclude.Include.NON_ABSENT) + .disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS) + .addModule(timeModule) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) + .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true) + .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true) + .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true); + } + + public static void validateModel(BaseModel model) { + if (null == model) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, "Param must not be null."); + } + model.valid(); + } + + public static void validateModel(BaseModel model, GatewayManager gateway) { + if (null == model) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, "Param must not be null."); + } + model.valid(gateway); + } + + public static ObjectMapper getObjectMapper() { + return MAPPER_BUILDER.build(); + } + + public static String convertSnake(String key) { + StringBuilder sb = new StringBuilder(); + boolean isChange = false; + for (char c : key.toCharArray()) { + if (c == '_') { + isChange = true; + continue; + } + if (isChange) { + sb.append((char)(c - 32)); + isChange = false; + continue; + } + sb.append(c); + } + return sb.toString(); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/CommonErrorEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/CommonErrorEnum.java new file mode 100644 index 0000000..8a7034e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/CommonErrorEnum.java @@ -0,0 +1,44 @@ + +package org.dromara.common.sdk.common; + +import org.dromara.common.sdk.mqtt.events.IEventsErrorCode; +import org.dromara.common.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum CommonErrorEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + + SUCCESS(0, "Success"), + + STATUS_NOT_SUPPORTED(314000, "该设备正在上传日志或执行飞行任务。请稍后再试。"), + + WRONG_PARAMETER(325001, "Cloud命令参数错误。Dock无法执行命令。"), + + UNKNOWN(-1, "Unknown"); + + private final int code; + + private final String msg; + + CommonErrorEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + public Integer getCode() { + return this.code; + } + + public String getMessage() { + return this.msg; + } + + public static CommonErrorEnum find(int code) { + return Arrays.stream(values()).filter(error -> error.code == code).findAny().orElse(UNKNOWN); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/ErrorCodeSourceEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/ErrorCodeSourceEnum.java new file mode 100644 index 0000000..c09a188 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/ErrorCodeSourceEnum.java @@ -0,0 +1,39 @@ + +package org.dromara.common.sdk.common; + +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum ErrorCodeSourceEnum { + + DEVICE(3), + + DOCK(5), + + PILOT(6); + + private final int source; + + ErrorCodeSourceEnum(int source) { + this.source = source; + } + + @JsonValue + public int getSource() { + return source; + } + + @JsonCreator + public static ErrorCodeSourceEnum find(int source) { + return Arrays.stream(values()).filter(error -> error.source == source).findAny() + .orElseThrow(() -> new CloudSDKException(ErrorCodeSourceEnum.class, source)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/HttpResultResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/HttpResultResponse.java new file mode 100644 index 0000000..cf3f465 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/HttpResultResponse.java @@ -0,0 +1,95 @@ +package org.dromara.common.sdk.common; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "The data format of the http response.") +public class HttpResultResponse { + + public static final int CODE_SUCCESS = 0; + public static final int CODE_FAILED = -1; + public static final String MESSAGE_SUCCESS = "success"; + public static final String MESSAGE_FAILED = "failed"; + + @Schema(description = "0 means success, non-zero means error.", example = "0") + private int code; + + @Schema(description = "The response message.", example = MESSAGE_SUCCESS) + private String message; + + @Schema(description = "The response data.") + private T data; + + public HttpResultResponse() { + } + + @Override + public String toString() { + return "HttpResultResponse{" + + "code=" + code + + ", message='" + message + '\'' + + ", data=" + data + + '}'; + } + + public int getCode() { + return code; + } + + public HttpResultResponse setCode(int code) { + this.code = code; + return this; + } + + public String getMessage() { + return message; + } + + public HttpResultResponse setMessage(String message) { + this.message = message;; + return this; + } + + public T getData() { + return data; + } + + public HttpResultResponse setData(T data) { + this.data = data; + return this; + } + + public static HttpResultResponse success() { + return new HttpResultResponse() + .setCode(CODE_SUCCESS) + .setMessage(MESSAGE_SUCCESS) + .setData(""); + } + + public static HttpResultResponse success(T data) { + return HttpResultResponse.success().setData(data); + } + + public static HttpResultResponse error() { + return new HttpResultResponse() + .setCode(CODE_FAILED) + .setMessage(MESSAGE_FAILED); + } + + public static HttpResultResponse error(String message) { + return new HttpResultResponse() + .setCode(CODE_FAILED) + .setMessage(message); + } + + public static HttpResultResponse error(int code, String message) { + return new HttpResultResponse() + .setCode(code) + .setMessage(message); + } + + public static HttpResultResponse error(IErrorInfo errorInfo) { + return new HttpResultResponse() + .setCode(errorInfo.getCode()) + .setMessage(errorInfo.getMessage()); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/IErrorInfo.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/IErrorInfo.java new file mode 100644 index 0000000..53498bd --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/IErrorInfo.java @@ -0,0 +1,22 @@ +package org.dromara.common.sdk.common; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public interface IErrorInfo { + + /** + * Get error message. + * @return error message + */ + String getMessage(); + + /** + * Get error code. + * @return error code + */ + Integer getCode(); + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/Pagination.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/Pagination.java new file mode 100644 index 0000000..fe0edb1 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/Pagination.java @@ -0,0 +1,79 @@ +package org.dromara.common.sdk.common; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * Used for paging display. These field names cannot be changed. + * Because they need to be the same as the pilot. + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Schema(description = "Used for paging display") +public class Pagination { + + /** + * The current page number. + */ + @Schema(description = "The current page number.", example = "1") + private long page; + + /** + * The amount of data displayed per page. + */ + @Schema(description = "The amount of data displayed per page.", example = "10") + @JsonProperty("page_size") + private long pageSize; + + /** + * The total amount of all data. + */ + @Schema(description = "The total amount of all data.", example = "10") + private long total; + + public Pagination() { + } + + public Pagination(long page, long pageSize, long total) { + this.page = page; + this.pageSize = pageSize; + this.total = total; + } + + @Override + public String toString() { + return "Pagination{" + + "page=" + page + + ", pageSize=" + pageSize + + ", total=" + total + + '}'; + } + + public long getPage() { + return page; + } + + public Pagination setPage(long page) { + this.page = page; + return this; + } + + public long getPageSize() { + return pageSize; + } + + public Pagination setPageSize(long pageSize) { + this.pageSize = pageSize; + return this; + } + + public long getTotal() { + return total; + } + + public Pagination setTotal(long total) { + this.total = total; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/PaginationData.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/PaginationData.java new file mode 100644 index 0000000..d5714dd --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/PaginationData.java @@ -0,0 +1,58 @@ +package org.dromara.common.sdk.common; + +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.List; + +/** + * The format of the data response when a paginated display is required. + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Schema(description = "Format of paged data") +public class PaginationData { + + /** + * The collection in which the data list is stored. + */ + @Schema(description = "The collection in which the data list is stored.") + private List list; + + @Schema(description = "Used for paging display. These field names cannot be changed. Because they need to be the same as the pilot.") + private Pagination pagination; + + public PaginationData() { + } + + public PaginationData(List list, Pagination pagination) { + this.list = list; + this.pagination = pagination; + } + + @Override + public String toString() { + return "PaginationData{" + + "list=" + list + + ", pagination=" + pagination + + '}'; + } + + public List getList() { + return list; + } + + public PaginationData setList(List list) { + this.list = list; + return this; + } + + public Pagination getPagination() { + return pagination; + } + + public PaginationData setPagination(Pagination pagination) { + this.pagination = pagination; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/SDKManager.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/SDKManager.java new file mode 100644 index 0000000..1f22eae --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/SDKManager.java @@ -0,0 +1,52 @@ +package org.dromara.common.sdk.common; + +import org.dromara.common.sdk.cloudapi.device.DeviceDomainEnum; +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; +import org.dromara.common.sdk.cloudapi.device.DeviceSubTypeEnum; +import org.dromara.common.sdk.cloudapi.device.DeviceTypeEnum; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; + +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public class SDKManager { + + private SDKManager() { + } + + private static final ConcurrentHashMap SDK_MAP = new ConcurrentHashMap<>(16); + + public static GatewayManager getDeviceSDK(String gatewaySn) { + if (SDK_MAP.containsKey(gatewaySn)) { + return SDK_MAP.get(gatewaySn); + } + throw new CloudSDKException(CloudSDKErrorEnum.NOT_REGISTERED, + "设备尚未注册,请先调用“SDKManager.registerDevice()”方法注册设备。"); + } + + public static GatewayManager registerDevice(String gatewaySn, String droneSn, + DeviceDomainEnum domain, DeviceTypeEnum type, DeviceSubTypeEnum subType, String gatewayThingVersion, String droneThingVersion) { + return registerDevice(gatewaySn, droneSn, GatewayTypeEnum.find(DeviceEnum.find(domain, type, subType)), gatewayThingVersion, droneThingVersion); + } + + public static GatewayManager registerDevice(String gatewaySn, String droneSn, GatewayTypeEnum type, String gatewayThingVersion, String droneThingVersion) { + return registerDevice(new GatewayManager(Objects.requireNonNull(gatewaySn), droneSn, type, gatewayThingVersion, droneThingVersion)); + } + + public static GatewayManager registerDevice(GatewayManager gateway) { + SDK_MAP.put(gateway.getGatewaySn(), gateway); + return gateway; + } + + public static void logoutDevice(String gatewaySn) { + SDK_MAP.remove(gatewaySn); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/SpringBeanUtils.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/SpringBeanUtils.java new file mode 100644 index 0000000..1f80147 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/common/SpringBeanUtils.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.common; + +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 SpringBeanUtils implements ApplicationContextAware { + + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringBeanUtils.applicationContext = applicationContext; + } + + public static T getBean(Class clazz) { + return applicationContext.getBean(clazz); + } + + public static Object getBean(String beanName) { + return applicationContext.getBean(beanName); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/CloudSDKHandler.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/CloudSDKHandler.java new file mode 100644 index 0000000..e286ef3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/CloudSDKHandler.java @@ -0,0 +1,108 @@ +package org.dromara.common.sdk.config; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; +import org.dromara.common.sdk.common.*; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; + +import java.lang.reflect.*; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/22 + */ +@Aspect +@Component +public class CloudSDKHandler { + + @Before("execution(public * org.dromara.common.sdk.cloudapi.*.api.*.*(org.dromara.common.sdk.config.version.GatewayManager, ..))") + public void checkCloudSDK(JoinPoint point) { + GatewayManager deviceSDK = (GatewayManager) point.getArgs()[0]; + CloudSDKVersion since = ((MethodSignature) point.getSignature()).getMethod().getDeclaredAnnotation(CloudSDKVersion.class); + if (Objects.isNull(since)) { + return; + } + if (!deviceSDK.isTypeSupport(since)) { + throw new CloudSDKException(CloudSDKErrorEnum.DEVICE_TYPE_NOT_SUPPORT); + } + if (!deviceSDK.isVersionSupport(since)) { + throw new CloudSDKException(CloudSDKErrorEnum.DEVICE_VERSION_NOT_SUPPORT); + } + } + + @Before("execution(public * org.dromara.common.sdk.cloudapi.*.api.*.*(org.dromara.common.sdk.config.version.GatewayManager, org.dromara.common.sdk.common.BaseModel+))") + public void checkRequest(JoinPoint point) { + Common.validateModel((BaseModel) point.getArgs()[1], (GatewayManager) point.getArgs()[0]); + } + + @AfterReturning(value = "execution(public org.dromara.common.sdk.common.HttpResultResponse+ org.dromara.common.sdk.cloudapi.*.api.*.*(..))", returning = "response") + public void checkResponse(JoinPoint point, HttpResultResponse response) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { + if (null == response) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, "The return value cannot be null."); + } + Method method = ((MethodSignature) point.getSignature()).getMethod(); + if (method.getGenericReturnType() instanceof Class) { + if (null == response.getData()) { + response.setData(""); + } + return; + } + checkClassType((ParameterizedType) method.getGenericReturnType(), response); + validData(response.getData(), point.getArgs()[0]); + } + + private void checkClassType(ParameterizedType type, HttpResultResponse response) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + Type actualType = type.getActualTypeArguments()[0]; + Class typeClass = actualType instanceof Class ? (Class) actualType : (Class) ((ParameterizedType) actualType).getRawType(); + if (null == response.getData()) { + if (List.class.isAssignableFrom(typeClass)) { + response.setData(Collections.emptyList()); + return; + } + response.setData(typeClass.getDeclaredConstructor().newInstance()); + return; + } + boolean isAssignableFrom = typeClass.isAssignableFrom(response.getData().getClass()); + if (!isAssignableFrom) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER); + } + } + + private void validData(Object data, Object arg) { + if (data instanceof BaseModel) { + Common.validateModel((BaseModel) data); + return; + } + if (data instanceof PaginationData) { + List list = ((PaginationData) data).getList(); + if (null == list) { + ((PaginationData) data).setList(Collections.EMPTY_LIST); + try { + Field page = arg.getClass().getDeclaredField("page"); + Field pageSize = arg.getClass().getDeclaredField("pageSize"); + page.setAccessible(true); + pageSize.setAccessible(true); + ((PaginationData) data).setPagination( + new Pagination().setPage((int) page.get(arg)).setPageSize((int) pageSize.get(arg))); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, e.getMessage()); + } + return; + } + for (BaseModel model : list) { + Common.validateModel(model); + } + } + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/CloudSDKMvcConfigurer.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/CloudSDKMvcConfigurer.java new file mode 100644 index 0000000..0386810 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/CloudSDKMvcConfigurer.java @@ -0,0 +1,16 @@ +package org.dromara.common.sdk.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +@Configuration +public class CloudSDKMvcConfigurer implements WebMvcConfigurer { + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(new GetSnakeArgumentProcessor(true)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/GetSnakeArgumentProcessor.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/GetSnakeArgumentProcessor.java new file mode 100644 index 0000000..f261708 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/GetSnakeArgumentProcessor.java @@ -0,0 +1,29 @@ +package org.dromara.common.sdk.config; + +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/16 + */ +public class GetSnakeArgumentProcessor extends ServletModelAttributeMethodProcessor { + + /** + * Class constructor. + * + * @param annotationNotRequired if "true", non-simple method arguments and + * return values are considered model attributes with or without a + * {@code @ModelAttribute} annotation + */ + public GetSnakeArgumentProcessor(boolean annotationNotRequired) { + super(annotationNotRequired); + } + + @Override + protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) { + super.bindRequestParameters(new GetSnakeDataBinder(binder.getTarget(), binder.getObjectName()), request); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/GetSnakeDataBinder.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/GetSnakeDataBinder.java new file mode 100644 index 0000000..c0919cf --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/GetSnakeDataBinder.java @@ -0,0 +1,109 @@ +package org.dromara.common.sdk.config; + +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.servlet.ServletRequest; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.PropertyValue; +import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +public class GetSnakeDataBinder extends ExtendedServletRequestDataBinder { + + public GetSnakeDataBinder(Object target, String objectName) { + super(target, objectName); + } + + @Override + protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) { + List propertyValueList = mpvs.getPropertyValueList(); + List values = new ArrayList<>(propertyValueList); + Field[] fields = this.getTarget().getClass().getDeclaredFields(); + Map fieldMap = Arrays.stream(fields).collect(Collectors.toMap(Field::getName, field -> field)); + fieldMap.putAll(Arrays.stream(fields).filter(field -> null != field.getAnnotation(JsonProperty.class)) + .collect(Collectors.toMap(field -> field.getAnnotation(JsonProperty.class).value(), field -> field))); + + for (PropertyValue property : values) { + if (!fieldMap.containsKey(property.getName())) { + continue; + } + + Field field = fieldMap.get(property.getName()); + List list = (List) Objects.requireNonNullElse(property.getConvertedValue(), new ArrayList<>()); + list.addAll((List) convertValue(field, this.getTarget(), property.getValue())); + property.setConvertedValue(list); + + String fieldName = field.getName(); + if (mpvs.contains(fieldName)) { + PropertyValue propertyValue = mpvs.getPropertyValue(fieldName); + if (propertyValue != property && null != propertyValue.getConvertedValue()) { + ((List) propertyValue.getConvertedValue()).addAll((List) property.getConvertedValue()); + property = propertyValue; + } + } + Object data = Collection.class.isAssignableFrom(field.getType()) ? property.getConvertedValue() : ((List) property.getConvertedValue()).get(0); + mpvs.addPropertyValue(new PropertyValue(fieldName, Objects.requireNonNullElse(data, property.getValue()))); + } + + super.addBindValues(mpvs, request); + } + + private Object convertValue(Field field, Object object, Object value) { + List convertedValue = new ArrayList(); + if (Enum.class.isAssignableFrom(field.getType())) { + convertedValue.add(getRealEnumValue(field.getType(), object, value)); + return convertedValue; + } + if (field.getType() == field.getGenericType()) { + convertedValue.add(value); + return convertedValue; + } + if (Collection.class.isAssignableFrom(field.getType())) { + if (!value.getClass().isArray()) { + value = String.valueOf(value).split(","); + } + for (String v : (String[]) value) { + if ("".equals(v)) { + continue; + } + convertedValue.add(getRealEnumValue((Class) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0], object, v)); + } + } + + return convertedValue; + } + + private Object getRealEnumValue(Class type, Object object, Object... value) { + if (!type.isEnum()) { + return value; + } + Set methods = Arrays.stream(type.getDeclaredMethods()) + .filter(m -> null != m.getAnnotation(JsonCreator.class)) + .filter(m -> m.getParameterTypes().length == value.length).collect(Collectors.toSet()); + for (Method m : methods) { + try { + Class[] parameterTypes = m.getParameterTypes(); + for (int i = 0; i < value.length; i++) { + value[i] = Common.getObjectMapper().convertValue(value[i], parameterTypes[i]); + } + return m.invoke(object, value); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new CloudSDKException(e); + } + } + return value; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/CloudSDKVersionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/CloudSDKVersionEnum.java new file mode 100644 index 0000000..b9f2376 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/CloudSDKVersionEnum.java @@ -0,0 +1,43 @@ +package org.dromara.common.sdk.config.version; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/22 + */ +public enum CloudSDKVersionEnum { + + V0_0_1("0.0.1"), + + V1_0_0("1.0.0"), + + V1_0_1("1.0.1"), + + V1_0_2("1.0.2"), + + V1_0_3("1.0.3"), + + V1_3_1("1.3.1"), + + DEFAULT("1.0.3"), + + V99("99"); + + private final String version; + + CloudSDKVersionEnum(String version) { + this.version = version; + } + + public String getVersion() { + return version; + } + + public boolean isSupported(CloudSDKVersionEnum version) { + return this.version.compareTo(version.getVersion()) >= 0; + } + + public boolean isDeprecated(CloudSDKVersionEnum version) { + return this.version.compareTo(version.getVersion()) >= 0; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/Dock2ThingVersionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/Dock2ThingVersionEnum.java new file mode 100644 index 0000000..2e130ed --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/Dock2ThingVersionEnum.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.config.version; + +import org.dromara.common.sdk.exception.CloudSDKVersionException; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/9/7 + */ +public enum Dock2ThingVersionEnum implements IThingVersion { + + V1_1_2("1.1.2", CloudSDKVersionEnum.V1_0_1), + + V1_2_0("1.2.0", CloudSDKVersionEnum.V1_0_3), + V1_3_0("1.3.0", CloudSDKVersionEnum.V1_0_3), + V1_3_1("1.3.1", CloudSDKVersionEnum.V1_3_1), + ; + + private final String thingVersion; + + private final CloudSDKVersionEnum cloudSDKVersion; + + Dock2ThingVersionEnum(String thingVersion, CloudSDKVersionEnum cloudSDKVersion) { + this.thingVersion = thingVersion; + this.cloudSDKVersion = cloudSDKVersion; + } + + @JsonValue + public String getThingVersion() { + return thingVersion; + } + + public CloudSDKVersionEnum getCloudSDKVersion() { + return cloudSDKVersion; + } + + public static Dock2ThingVersionEnum find(String thingVersion) { + return Arrays.stream(values()).filter(thingVersionEnum -> thingVersionEnum.thingVersion.equals(thingVersion)) + .findAny().orElseThrow(() -> new CloudSDKVersionException(thingVersion)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/DockThingVersionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/DockThingVersionEnum.java new file mode 100644 index 0000000..11bfeb5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/DockThingVersionEnum.java @@ -0,0 +1,47 @@ +package org.dromara.common.sdk.config.version; + +import org.dromara.common.sdk.exception.CloudSDKVersionException; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public enum DockThingVersionEnum implements IThingVersion { + + V1_0_0("1.0.0", CloudSDKVersionEnum.V0_0_1), + + V1_1_0("1.1.0", CloudSDKVersionEnum.V0_0_1), + + V1_1_2("1.1.2", CloudSDKVersionEnum.V1_0_0), + + V1_1_3("1.1.3", CloudSDKVersionEnum.V1_0_2), + + ; + + private final String thingVersion; + + private final CloudSDKVersionEnum cloudSDKVersion; + + DockThingVersionEnum(String thingVersion, CloudSDKVersionEnum cloudSDKVersion) { + this.thingVersion = thingVersion; + this.cloudSDKVersion = cloudSDKVersion; + } + + @JsonValue + public String getThingVersion() { + return thingVersion; + } + + public CloudSDKVersionEnum getCloudSDKVersion() { + return cloudSDKVersion; + } + + public static DockThingVersionEnum find(String thingVersion) { + return Arrays.stream(values()).filter(thingVersionEnum -> thingVersionEnum.thingVersion.equals(thingVersion)) + .findAny().orElseThrow(() -> new CloudSDKVersionException(thingVersion)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/DroneThingVersionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/DroneThingVersionEnum.java new file mode 100644 index 0000000..92e14ff --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/DroneThingVersionEnum.java @@ -0,0 +1,62 @@ +package org.dromara.common.sdk.config.version; + +import org.dromara.common.sdk.exception.CloudSDKVersionException; +import com.fasterxml.jackson.annotation.JsonValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public enum DroneThingVersionEnum implements IThingVersion { + + V1_0_0("1.0.0", CloudSDKVersionEnum.V0_0_1), + + V1_1_0("1.1.0", CloudSDKVersionEnum.V1_0_0), + + V1_1_2("1.1.2", CloudSDKVersionEnum.V1_0_0), + + V1_1_3("1.1.3", CloudSDKVersionEnum.V1_0_2), + + V1_2_0("1.2.0", CloudSDKVersionEnum.V1_0_3), + + V1_3_0("1.3.0", CloudSDKVersionEnum.V1_0_3), + + V1_3_1("1.3.1", CloudSDKVersionEnum.V1_3_1), + + ; + + private static final Logger log = LoggerFactory.getLogger(DroneThingVersionEnum.class); + + private final String thingVersion; + + private final CloudSDKVersionEnum cloudSDKVersion; + + DroneThingVersionEnum(String thingVersion, CloudSDKVersionEnum cloudSDKVersion) { + this.thingVersion = thingVersion; + this.cloudSDKVersion = cloudSDKVersion; + } + + @JsonValue + public String getThingVersion() { + return thingVersion; + } + + public CloudSDKVersionEnum getCloudSDKVersion() { + return cloudSDKVersion; + } + + public static DroneThingVersionEnum find(String thingVersion) { + Optional opt = Arrays.stream(values()) + .filter(thingVersionEnum -> thingVersionEnum.thingVersion.equals(thingVersion)).findAny(); + if (opt.isPresent()) { + return opt.get(); + } + throw new CloudSDKVersionException(thingVersion); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/GatewayManager.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/GatewayManager.java new file mode 100644 index 0000000..c804185 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/GatewayManager.java @@ -0,0 +1,88 @@ +package org.dromara.common.sdk.config.version; + +import org.dromara.common.sdk.annotations.CloudSDKVersion; + +import java.util.Arrays; +import java.util.Objects; + +/** + * SDK information corresponding to the gateway device + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public class GatewayManager { + + private String gatewaySn; + private GatewayThingVersion gatewayThingVersion; + private DroneThingVersionEnum droneThingVersion; + private GatewayTypeEnum type; + private CloudSDKVersionEnum sdkVersion; + private String droneSn; + + private GatewayManager(String gatewaySn, String droneSn, GatewayTypeEnum gatewayType) { + this.gatewaySn = gatewaySn; + this.type = gatewayType; + this.droneSn = droneSn; + } + + public GatewayManager(String gatewaySn, String droneSn, GatewayTypeEnum gatewayType, String gatewayThingVersion, String droneThingVersion) { + this(gatewaySn, droneSn, gatewayType); + this.gatewayThingVersion = new GatewayThingVersion(gatewayType, gatewayThingVersion); + if (GatewayTypeEnum.RC == gatewayType) { + this.sdkVersion = CloudSDKVersionEnum.V0_0_1; + return; + } + if (Objects.isNull(droneThingVersion)) { + this.sdkVersion = this.gatewayThingVersion.getCloudSDKVersion(); + return; + } + this.droneThingVersion = DroneThingVersionEnum.find(droneThingVersion); + this.sdkVersion = this.gatewayThingVersion.getCloudSDKVersion().isSupported(this.droneThingVersion.getCloudSDKVersion()) ? + this.droneThingVersion.getCloudSDKVersion() : this.gatewayThingVersion.getCloudSDKVersion(); + } + + public String getGatewaySn() { + return gatewaySn; + } + + public GatewayThingVersion getGatewayThingVersion() { + return gatewayThingVersion; + } + + public DroneThingVersionEnum getDroneThingVersion() { + return droneThingVersion; + } + + public GatewayTypeEnum getType() { + return type; + } + + public CloudSDKVersionEnum getSdkVersion() { + return sdkVersion; + } + + public String getDroneSn() { + return droneSn; + } + + public boolean isTypeSupport(CloudSDKVersion version) { + return null != version && Arrays.stream(version.exclude()).noneMatch(typeEnum -> typeEnum == this.getType()) + && (version.include().length == 0 + || Arrays.stream(version.include()).anyMatch(typeEnum -> typeEnum == this.getType())); + } + + public boolean isVersionSupport(CloudSDKVersion version) { + return null != version && this.getSdkVersion().isSupported(version.since()) && !isDeprecated(version); + } + + public boolean isDeprecated(CloudSDKVersion version) { + return null != version && this.getSdkVersion().isDeprecated(version.deprecated()); + } + + public boolean isPropertyValid(CloudSDKVersion version) { + return null == version || + (!this.getSdkVersion().isDeprecated(version.since()) + && this.getSdkVersion().isSupported(version.since())); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/GatewayThingVersion.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/GatewayThingVersion.java new file mode 100644 index 0000000..408b997 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/GatewayThingVersion.java @@ -0,0 +1,37 @@ +package org.dromara.common.sdk.config.version; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public class GatewayThingVersion { + + private IThingVersion thingVersion; + + public GatewayThingVersion(IThingVersion thingVersion) { + this.thingVersion = thingVersion; + } + + public GatewayThingVersion(GatewayTypeEnum type, String thingVersion) { + switch (type) { + case DOCK: + this.thingVersion = DockThingVersionEnum.find(thingVersion); + return; + case DOCK2: + this.thingVersion = Dock2ThingVersionEnum.find(thingVersion); + return; + case RC: + this.thingVersion = RcThingVersionEnum.find(thingVersion); + return; + } + } + + public String getThingVersion() { + return thingVersion.getThingVersion(); + } + + public CloudSDKVersionEnum getCloudSDKVersion() { + return thingVersion.getCloudSDKVersion(); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/GatewayTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/GatewayTypeEnum.java new file mode 100644 index 0000000..525c18e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/GatewayTypeEnum.java @@ -0,0 +1,36 @@ +package org.dromara.common.sdk.config.version; + +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; +import org.dromara.common.sdk.exception.CloudSDKException; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public enum GatewayTypeEnum { + + RC(DeviceEnum.RC, DeviceEnum.RC_PLUS, DeviceEnum.RC_PRO), + + DOCK(DeviceEnum.DOCK), + + DOCK2(DeviceEnum.DOCK2), + ; + + private final DeviceEnum[] gateway; + + GatewayTypeEnum(DeviceEnum... gateway) { + this.gateway = gateway; + } + + public DeviceEnum[] getGateway() { + return gateway; + } + + public static GatewayTypeEnum find(DeviceEnum device) { + return Arrays.stream(values()).filter(gateway -> Arrays.stream(gateway.gateway).anyMatch(deviceEnum -> device == deviceEnum)) + .findAny().orElseThrow(() -> new CloudSDKException(GatewayTypeEnum.class, device)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/IThingVersion.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/IThingVersion.java new file mode 100644 index 0000000..162ab13 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/IThingVersion.java @@ -0,0 +1,13 @@ +package org.dromara.common.sdk.config.version; + +/** + * @author sean + * @version 1.7 + * @date 2023/9/7 + */ +public interface IThingVersion { + + String getThingVersion(); + + CloudSDKVersionEnum getCloudSDKVersion(); +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/RcThingVersionEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/RcThingVersionEnum.java new file mode 100644 index 0000000..0f94335 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/config/version/RcThingVersionEnum.java @@ -0,0 +1,35 @@ +package org.dromara.common.sdk.config.version; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public enum RcThingVersionEnum implements IThingVersion { + + V1_0_0("1.0.0", CloudSDKVersionEnum.V0_0_1); + + private final String thingVersion; + + private final CloudSDKVersionEnum cloudSDKVersion; + + RcThingVersionEnum(String thingVersion, CloudSDKVersionEnum cloudSDKVersion) { + this.thingVersion = thingVersion; + this.cloudSDKVersion = cloudSDKVersion; + } + + @JsonValue + public String getThingVersion() { + return thingVersion; + } + + public CloudSDKVersionEnum getCloudSDKVersion() { + return cloudSDKVersion; + } + + public static RcThingVersionEnum find(String thingVersion) { + return V1_0_0; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/exception/CloudSDKErrorEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/exception/CloudSDKErrorEnum.java new file mode 100644 index 0000000..178da06 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/exception/CloudSDKErrorEnum.java @@ -0,0 +1,49 @@ +package org.dromara.common.sdk.exception; + +import org.dromara.common.sdk.common.IErrorInfo; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/23 + */ +public enum CloudSDKErrorEnum implements IErrorInfo { + + NOT_REGISTERED(210001, "设备未注册。"), + + INVALID_PARAMETER(210002, "无效参数。"), + + DEVICE_TYPE_NOT_SUPPORT(210003, "当前类型的设备不支持此功能。"), + + DEVICE_VERSION_NOT_SUPPORT(210004, "设备的当前版本不支持此功能。"), + + DEVICE_PROPERTY_NOT_SUPPORT(210005, "当前设备不支持此功能。"), + + MQTT_PUBLISH_ABNORMAL(211001, "mqtt消息发送异常。"), + + WEBSOCKET_PUBLISH_ABNORMAL(212001, "webSocket消息发送异常。"), + + WRONG_DATA(220001, "数据超出限制。"), + + UNKNOWN(299999, "sdk未知"), + ; + + private final int code; + + private final String message; + + CloudSDKErrorEnum(int code, String message) { + this.code = code; + this.message = message; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public Integer getCode() { + return code; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/exception/CloudSDKException.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/exception/CloudSDKException.java new file mode 100644 index 0000000..5b02511 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/exception/CloudSDKException.java @@ -0,0 +1,48 @@ +package org.dromara.common.sdk.exception; + +import org.dromara.common.sdk.common.IErrorInfo; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/19 + */ +public class CloudSDKException extends RuntimeException { + + private IErrorInfo errorInfo; + + public CloudSDKException(String message) { + super(message); + this.errorInfo = CloudSDKErrorEnum.UNKNOWN; + } + + public CloudSDKException(Throwable cause) { + super(cause); + this.errorInfo = CloudSDKErrorEnum.UNKNOWN; + } + + public CloudSDKException() { + this("SDK Exception"); + this.errorInfo = CloudSDKErrorEnum.UNKNOWN; + } + + public CloudSDKException(Class clazz, Object... code) { + this(clazz.getName() + " has unknown data: " + Arrays.toString(code)); + this.errorInfo = CloudSDKErrorEnum.WRONG_DATA; + } + + public CloudSDKException(IErrorInfo err) { + this(err, null); + } + + public CloudSDKException(IErrorInfo err, String msg) { + this(String.format("Error Code: %d, Error Msg: %s. %s", err.getCode(), err.getMessage(), msg)); + this.errorInfo = err; + } + + public IErrorInfo getErrorInfo() { + return errorInfo; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/exception/CloudSDKVersionException.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/exception/CloudSDKVersionException.java new file mode 100644 index 0000000..430ddfa --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/exception/CloudSDKVersionException.java @@ -0,0 +1,17 @@ +package org.dromara.common.sdk.exception; + +import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/7 + */ +public class CloudSDKVersionException extends CloudSDKException { + + public CloudSDKVersionException(String thingVersion) { + super(String.format("The current CloudSDK version(%s) does not support this thing version(%s), " + + "please replace the corresponding CloudSDK version.)", CloudSDKVersionEnum.DEFAULT.getVersion(), thingVersion)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/Chan.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/Chan.java new file mode 100644 index 0000000..f18dcee --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/Chan.java @@ -0,0 +1,59 @@ +package org.dromara.common.sdk.mqtt; + +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.LockSupport; + +/** + * The demo is only for functional closure, which is not recommended. + * @author sean.zhou + * @date 2021/11/22 + * @version 0.1 + */ +public class Chan { + + private static final ConcurrentHashMap CHANNEL = new ConcurrentHashMap<>(); + + private static final int UNIT = 1000_000; + + private volatile CommonTopicResponse data; + + private volatile Thread t; + + private Chan () { + + } + + public static Chan getInstance(String tid, boolean isNeedCreate) { + if (!isNeedCreate) { + return CHANNEL.get(tid); + } + Chan chan = new Chan(); + CHANNEL.put(tid, chan); + return chan; + } + + public CommonTopicResponse get(String tid, long timeout) { + Chan chan = CHANNEL.get(tid); + if (Objects.isNull(chan)) { + return null; + } + chan.t = Thread.currentThread(); + LockSupport.parkNanos(chan.t, timeout * UNIT); + chan.t = null; + CHANNEL.remove(tid); + return chan.data; + } + + public void put(CommonTopicResponse response) { + Chan chan = CHANNEL.get(response.getTid()); + if (Objects.isNull(chan)) { + return; + } + chan.data = response; + if (chan.t == null) { + return; + } + LockSupport.unpark(chan.t); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/ChannelName.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/ChannelName.java new file mode 100644 index 0000000..58fb96e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/ChannelName.java @@ -0,0 +1,181 @@ +package org.dromara.common.sdk.mqtt; + +/** + * The name of all channels. + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +public class ChannelName { + + public static final String INBOUND = "inbound"; + public static final String DEFAULT = "default"; + public static final String OUTBOUND = "outbound"; + + // status + public static final String INBOUND_STATUS = "inboundStatus"; + + public static final String OUTBOUND_STATUS = "outboundStatus"; + + public static final String INBOUND_STATUS_ONLINE = "inboundStatusOnline"; + + public static final String INBOUND_STATUS_OFFLINE = "inboundStatusOffline"; + + + // state + public static final String INBOUND_STATE = "inboundState"; + + public static final String INBOUND_STATE_RC_CONTROL_SOURCE = "inboundStateRcControlSource"; + + public static final String INBOUND_STATE_DOCK_DRONE_CONTROL_SOURCE = "inboundStateDockControlSource"; + + public static final String INBOUND_STATE_RC_LIVESTREAM_ABILITY_UPDATE = "inboundStateRcLiveCapacity"; + + public static final String INBOUND_STATE_DOCK_LIVESTREAM_ABILITY_UPDATE = "inboundStateDockLiveCapacity"; + + public static final String INBOUND_STATE_RC_LIVE_STATUS = "inboundStateRcLiveStatus"; + + public static final String INBOUND_STATE_DOCK_LIVE_STATUS = "inboundStateDockLiveStatus"; + + public static final String INBOUND_STATE_RC_AND_DRONE_FIRMWARE_VERSION = "inboundStateRcAndDroneFirmwareVersion"; + + public static final String INBOUND_STATE_DOCK_FIRMWARE_VERSION = "inboundStateDockFirmwareVersion"; + + public static final String INBOUND_STATE_RC_PAYLOAD_FIRMWARE = "inboundStateRcPayloadFirmware"; + + public static final String INBOUND_STATE_DOCK_DRONE_WPMZ_VERSION = "inboundStateDockDroneWpmzVersion"; + + public static final String INBOUND_STATE_DOCK_DRONE_THERMAL_SUPPORTED_PALETTE_STYLE = "inboundStateDockDronePayload"; + + public static final String INBOUND_STATE_DOCK_DRONE_RTH_MODE = "inboundStateDockDroneRthMode"; + + public static final String INBOUND_STATE_DOCK_DRONE_CURRENT_RTH_MODE = "inboundStateDockDroneCurrentRthMode"; + + public static final String INBOUND_STATE_DOCK_DRONE_COMMANDER_MODE_LOST_ACTION = "inboundStateDockDroneCommanderModeLostAction"; + + public static final String INBOUND_STATE_DOCK_DRONE_CURRENT_COMMANDER_FLIGHT_MODE = "inboundStateDockDroneCurrentCommanderFlightMode"; + + public static final String INBOUND_STATE_DOCK_DRONE_COMMANDER_FLIGHT_HEIGHT = "inboundStateDockDroneCommanderFlightHeight"; + + public static final String INBOUND_STATE_DOCK_DRONE_MODE_CODE_REASON = "inboundStateDockDroneModeCodeReason"; + + public static final String INBOUND_STATE_DOCK_DRONE_OFFLINE_MAP_ENABLE = "inboundStateDockDroneOfflineMapEnable"; + + public static final String INBOUND_STATE_DOCK_AND_DRONE_DONGLE_INFOS = "inboundStateDockAndDroneDongleInfos"; + + public static final String INBOUND_STATE_DOCK_SILENT_MODE = "inboundStateDockSilentMode"; + + + public static final String OUTBOUND_STATE = "outboundState"; + + + // services_reply + public static final String INBOUND_SERVICES_REPLY = "inboundServicesReply"; + + + // osd + public static final String INBOUND_OSD = "inboundOsd"; + + public static final String INBOUND_OSD_RC = "inboundOsdRc"; + + public static final String INBOUND_OSD_DOCK = "inboundOsdDock"; + + public static final String INBOUND_OSD_RC_DRONE = "inboundOsdRcDrone"; + + public static final String INBOUND_OSD_DOCK_DRONE = "inboundOsdDockDrone"; + + + // requests + public static final String INBOUND_REQUESTS = "inboundRequests"; + + public static final String INBOUND_REQUESTS_STORAGE_CONFIG_GET = "inboundRequestsStorageConfigGet"; + + public static final String INBOUND_REQUESTS_AIRPORT_BIND_STATUS = "inboundRequestsAirportBindStatus"; + + public static final String INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET = "inboundRequestsAirportOrganizationGet"; + + public static final String INBOUND_REQUESTS_AIRPORT_ORGANIZATION_BIND = "inboundRequestsAirportOrganizationBind"; + + public static final String INBOUND_REQUESTS_CONFIG = "inboundRequestsConfig"; + + public static final String INBOUND_REQUESTS_FLIGHTTASK_RESOURCE_GET = "inboundRequestsFlightTaskResourceGet"; + + public static final String INBOUND_REQUESTS_FLIGHT_AREAS_GET = "inboundRequestsFlightAreasGet"; + + public static final String INBOUND_REQUESTS_OFFLINE_MAP_GET = "inboundRequestsOfflineMapGet"; + + + public static final String OUTBOUND_REQUESTS = "outboundRequests"; + + + // events + public static final String INBOUND_EVENTS = "inboundEvents"; + + public static final String OUTBOUND_EVENTS = "outboundEvents"; + + public static final String INBOUND_EVENTS_DEVICE_EXIT_HOMING_NOTIFY = "inboundEventsDeviceExitHomingNotify"; + + public static final String INBOUND_EVENTS_FLIGHTTASK_PROGRESS = "inboundEventsFlighttaskProgress"; + + public static final String INBOUND_EVENTS_FLIGHTTASK_READY = "inboundEventsFlighttaskReady"; + + public static final String INBOUND_EVENTS_FILE_UPLOAD_CALLBACK = "inboundEventsFileUploadCallback"; + + public static final String INBOUND_EVENTS_HMS = "inboundEventsHms"; + + public static final String INBOUND_EVENTS_CONTROL_PROGRESS = "inboundEventsControlProgress"; + + public static final String INBOUND_EVENTS_OTA_PROGRESS = "inboundEventsOtaProgress"; + + public static final String INBOUND_EVENTS_FILEUPLOAD_PROGRESS = "inboundEventsFileUploadProgress"; + + public static final String INBOUND_EVENTS_FLY_TO_POINT_PROGRESS = "inboundEventsFlyToPointProgress"; + + public static final String INBOUND_EVENTS_TAKEOFF_TO_POINT_PROGRESS = "inboundEventsTakeoffToPointProgress"; + + public static final String INBOUND_EVENTS_DRC_STATUS_NOTIFY = "inboundEventsDrcStatusNotify"; + + public static final String INBOUND_EVENTS_JOYSTICK_INVALID_NOTIFY = "inboundEventsJoystickInvalidNotify"; + + public static final String INBOUND_EVENTS_HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA = "inboundEventsHighestPriorityUploadFlightTaskMedia"; + + public static final String INBOUND_EVENTS_RETURN_HOME_INFO = "inboundEventsReturnHomeInfo"; + + public static final String INBOUND_EVENTS_CUSTOM_DATA_TRANSMISSION_FROM_ESDK = "inboundEventsCustomDataTransmissionFromEsdk"; + + public static final String INBOUND_EVENTS_CUSTOM_DATA_TRANSMISSION_FROM_PSDK = "inboundEventsCustomDataTransmissionFromPsdk"; + + public static final String INBOUND_EVENTS_AIRSENSE_WARNING = "inboundEventsAirsenseWarning"; + + public static final String INBOUND_EVENTS_FLIGHT_AREAS_SYNC_PROGRESS = "inboundEventsFlightAreasSyncProgress"; + + public static final String INBOUND_EVENTS_FLIGHT_AREAS_DRONE_LOCATION = "inboundEventsFlightAreasDroneLocation"; + + public static final String INBOUND_EVENTS_OFFLINE_MAP_SYNC_PROGRESS = "inboundEventsOfflineMapSyncProgress"; + + public static final String INBOUND_EVENTS_POI_STATUS_NOTIFY = "inboundEventsPoiStatusNotify"; + + public static final String INBOUND_EVENTS_CAMERA_PHOTO_TAKE_PROGRESS = "inboundEventsCameraPhotoTakeProgress"; + + + // property + public static final String INBOUND_PROPERTY_SET_REPLY = "inboundPropertySetReply"; + + + // drc/up + public static final String INBOUND_DRC_UP = "inboundDrcUp"; + + public static final String INBOUND_DRC_UP_DRONE_CONTROL = "inboundDrcUpDroneControl"; + + public static final String INBOUND_DRC_UP_DRONE_EMERGENCY_STOP = "inboundDrcUpDroneEmergencyStop"; + + public static final String INBOUND_DRC_UP_HEART_BEAT = "inboundDrcUpHeartBeat"; + + public static final String INBOUND_DRC_UP_HSI_INFO_PUSH = "inboundDrcUpHsiInfoPush"; + + public static final String INBOUND_DRC_UP_DELAY_INFO_PUSH = "inboundDrcUpDelayInfoPush"; + + public static final String INBOUND_DRC_UP_OSD_INFO_PUSH = "inboundDrcUpOsdInfoPush"; + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/CloudApiTopicEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/CloudApiTopicEnum.java new file mode 100644 index 0000000..631a994 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/CloudApiTopicEnum.java @@ -0,0 +1,53 @@ +package org.dromara.common.sdk.mqtt; + +import java.util.Arrays; +import java.util.regex.Pattern; + +import static org.dromara.common.sdk.mqtt.TopicConst.*; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/28 + */ +public enum CloudApiTopicEnum { + + STATUS(Pattern.compile("^" + BASIC_PRE + PRODUCT + REGEX_SN + STATUS_SUF + "$"), ChannelName.INBOUND_STATUS), + + STATE(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + STATE_SUF + "$"), ChannelName.INBOUND_STATE), + + SERVICE_REPLY(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + SERVICES_SUF + _REPLY_SUF + "$"), ChannelName.INBOUND_SERVICES_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), + + DRC_UP(Pattern.compile("^" + THING_MODEL_PRE + PRODUCT + REGEX_SN + DRC + UP + "$"), ChannelName.INBOUND_DRC_UP), + + UNKNOWN(Pattern.compile("^.*$"), ChannelName.DEFAULT); + + private final Pattern pattern; + + private final String beanName; + + CloudApiTopicEnum(Pattern pattern, String beanName) { + this.pattern = pattern; + this.beanName = beanName; + } + + public Pattern getPattern() { + return pattern; + } + + public String getBeanName() { + return beanName; + } + + public static CloudApiTopicEnum find(String topic) { + return Arrays.stream(CloudApiTopicEnum.values()).filter(topicEnum -> topicEnum.pattern.matcher(topic).matches()).findAny().orElse(UNKNOWN); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/CommonTopicRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/CommonTopicRequest.java new file mode 100644 index 0000000..bdeb30e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/CommonTopicRequest.java @@ -0,0 +1,71 @@ +package org.dromara.common.sdk.mqtt; + +/** + * Unified topic request format. + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +public class CommonTopicRequest { + + /** + * The command is sent and the response is matched by the tid and bid fields in the message, + * and the reply should keep the tid and bid the same. + */ + protected String tid; + + protected String bid; + + protected Long timestamp; + + protected T data; + + public CommonTopicRequest() { + } + + @Override + public String toString() { + return "CommonTopicRequest{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getTid() { + return tid; + } + + public CommonTopicRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public CommonTopicRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public CommonTopicRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public CommonTopicRequest setData(T data) { + this.data = data; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/CommonTopicResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/CommonTopicResponse.java new file mode 100644 index 0000000..79ef756 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/CommonTopicResponse.java @@ -0,0 +1,71 @@ +package org.dromara.common.sdk.mqtt; + +/** + * Unified Topic response format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class CommonTopicResponse { + + /** + * The command is sent and the response is matched by the tid and bid fields in the message, + * and the reply should keep the tid and bid the same. + */ + protected String tid; + + protected String bid; + + protected T data; + + protected Long timestamp; + + @Override + public String toString() { + return "CommonTopicResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public CommonTopicResponse() { + } + + public String getTid() { + return tid; + } + + public CommonTopicResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public CommonTopicResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public T getData() { + return data; + } + + public CommonTopicResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public CommonTopicResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/IMqttMessageGateway.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/IMqttMessageGateway.java new file mode 100644 index 0000000..d2651a3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/IMqttMessageGateway.java @@ -0,0 +1,32 @@ +package org.dromara.common.sdk.mqtt; + +import org.springframework.integration.annotation.MessagingGateway; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.stereotype.Component; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +@MessagingGateway(defaultRequestChannel = ChannelName.OUTBOUND) +public interface IMqttMessageGateway { + + /** + * Publish a message to a specific topic. + * @param topic target + * @param payload message + */ + void publish(@Header(MqttHeaders.TOPIC) String topic, byte[] payload); + + /** + * Use a specific qos to push messages to a specific topic. + * @param topic target + * @param payload message + * @param qos qos + */ + void publish(@Header(MqttHeaders.TOPIC) String topic, byte[] payload, @Header(MqttHeaders.QOS) int qos); +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/IMqttTopicService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/IMqttTopicService.java new file mode 100644 index 0000000..7fd44cf --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/IMqttTopicService.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.mqtt; + +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.handler.annotation.Header; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +public interface IMqttTopicService { + + /** + * Subscribe to a specific topic. + * @param topics target + */ + void subscribe(@Header(MqttHeaders.TOPIC) String... topics); + + /** + * Subscribe to a specific topic using a specific qos. + * @param topic target + * @param qos qos + */ + void subscribe(@Header(MqttHeaders.TOPIC) String topic, int qos); + + /** + * Unsubscribe from a specific topic. + * @param topics target + */ + void unsubscribe(@Header(MqttHeaders.TOPIC) String... topics); + + /** + * Get all the subscribed topics. + * @return topics + */ + String[] getSubscribedTopic(); +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/InboundMessageRouter.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/InboundMessageRouter.java new file mode 100644 index 0000000..a520319 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/InboundMessageRouter.java @@ -0,0 +1,47 @@ +package org.dromara.common.sdk.mqtt; + +import org.dromara.common.sdk.common.SpringBeanUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.integration.annotation.Router; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.integration.router.AbstractMessageRouter; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Collections; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class InboundMessageRouter extends AbstractMessageRouter { + + private static final Logger log = LoggerFactory.getLogger(InboundMessageRouter.class); + + /** + * All mqtt broker messages will arrive here before distributing them to different channels. + * @param message message from mqtt broker + * @return channel + */ + @Override + @Router(inputChannel = ChannelName.INBOUND) + protected Collection determineTargetChannels(Message message) { + MessageHeaders headers = message.getHeaders(); + String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString(); + byte[] payload = (byte[])message.getPayload(); + + log.debug("received topic: {} \t payload =>{}", topic, new String(payload)); + + CloudApiTopicEnum topicEnum = CloudApiTopicEnum.find(topic); + MessageChannel bean = (MessageChannel) SpringBeanUtils.getBean(topicEnum.getBeanName()); + + return Collections.singleton(bean); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttConfiguration.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttConfiguration.java new file mode 100644 index 0000000..4612480 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttConfiguration.java @@ -0,0 +1,93 @@ +package org.dromara.common.sdk.mqtt; + +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.annotation.IntegrationComponentScan; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.integration.mqtt.core.MqttPahoClientFactory; +import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter; +import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler; +import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.MessageHandler; + +import java.util.UUID; + +/** + * Client configuration for inbound messages. + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Configuration +@IntegrationComponentScan +public class MqttConfiguration { + + private static final Logger log = LoggerFactory.getLogger(MqttConfiguration.class); + + @Value("${cloud-sdk.mqtt.inbound-topic: }") + private String inboundTopic; + + @Resource + private MqttPahoClientFactory mqttClientFactory; + + @Resource(name = ChannelName.INBOUND) + private MessageChannel inboundChannel; + + /** + * Clients of inbound message channels. + * @return + */ + @Bean + public MqttPahoMessageDrivenChannelAdapter mqttInbound() { + MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter( + UUID.randomUUID().toString(), mqttClientFactory, inboundTopic.split(",")); + DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter(); + // use byte types uniformly + converter.setPayloadAsBytes(true); + adapter.setConverter(converter); + adapter.setQos(1); + adapter.setOutputChannel(inboundChannel); + return adapter; + } + + /** + * Clients of outbound message channels. + * @return + */ + @Bean + @ServiceActivator(inputChannel = ChannelName.OUTBOUND) + public MessageHandler mqttOutbound() { + MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler( + UUID.randomUUID().toString(), mqttClientFactory); + DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter(); + // use byte types uniformly + converter.setPayloadAsBytes(true); + + messageHandler.setAsync(true); + messageHandler.setDefaultQos(0); + messageHandler.setConverter(converter); + return messageHandler; + } + + + + /** + * Define a default channel to handle messages that have no effect. + * @return + */ + @Bean + @ServiceActivator(inputChannel = ChannelName.DEFAULT) + public MessageHandler defaultInboundHandler() { + return message -> { + log.info("The default channel does not handle messages." + + "\nTopic: " + message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC) + + "\nPayload: " + message.getPayload() + "\n"); + }; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttGatewayPublish.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttGatewayPublish.java new file mode 100644 index 0000000..794a636 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttGatewayPublish.java @@ -0,0 +1,105 @@ +package org.dromara.common.sdk.mqtt; + +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.core.JsonProcessingException; +import jakarta.annotation.Resource; +import lombok.extern.log4j.Log4j; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.TypeMismatchException; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author sean.zhou + * @date 2021/11/16 + * @version 0.1 + */ +@Component +@Slf4j +public class MqttGatewayPublish { + + + private static final int DEFAULT_QOS = 0; + public static final int DEFAULT_RETRY_COUNT = 2; + public static final int DEFAULT_RETRY_TIMEOUT = 3000; + + @Resource + private IMqttMessageGateway messageGateway; + + public void publish(String topic, int qos, CommonTopicRequest request) { + try { + log.debug("send topic: {}, payload: {}", topic, request.toString()); + byte[] payload = Common.getObjectMapper().writeValueAsBytes(request); + messageGateway.publish(topic, payload, qos); + } catch (JsonProcessingException e) { + log.error("Failed to publish the message. {}", request.toString()); + e.printStackTrace(); + } + } + + public void publish(String topic, int qos, CommonTopicResponse response) { + try { + log.debug("send topic: {}, payload: {}", topic, response.toString()); + byte[] payload = Common.getObjectMapper().writeValueAsBytes(response); + messageGateway.publish(topic, payload, qos); + } catch (JsonProcessingException e) { + log.error("Failed to publish the message. {}", response.toString()); + e.printStackTrace(); + } + } + + public void publish(String topic, CommonTopicRequest request, int publishCount) { + AtomicInteger time = new AtomicInteger(0); + while (time.getAndIncrement() < publishCount) { + this.publish(topic, DEFAULT_QOS, request); + } + } + + public void publish(String topic, CommonTopicRequest request) { + this.publish(topic, DEFAULT_QOS, request); + } + + public void publishReply(CommonTopicResponse response, MessageHeaders headers) { + this.publish(headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF, 2, response); + } + + public CommonTopicResponse publishWithReply(Class clazz, String topic, CommonTopicRequest request, int retryCount, long timeout) { + AtomicInteger time = new AtomicInteger(0); + boolean hasBid = StringUtils.hasText(request.getBid()); + request.setBid(hasBid ? request.getBid() : UUID.randomUUID().toString()); + // Retry + while (time.getAndIncrement() <= retryCount) { + this.publish(topic, request); + + // If the message is not received in 3 seconds then resend it again. + CommonTopicResponse receiver = Chan.getInstance(request.getTid(), true).get(request.getTid(), timeout); + // Need to match tid and bid. + if (Objects.nonNull(receiver) + && receiver.getTid().equals(request.getTid()) + && receiver.getBid().equals(request.getBid())) { + if (clazz.isAssignableFrom(receiver.getData().getClass())) { + return receiver; + } + throw new TypeMismatchException(receiver.getData(), clazz); + } + // It must be guaranteed that the tid and bid of each message are different. + if (!hasBid) { + request.setBid(UUID.randomUUID().toString()); + } + request.setTid(UUID.randomUUID().toString()); + } + throw new CloudSDKException(CloudSDKErrorEnum.MQTT_PUBLISH_ABNORMAL, "No message reply received."); + } + + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttReply.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttReply.java new file mode 100644 index 0000000..a71342e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttReply.java @@ -0,0 +1,73 @@ +package org.dromara.common.sdk.mqtt; + +import org.dromara.common.sdk.common.IErrorInfo; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/13 + */ +public class MqttReply { + + public static final int CODE_ERROR = -1; + + public static final int CODE_SUCCESS = 0; + + private Integer result; + + private T output; + + private MqttReply() { + } + + @Override + public String toString() { + return "MqttReply{" + + "result=" + result + + ", output=" + output + + '}'; + } + + private MqttReply(T output) { + this.output = output; + } + + private MqttReply(Integer result, T output) { + this.result = result; + this.output = output; + } + + public static MqttReply error(IErrorInfo errorInfo) { + return new MqttReply(errorInfo.getCode(), errorInfo.getMessage()); + } + + public static MqttReply error(String message) { + return new MqttReply(CODE_ERROR, message); + } + + public static MqttReply success(T data) { + return new MqttReply(CODE_SUCCESS, data); + } + + public static MqttReply success() { + return new MqttReply().setResult(CODE_SUCCESS); + } + + public Integer getResult() { + return result; + } + + public MqttReply setResult(Integer result) { + this.result = result; + return this; + } + + public MqttReply setOutput(T output) { + this.output = output; + return this; + } + + public T getOutput() { + return output; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttReplyHandler.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttReplyHandler.java new file mode 100644 index 0000000..0ba579f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttReplyHandler.java @@ -0,0 +1,68 @@ +package org.dromara.common.sdk.mqtt; + +import org.dromara.common.sdk.common.BaseModel; +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.mqtt.events.TopicEventsRequest; +import org.dromara.common.sdk.mqtt.events.TopicEventsResponse; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsRequest; +import org.dromara.common.sdk.mqtt.requests.TopicRequestsResponse; +import org.dromara.common.sdk.mqtt.state.TopicStateRequest; +import org.dromara.common.sdk.mqtt.state.TopicStateResponse; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/22 + */ +@Aspect +@Component +public class MqttReplyHandler { + + @AfterReturning(value = "execution(public org.dromara.common.sdk.mqtt.CommonTopicResponse+ org.dromara.common.sdk.cloudapi.*.api.*.*(org.dromara.common.sdk.mqtt.CommonTopicRequest+, org.springframework.messaging.MessageHeaders))", returning = "result") + public Object validateReturnValue(JoinPoint point, CommonTopicResponse result) { + if (Objects.isNull(result)) { + return null; + } + CommonTopicRequest request = (CommonTopicRequest) point.getArgs()[0]; + result.setBid(request.getBid()).setTid(request.getTid()).setTimestamp(System.currentTimeMillis()); + if (result instanceof TopicEventsResponse) { + fillEvents((TopicEventsResponse) result, (TopicEventsRequest) request); + } else if (result instanceof TopicRequestsResponse) { + validateRequests((TopicRequestsResponse) result, (TopicRequestsRequest) request); + } else if (result instanceof TopicStateResponse) { + fillState((TopicStateResponse) result, (TopicStateRequest) request); + } + return result; + } + + private void fillEvents(TopicEventsResponse response, TopicEventsRequest request) { + if (!request.isNeedReply()) { + response.setData(null); + return; + } + response.setMethod(request.getMethod()).setData(MqttReply.success()); + } + + private void validateRequests(TopicRequestsResponse response, TopicRequestsRequest request) { + response.setMethod(request.getMethod()); + Object data = response.getData(); + if (data instanceof MqttReply) { + MqttReply mqttData = (MqttReply) data; + if (MqttReply.CODE_SUCCESS != mqttData.getResult()) { + return; + } + data = mqttData.getOutput(); + } + Common.validateModel((BaseModel) data); + } + + private void fillState(TopicStateResponse response, TopicStateRequest request) { + response.setData(request.isNeedReply() ? MqttReply.success() : null); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttTopicServiceImpl.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttTopicServiceImpl.java new file mode 100644 index 0000000..56f89ec --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/MqttTopicServiceImpl.java @@ -0,0 +1,57 @@ +package org.dromara.common.sdk.mqtt; + +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class MqttTopicServiceImpl implements IMqttTopicService { + + private static final Logger log = LoggerFactory.getLogger(MqttTopicServiceImpl.class); + + @Resource + private MqttPahoMessageDrivenChannelAdapter adapter; + + @Override + public void subscribe(String... topics) { + Set topicSet = new HashSet<>(Arrays.asList(getSubscribedTopic())); + for (String topic : topics) { + if (topicSet.contains(topic)) { + return; + } + subscribe(topic, 1); + } + } + + @Override + public void subscribe(String topic, int qos) { + Set topicSet = new HashSet<>(Arrays.asList(getSubscribedTopic())); + if (topicSet.contains(topic)) { + return; + } + log.debug("subscribe topic: {}", topic); + adapter.addTopic(topic, qos); + } + + @Override + public void unsubscribe(String... topics) { + log.debug("unsubscribe topic: {}", Arrays.toString(topics)); + adapter.removeTopic(topics); + } + + public String[] getSubscribedTopic() { + return adapter.getTopic(); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/TopicConst.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/TopicConst.java new file mode 100644 index 0000000..d2ff422 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/TopicConst.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.mqtt; + +/** + * All the topics that need to be used in the project. + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +public class TopicConst { + + public static final String BASIC_PRE = "sys/"; + + public static final String THING_MODEL_PRE = "thing/"; + + public static final String PRODUCT = "product/"; + + public static final String STATUS_SUF = "/status"; + + public static final String _REPLY_SUF = "_reply"; + + public static final String STATE_SUF = "/state"; + + public static final String SERVICES_SUF = "/services"; + + public static final String OSD_SUF = "/osd"; + + public static final String REQUESTS_SUF = "/requests"; + + 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]+"; + + public static final String DRC = "/drc"; + + public static final String UP = "/up"; + + public static final String DOWN = "/down"; +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcDownPublish.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcDownPublish.java new file mode 100644 index 0000000..d5eecd6 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcDownPublish.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.mqtt.drc; + +import org.dromara.common.sdk.mqtt.MqttGatewayPublish; +import org.dromara.common.sdk.mqtt.TopicConst; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class DrcDownPublish { + + @Resource + private MqttGatewayPublish gatewayPublish; + + public static final int DEFAULT_PUBLISH_COUNT = 5; + + public void publish(String sn, String method) { + this.publish(sn, method, null); + } + + public void publish(String sn, String method, Object data) { + this.publish(sn, method, data, DEFAULT_PUBLISH_COUNT); + } + + public void publish(String sn, String method, Object data, int publishCount) { + String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(sn) + TopicConst.DRC + TopicConst.DOWN; + gatewayPublish.publish(topic, + new TopicDrcRequest<>() + .setMethod(method) + .setData(Objects.requireNonNullElse(data, "")), + publishCount); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpData.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpData.java new file mode 100644 index 0000000..cd53852 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpData.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.mqtt.drc; + +import org.dromara.common.sdk.cloudapi.wayline.WaylineErrorCodeEnum; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/22 + */ +public class DrcUpData { + + private WaylineErrorCodeEnum result; + + private T output; + + public DrcUpData() { + } + + @Override + public String toString() { + return "DrcUpData{" + + "result=" + result + + ", output=" + output + + '}'; + } + + public WaylineErrorCodeEnum getResult() { + return result; + } + + public DrcUpData setResult(WaylineErrorCodeEnum result) { + this.result = result; + return this; + } + + public T getOutput() { + return output; + } + + public DrcUpData setOutput(T output) { + this.output = output; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpMethodEnum.java new file mode 100644 index 0000000..bff3f08 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpMethodEnum.java @@ -0,0 +1,59 @@ +package org.dromara.common.sdk.mqtt.drc; + +import org.dromara.common.sdk.cloudapi.control.*; +import org.dromara.common.sdk.mqtt.ChannelName; +import com.fasterxml.jackson.core.type.TypeReference; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +public enum DrcUpMethodEnum { + + DRONE_CONTROL("drone_control", ChannelName.INBOUND_DRC_UP_DRONE_CONTROL, new TypeReference>() {}), + + DRONE_EMERGENCY_STOP("drone_emergency_stop", ChannelName.INBOUND_DRC_UP_DRONE_EMERGENCY_STOP, new TypeReference() {}), + + HEART_BEAT("heart_beat", ChannelName.INBOUND_DRC_UP_HEART_BEAT, new TypeReference() {}), + + HSI_INFO_PUSH("hsi_info_push", ChannelName.INBOUND_DRC_UP_HSI_INFO_PUSH, new TypeReference() {}), + + DELAY_INFO_PUSH("delay_info_push", ChannelName.INBOUND_DRC_UP_DELAY_INFO_PUSH, new TypeReference() {}), + + OSD_INFO_PUSH("osd_info_push", ChannelName.INBOUND_DRC_UP_OSD_INFO_PUSH, new TypeReference() {}), + + UNKNOWN("", ChannelName.DEFAULT, new TypeReference<>() {}); + + private final String method; + + private final String channelName; + + private final TypeReference classType; + + DrcUpMethodEnum(String method, String channelName, TypeReference classType) { + this.method = method; + this.channelName = channelName; + this.classType = classType; + } + + public String getMethod() { + return method; + } + + public String getChannelName() { + return channelName; + } + + public TypeReference getClassType() { + return classType; + } + + public static DrcUpMethodEnum find(String method) { + return Arrays.stream(DrcUpMethodEnum.values()) + .filter(methodEnum -> methodEnum.method.equals(method)) + .findAny().orElse(UNKNOWN); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpRouter.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpRouter.java new file mode 100644 index 0000000..c598736 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpRouter.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.mqtt.drc; + +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.messaging.Message; + +import java.io.IOException; +import java.util.Arrays; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Configuration +public class DrcUpRouter { + + @Bean + public IntegrationFlow drcUpRouterFlow() { + return IntegrationFlow + .from(ChannelName.INBOUND_DRC_UP) + .transform(Message.class, source -> { + try { + TopicDrcRequest data = Common.getObjectMapper().readValue((byte[]) source.getPayload(), TopicDrcRequest.class); + return data.setData(Common.getObjectMapper().convertValue(data.getData(), DrcUpMethodEnum.find(data.getMethod()).getClassType())); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }) + .route( + response -> DrcUpMethodEnum.find(response.getMethod()), + mapping -> Arrays.stream(DrcUpMethodEnum.values()).forEach( + methodEnum -> mapping.channelMapping(methodEnum, methodEnum.getChannelName()))) + .get(); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpSubscribe.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpSubscribe.java new file mode 100644 index 0000000..59eb18f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/DrcUpSubscribe.java @@ -0,0 +1,26 @@ +package org.dromara.common.sdk.mqtt.drc; + +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.mqtt.IMqttTopicService; +import org.dromara.common.sdk.mqtt.TopicConst; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class DrcUpSubscribe { + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway) { + String drc = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.DRC + TopicConst.UP; + topicService.subscribe(String.format(drc, gateway.getGatewaySn())); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/TopicDrcRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/TopicDrcRequest.java new file mode 100644 index 0000000..802a717 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/TopicDrcRequest.java @@ -0,0 +1,73 @@ +package org.dromara.common.sdk.mqtt.drc; + +import org.dromara.common.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicDrcRequest extends CommonTopicRequest { + + private String method; + + public TopicDrcRequest() { + } + + @Override + public String toString() { + return "TopicDrcRequest{" + + "method='" + method + '\'' + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getMethod() { + return method; + } + + public TopicDrcRequest setMethod(String method) { + this.method = method; + return this; + } + + public String getTid() { + return tid; + } + + public TopicDrcRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicDrcRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicDrcRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicDrcRequest setData(T data) { + this.data = data; + return this; + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/TopicDrcResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/TopicDrcResponse.java new file mode 100644 index 0000000..2e4f93f --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/drc/TopicDrcResponse.java @@ -0,0 +1,73 @@ +package org.dromara.common.sdk.mqtt.drc; + +import org.dromara.common.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicDrcResponse extends CommonTopicResponse { + + private String method; + + @Override + public String toString() { + return "TopicDrcResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", method='" + method + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicDrcResponse() { + } + + public String getTid() { + return tid; + } + + public TopicDrcResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicDrcResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public String getMethod() { + return method; + } + + public TopicDrcResponse setMethod(String method) { + this.method = method; + return this; + } + + public T getData() { + return data; + } + + public TopicDrcResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicDrcResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsDataRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsDataRequest.java new file mode 100644 index 0000000..c412ef2 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsDataRequest.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.mqtt.events; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +public class EventsDataRequest { + + private EventsErrorCode result; + + private T output; + + public EventsDataRequest() { + } + + @Override + public String toString() { + return "EventsDataRequest{" + + "result=" + result + + ", output=" + output + + '}'; + } + + public EventsErrorCode getResult() { + return result; + } + + public EventsDataRequest setResult(EventsErrorCode result) { + this.result = result; + return this; + } + + public T getOutput() { + return output; + } + + public EventsDataRequest setOutput(T output) { + this.output = output; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsErrorCode.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsErrorCode.java new file mode 100644 index 0000000..009cf6d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsErrorCode.java @@ -0,0 +1,89 @@ +package org.dromara.common.sdk.mqtt.events; + +import org.dromara.common.sdk.cloudapi.control.ControlErrorCodeEnum; +import org.dromara.common.sdk.cloudapi.debug.DebugErrorCodeEnum; +import org.dromara.common.sdk.cloudapi.firmware.FirmwareErrorCodeEnum; +import org.dromara.common.sdk.cloudapi.log.LogErrorCodeEnum; +import org.dromara.common.sdk.cloudapi.wayline.WaylineErrorCodeEnum; +import org.dromara.common.sdk.common.CommonErrorEnum; +import org.dromara.common.sdk.common.ErrorCodeSourceEnum; +import org.dromara.common.sdk.common.IErrorInfo; +import org.dromara.common.sdk.mqtt.MqttReply; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/14 + */ +public class EventsErrorCode implements IErrorInfo { + + private static final int MOD = 100_000; + + private ErrorCodeSourceEnum source; + + private IEventsErrorCode errorCode; + + private boolean success; + + private Integer sourceCode; + + @Override + public String toString() { + return "{" + + "errorCode=" + getCode() + + ", errorMsg=" + getMessage() + + '}'; + } + + @JsonCreator + public EventsErrorCode(int code) { + this.sourceCode = code; + if (MqttReply.CODE_SUCCESS == code) { + this.success = true; + this.errorCode = CommonErrorEnum.SUCCESS; + return; + } + this.source = ErrorCodeSourceEnum.find(code / MOD); + this.errorCode = DebugErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = ControlErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = LogErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = FirmwareErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = WaylineErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = CommonErrorEnum.find(code); + } + + @Override + public String getMessage() { + return errorCode.getMessage(); + } + + @JsonValue + public Integer getCode() { + return sourceCode; + } + + public boolean isSuccess() { + return success; + } + + public ErrorCodeSourceEnum getSource() { + return source; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsMethodEnum.java new file mode 100644 index 0000000..8d85540 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsMethodEnum.java @@ -0,0 +1,132 @@ +package org.dromara.common.sdk.mqtt.events; + +import org.dromara.common.sdk.cloudapi.airsense.AirsenseWarning; +import org.dromara.common.sdk.cloudapi.control.*; +import org.dromara.common.sdk.cloudapi.debug.RemoteDebugProgress; +import org.dromara.common.sdk.cloudapi.firmware.OtaProgress; +import org.dromara.common.sdk.cloudapi.flightarea.FlightAreasDroneLocation; +import org.dromara.common.sdk.cloudapi.flightarea.FlightAreasSyncProgress; +import org.dromara.common.sdk.cloudapi.hms.Hms; +import org.dromara.common.sdk.cloudapi.interconnection.CustomDataTransmissionFromEsdk; +import org.dromara.common.sdk.cloudapi.interconnection.CustomDataTransmissionFromPsdk; +import org.dromara.common.sdk.cloudapi.log.FileUploadProgress; +import org.dromara.common.sdk.cloudapi.map.OfflineMapSyncProgress; +import org.dromara.common.sdk.cloudapi.media.FileUploadCallback; +import org.dromara.common.sdk.cloudapi.media.HighestPriorityUploadFlightTaskMedia; +import org.dromara.common.sdk.cloudapi.wayline.DeviceExitHomingNotify; +import org.dromara.common.sdk.cloudapi.wayline.FlighttaskProgress; +import org.dromara.common.sdk.cloudapi.wayline.FlighttaskReady; +import org.dromara.common.sdk.cloudapi.wayline.ReturnHomeInfo; +import org.dromara.common.sdk.mqtt.ChannelName; +import com.fasterxml.jackson.core.type.TypeReference; + +import java.util.Arrays; +import java.util.List; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +public enum EventsMethodEnum { + + FLIGHTTASK_PROGRESS("flighttask_progress", ChannelName.INBOUND_EVENTS_FLIGHTTASK_PROGRESS, new TypeReference>() {}), + + DEVICE_EXIT_HOMING_NOTIFY("device_exit_homing_notify", ChannelName.INBOUND_EVENTS_DEVICE_EXIT_HOMING_NOTIFY, new TypeReference() {}), + + FILE_UPLOAD_CALLBACK("file_upload_callback", ChannelName.INBOUND_EVENTS_FILE_UPLOAD_CALLBACK, new TypeReference() {}), + + HMS("hms", ChannelName.INBOUND_EVENTS_HMS, new TypeReference() {}), + + DEVICE_REBOOT("device_reboot", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + DRONE_OPEN("drone_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + DRONE_CLOSE("drone_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + DRONE_FORMAT("drone_format", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + DEVICE_FORMAT("device_format", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + COVER_OPEN("cover_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + COVER_CLOSE("cover_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + PUTTER_OPEN("putter_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + PUTTER_CLOSE("putter_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + CHARGE_OPEN("charge_open", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + CHARGE_CLOSE("charge_close", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + ESIM_ACTIVATE("esim_activate", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + ESIM_OPERATOR_SWITCH("esim_operator_switch", ChannelName.INBOUND_EVENTS_CONTROL_PROGRESS, new TypeReference>() {}), + + OTA_PROGRESS("ota_progress", ChannelName.INBOUND_EVENTS_OTA_PROGRESS, new TypeReference>() {}), + + FILE_UPLOAD_PROGRESS("fileupload_progress", ChannelName.INBOUND_EVENTS_FILEUPLOAD_PROGRESS, new TypeReference>() {}), + + HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA("highest_priority_upload_flighttask_media", ChannelName.INBOUND_EVENTS_HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA, new TypeReference() {}), + + FLIGHT_TASK_READY("flighttask_ready", ChannelName.INBOUND_EVENTS_FLIGHTTASK_READY, new TypeReference() {}), + + FLY_TO_POINT_PROGRESS("fly_to_point_progress", ChannelName.INBOUND_EVENTS_FLY_TO_POINT_PROGRESS, new TypeReference() {}), + + TAKE_OFF_TO_POINT_PROGRESS("takeoff_to_point_progress", ChannelName.INBOUND_EVENTS_TAKEOFF_TO_POINT_PROGRESS, new TypeReference() {}), + + DRC_STATUS_NOTIFY("drc_status_notify", ChannelName.INBOUND_EVENTS_DRC_STATUS_NOTIFY, new TypeReference() {}), + + JOYSTICK_INVALID_NOTIFY("joystick_invalid_notify", ChannelName.INBOUND_EVENTS_JOYSTICK_INVALID_NOTIFY, new TypeReference() {}), + + RETURN_HOME_INFO("return_home_info", ChannelName.INBOUND_EVENTS_RETURN_HOME_INFO, new TypeReference() {}), + + CUSTOM_DATA_TRANSMISSION_FROM_ESDK("custom_data_transmission_from_esdk", ChannelName.INBOUND_EVENTS_CUSTOM_DATA_TRANSMISSION_FROM_ESDK, new TypeReference() {}), + + CUSTOM_DATA_TRANSMISSION_FROM_PSDK("custom_data_transmission_from_psdk", ChannelName.INBOUND_EVENTS_CUSTOM_DATA_TRANSMISSION_FROM_PSDK, new TypeReference() {}), + + AIRSENSE_WARNING("airsense_warning", ChannelName.INBOUND_EVENTS_AIRSENSE_WARNING, new TypeReference>() {}), + + FLIGHT_AREAS_SYNC_PROGRESS("flight_areas_sync_progress", ChannelName.INBOUND_EVENTS_FLIGHT_AREAS_SYNC_PROGRESS, new TypeReference() {}), + + FLIGHT_AREAS_DRONE_LOCATION("flight_areas_drone_location", ChannelName.INBOUND_EVENTS_FLIGHT_AREAS_DRONE_LOCATION, new TypeReference() {}), + + OFFLINE_MAP_SYNC_PROGRESS("offline_map_sync_progress", ChannelName.INBOUND_EVENTS_OFFLINE_MAP_SYNC_PROGRESS, new TypeReference() {}), + + POI_STATUS_NOTIFY("poi_status_notify", ChannelName.INBOUND_EVENTS_POI_STATUS_NOTIFY, new TypeReference() {}), + + CAMERA_PHOTO_TAKE_PROGRESS("camera_photo_take_progress", ChannelName.INBOUND_EVENTS_CAMERA_PHOTO_TAKE_PROGRESS, new TypeReference>() {}), + + UNKNOWN("", ChannelName.DEFAULT, new TypeReference<>() {}); + + private final String method; + + private final String channelName; + + private final TypeReference classType; + + EventsMethodEnum(String method, String channelName, TypeReference classType) { + this.method = method; + this.channelName = channelName; + this.classType = classType; + } + + public String getMethod() { + return method; + } + + public String getChannelName() { + return channelName; + } + + public TypeReference getClassType() { + return classType; + } + + public static EventsMethodEnum find(String method) { + return Arrays.stream(EventsMethodEnum.values()) + .filter(methodEnum -> methodEnum.method.equals(method)) + .findAny().orElse(UNKNOWN); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsRouter.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsRouter.java new file mode 100644 index 0000000..76a37fb --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsRouter.java @@ -0,0 +1,70 @@ +package org.dromara.common.sdk.mqtt.events; + +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttGatewayPublish; +import jakarta.annotation.Resource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Objects; + +import static org.dromara.common.sdk.mqtt.TopicConst.*; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Configuration +public class EventsRouter { + + @Resource + private MqttGatewayPublish gatewayPublish; + + @Bean + public IntegrationFlow eventsMethodRouterFlow() { + return IntegrationFlow + .from(ChannelName.INBOUND_EVENTS) + .transform(Message.class, source -> { + try { + TopicEventsRequest data = Common.getObjectMapper().readValue((byte[]) source.getPayload(), TopicEventsRequest.class); + String topic = String.valueOf(source.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)); + return data.setFrom(topic.substring((THING_MODEL_PRE + PRODUCT).length(), topic.indexOf(EVENTS_SUF))) + .setData(Common.getObjectMapper().convertValue(data.getData(), EventsMethodEnum.find(data.getMethod()).getClassType())); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }) + .route( + response -> EventsMethodEnum.find(response.getMethod()), + mapping -> Arrays.stream(EventsMethodEnum.values()).forEach( + methodEnum -> mapping.channelMapping(methodEnum, methodEnum.getChannelName()))) + .get(); + } + + @Bean + public IntegrationFlow replySuccessEvents() { + return IntegrationFlow + .from(ChannelName.OUTBOUND_EVENTS) + .handle(this::publish) + .nullChannel(); + + } + + private TopicEventsResponse publish(TopicEventsResponse request, MessageHeaders headers) { + if (Objects.isNull(request) || Objects.isNull(request.getData())) { + return null; + } + gatewayPublish.publishReply(request, headers); + return request; + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsSubscribe.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsSubscribe.java new file mode 100644 index 0000000..e3e33c0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/EventsSubscribe.java @@ -0,0 +1,41 @@ +package org.dromara.common.sdk.mqtt.events; + +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.mqtt.IMqttTopicService; +import org.dromara.common.sdk.mqtt.TopicConst; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class EventsSubscribe { + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.EVENTS_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway, boolean unsubscribeSubDevice) { + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (unsubscribeSubDevice) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + return; + } + if (null != gateway.getDroneSn()) { + topicService.subscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } + + public void unsubscribe(GatewayManager gateway) { + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (null != gateway.getDroneSn()) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/IEventsErrorCode.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/IEventsErrorCode.java new file mode 100644 index 0000000..55da322 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/IEventsErrorCode.java @@ -0,0 +1,22 @@ +package org.dromara.common.sdk.mqtt.events; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public interface IEventsErrorCode { + + /** + * Get error message. + * @return error message + */ + String getMessage(); + + /** + * Get error code. + * @return error code + */ + Integer getCode(); + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/TopicEventsRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/TopicEventsRequest.java new file mode 100644 index 0000000..d29044e --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/TopicEventsRequest.java @@ -0,0 +1,108 @@ +package org.dromara.common.sdk.mqtt.events; + +import org.dromara.common.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicEventsRequest extends CommonTopicRequest { + + private String method; + + private String gateway; + + private String from; + + private boolean needReply; + + public TopicEventsRequest() { + } + + @Override + public String toString() { + return "TopicRequestsRequest{" + + "method='" + method + '\'' + + ", gateway='" + gateway + '\'' + + ", from='" + from + '\'' + + ", needReply=" + needReply + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getTid() { + return tid; + } + + public TopicEventsRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicEventsRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicEventsRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicEventsRequest setData(T data) { + this.data = data; + return this; + } + + public String getGateway() { + return gateway; + } + + public TopicEventsRequest setGateway(String gateway) { + this.gateway = gateway; + return this; + } + + public String getFrom() { + return from; + } + + public TopicEventsRequest setFrom(String from) { + this.from = from; + return this; + } + + public boolean isNeedReply() { + return needReply; + } + + public TopicEventsRequest setNeedReply(boolean needReply) { + this.needReply = needReply; + return this; + } + + public String getMethod() { + return method; + } + + public TopicEventsRequest setMethod(String method) { + this.method = method; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/TopicEventsResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/TopicEventsResponse.java new file mode 100644 index 0000000..97fdbaa --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/events/TopicEventsResponse.java @@ -0,0 +1,73 @@ +package org.dromara.common.sdk.mqtt.events; + +import org.dromara.common.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicEventsResponse extends CommonTopicResponse { + + private String method; + + @Override + public String toString() { + return "TopicEventsResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", method='" + method + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicEventsResponse() { + } + + public String getTid() { + return tid; + } + + public TopicEventsResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicEventsResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public String getMethod() { + return method; + } + + public TopicEventsResponse setMethod(String method) { + this.method = method; + return this; + } + + public T getData() { + return data; + } + + public TopicEventsResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicEventsResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/OsdDeviceTypeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/OsdDeviceTypeEnum.java new file mode 100644 index 0000000..8ee2bb3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/OsdDeviceTypeEnum.java @@ -0,0 +1,71 @@ +package org.dromara.common.sdk.mqtt.osd; + +import org.dromara.common.sdk.cloudapi.device.OsdDock; +import org.dromara.common.sdk.cloudapi.device.OsdDockDrone; +import org.dromara.common.sdk.cloudapi.device.OsdRcDrone; +import org.dromara.common.sdk.cloudapi.device.OsdRemoteControl; +import org.dromara.common.sdk.config.version.GatewayTypeEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.dromara.common.sdk.mqtt.ChannelName; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/29 + */ +public enum OsdDeviceTypeEnum { + + RC(true, OsdRemoteControl.class, ChannelName.INBOUND_OSD_RC, GatewayTypeEnum.RC), + + DOCK(true, OsdDock.class, ChannelName.INBOUND_OSD_DOCK, GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2), + + RC_DRONE(false, OsdRcDrone.class, ChannelName.INBOUND_OSD_RC_DRONE, GatewayTypeEnum.RC), + + DOCK_DRONE(false, OsdDockDrone.class, ChannelName.INBOUND_OSD_DOCK_DRONE, GatewayTypeEnum.DOCK, GatewayTypeEnum.DOCK2); + + private final boolean gateway; + + private final Set gatewayType = new HashSet<>(); + + private final Class classType; + + private final String channelName; + + OsdDeviceTypeEnum(boolean gateway, Class classType, String channelName, GatewayTypeEnum... gatewayType) { + this.gateway = gateway; + this.classType = classType; + this.channelName = channelName; + Collections.addAll(this.gatewayType, gatewayType); + } + + public Set getGatewayType() { + return gatewayType; + } + + public boolean isGateway() { + return gateway; + } + + public Class getClassType() { + return classType; + } + + public String getChannelName() { + return channelName; + } + + public static OsdDeviceTypeEnum find(GatewayTypeEnum gatewayType, boolean isGateway) { + return Arrays.stream(values()).filter(osdEnum -> osdEnum.gatewayType.contains(gatewayType) && osdEnum.gateway == isGateway).findAny() + .orElseThrow(() -> new CloudSDKException(OsdDeviceTypeEnum.class, gatewayType, isGateway)); + } + + public static OsdDeviceTypeEnum find(Class classType) { + return Arrays.stream(values()).filter(type -> type.classType == classType).findAny() + .orElseThrow(() -> new CloudSDKException(OsdDeviceTypeEnum.class, classType)); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/OsdRouter.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/OsdRouter.java new file mode 100644 index 0000000..04666cd --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/OsdRouter.java @@ -0,0 +1,63 @@ +package org.dromara.common.sdk.mqtt.osd; + +import org.dromara.common.sdk.cloudapi.device.PayloadModelConst; +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.common.SDKManager; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.dromara.common.sdk.mqtt.ChannelName; +import com.fasterxml.jackson.core.type.TypeReference; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.Message; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static org.dromara.common.sdk.mqtt.TopicConst.*; + +/** + * + * @author sean.zhou + * @date 2021/11/17 + * @version 0.1 + */ +@Configuration +public class OsdRouter { + + @Bean + public IntegrationFlow osdRouterFlow() { + return IntegrationFlow + .from(ChannelName.INBOUND_OSD) + .transform(Message.class, source -> { + try { + TopicOsdRequest response = Common.getObjectMapper().readValue((byte[]) source.getPayload(), new TypeReference() {}); + String topic = String.valueOf(source.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)); + return response.setFrom(topic.substring((THING_MODEL_PRE + PRODUCT).length(), topic.indexOf(OSD_SUF))); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }) + .handle((response, headers) -> { + GatewayManager gateway = SDKManager.getDeviceSDK(response.getGateway()); + OsdDeviceTypeEnum typeEnum = OsdDeviceTypeEnum.find(gateway.getType(), response.getFrom().equals(response.getGateway())); + Map data = (Map) response.getData(); + if (!typeEnum.isGateway()) { + List payloadData = (List) data.getOrDefault(PayloadModelConst.PAYLOAD_KEY, new ArrayList<>()); + PayloadModelConst.getAllIndexWithPosition().stream().filter(data::containsKey) + .map(data::get).forEach(payloadData::add); + data.put(PayloadModelConst.PAYLOAD_KEY, payloadData); + } + return response.setData(Common.getObjectMapper().convertValue(data, typeEnum.getClassType())); + }) + .route(response -> OsdDeviceTypeEnum.find(response.getData().getClass()), + mapping -> Arrays.stream(OsdDeviceTypeEnum.values()).forEach(key -> mapping.channelMapping(key, key.getChannelName()))) + .get(); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/OsdSubscribe.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/OsdSubscribe.java new file mode 100644 index 0000000..5101779 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/OsdSubscribe.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.mqtt.osd; + +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.common.SDKManager; +import org.dromara.common.sdk.mqtt.IMqttTopicService; +import org.dromara.common.sdk.mqtt.TopicConst; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class OsdSubscribe { + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.OSD_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway, boolean unsubscribeSubDevice) { + SDKManager.registerDevice(gateway); + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (unsubscribeSubDevice) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + return; + } + if (null != gateway.getDroneSn()) { + topicService.subscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } + + public void unsubscribe(GatewayManager gateway) { + SDKManager.logoutDevice(gateway.getGatewaySn()); + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (null != gateway.getDroneSn()) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/TopicOsdRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/TopicOsdRequest.java new file mode 100644 index 0000000..47c53f3 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/osd/TopicOsdRequest.java @@ -0,0 +1,83 @@ +package org.dromara.common.sdk.mqtt.osd; + +import org.dromara.common.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicOsdRequest extends CommonTopicRequest { + + private String gateway; + + private String from; + + public TopicOsdRequest() { + } + + @Override + public String toString() { + return "TopicOsdRequest{" + + "gateway='" + gateway + '\'' + + ", from='" + from + '\'' + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + public String getTid() { + return tid; + } + + public TopicOsdRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicOsdRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicOsdRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicOsdRequest setData(T data) { + this.data = data; + return this; + } + + public String getGateway() { + return gateway; + } + + public TopicOsdRequest setGateway(String gateway) { + this.gateway = gateway; + return this; + } + + public String getFrom() { + return from; + } + + public TopicOsdRequest setFrom(String from) { + this.from = from; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetPublish.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetPublish.java new file mode 100644 index 0000000..b4299fc --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetPublish.java @@ -0,0 +1,40 @@ +package org.dromara.common.sdk.mqtt.property; + +import org.dromara.common.sdk.mqtt.MqttGatewayPublish; +import org.dromara.common.sdk.mqtt.TopicConst; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.util.Objects; +import java.util.UUID; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class PropertySetPublish { + + @Resource + private MqttGatewayPublish gatewayPublish; + + public PropertySetReplyResultEnum publish(String sn, Object data) { + return this.publish(sn, data, MqttGatewayPublish.DEFAULT_RETRY_COUNT); + } + + public PropertySetReplyResultEnum publish(String sn, Object data, int retryCount) { + return this.publish(sn, data, retryCount, MqttGatewayPublish.DEFAULT_RETRY_TIMEOUT); + } + + public PropertySetReplyResultEnum publish(String sn, Object data, int retryCount, long timeout) { + String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(sn) + TopicConst.PROPERTY_SUF + TopicConst.SET_SUF; + return gatewayPublish.publishWithReply( + PropertySetReplyResultEnum.class, topic, new TopicPropertySetRequest<>() + .setTid(UUID.randomUUID().toString()) + .setBid(null) + .setTimestamp(System.currentTimeMillis()) + .setData(Objects.requireNonNull(data)), retryCount, timeout).getData(); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetReplyHandler.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetReplyHandler.java new file mode 100644 index 0000000..759963d --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetReplyHandler.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.mqtt.property; + +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.mqtt.Chan; +import org.dromara.common.sdk.mqtt.ChannelName; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.Objects; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +@Component +public class PropertySetReplyHandler { + + private static final String RESULT_KEY = "result"; + + /** + * Handle the reply message from topic "/property/set_reply". + * @param message reply message + * @throws IOException + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_PROPERTY_SET_REPLY) + public void propertySetReply(Message message) throws IOException { + byte[] payload = (byte[])message.getPayload(); + + TopicPropertySetResponse receiver = Common.getObjectMapper().readValue(payload, new TypeReference() {}); + Chan chan = Chan.getInstance(receiver.getTid(), false); + if (Objects.isNull(chan)) { + return; + } + receiver.setData(PropertySetReplyResultEnum.find( + Common.getObjectMapper().convertValue(receiver.getData(), JsonNode.class).findValue(RESULT_KEY).intValue())); + // Put the message to the chan object. + chan.put(receiver); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetReplyResultEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetReplyResultEnum.java new file mode 100644 index 0000000..61f7658 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetReplyResultEnum.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.mqtt.property; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/28 + */ +public enum PropertySetReplyResultEnum { + + SUCCESS(0), + + FAILED(1), + + TIMEOUT(2), + + UNKNOWN(-1); + + private final int result; + + PropertySetReplyResultEnum(int result) { + this.result = result; + } + + @JsonValue + public int getResult() { + return result; + } + + @JsonCreator + public static PropertySetReplyResultEnum find(int result) { + return Arrays.stream(values()).filter(resultEnum -> resultEnum.result == result).findAny().orElse(UNKNOWN); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetSubscribe.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetSubscribe.java new file mode 100644 index 0000000..017adc5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/PropertySetSubscribe.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.mqtt.property; + +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.mqtt.IMqttTopicService; +import org.dromara.common.sdk.mqtt.TopicConst; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class PropertySetSubscribe { + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.PROPERTY_SUF + TopicConst.SET_SUF + TopicConst._REPLY_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway) { + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + + public void unsubscribe(GatewayManager gateway) { + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/TopicPropertySetRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/TopicPropertySetRequest.java new file mode 100644 index 0000000..514d2dd --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/TopicPropertySetRequest.java @@ -0,0 +1,61 @@ +package org.dromara.common.sdk.mqtt.property; + +import org.dromara.common.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicPropertySetRequest extends CommonTopicRequest { + + public TopicPropertySetRequest() { + } + + @Override + public String toString() { + return "TopicPropertySetRequest{" + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getTid() { + return tid; + } + + public TopicPropertySetRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicPropertySetRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicPropertySetRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicPropertySetRequest setData(T data) { + this.data = data; + return this; + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/TopicPropertySetResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/TopicPropertySetResponse.java new file mode 100644 index 0000000..db79951 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/property/TopicPropertySetResponse.java @@ -0,0 +1,61 @@ +package org.dromara.common.sdk.mqtt.property; + +import org.dromara.common.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicPropertySetResponse extends CommonTopicResponse { + + @Override + public String toString() { + return "TopicPropertySetResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicPropertySetResponse() { + } + + public String getTid() { + return tid; + } + + public TopicPropertySetResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicPropertySetResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public T getData() { + return data; + } + + public TopicPropertySetResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicPropertySetResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/RequestsMethodEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/RequestsMethodEnum.java new file mode 100644 index 0000000..c2909bc --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/RequestsMethodEnum.java @@ -0,0 +1,69 @@ +package org.dromara.common.sdk.mqtt.requests; + +import org.dromara.common.sdk.cloudapi.config.RequestsConfigRequest; +import org.dromara.common.sdk.cloudapi.flightarea.FlightAreasGetRequest; +import org.dromara.common.sdk.cloudapi.map.OfflineMapGetRequest; +import org.dromara.common.sdk.cloudapi.media.StorageConfigGet; +import org.dromara.common.sdk.cloudapi.organization.AirportBindStatusRequest; +import org.dromara.common.sdk.cloudapi.organization.AirportOrganizationBindRequest; +import org.dromara.common.sdk.cloudapi.organization.AirportOrganizationGetRequest; +import org.dromara.common.sdk.cloudapi.wayline.FlighttaskResourceGetRequest; +import org.dromara.common.sdk.mqtt.ChannelName; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/25 + */ +public enum RequestsMethodEnum { + + STORAGE_CONFIG_GET("storage_config_get", ChannelName.INBOUND_REQUESTS_STORAGE_CONFIG_GET, StorageConfigGet.class), + + AIRPORT_BIND_STATUS("airport_bind_status", ChannelName.INBOUND_REQUESTS_AIRPORT_BIND_STATUS, AirportBindStatusRequest.class), + + AIRPORT_ORGANIZATION_BIND("airport_organization_bind", ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_BIND, AirportOrganizationBindRequest.class), + + AIRPORT_ORGANIZATION_GET("airport_organization_get", ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET, AirportOrganizationGetRequest.class), + + FLIGHT_TASK_RESOURCE_GET("flighttask_resource_get", ChannelName.INBOUND_REQUESTS_FLIGHTTASK_RESOURCE_GET, FlighttaskResourceGetRequest.class), + + CONFIG("config", ChannelName.INBOUND_REQUESTS_CONFIG, RequestsConfigRequest.class), + + FLIGHT_AREAS_GET("flight_areas_get", ChannelName.INBOUND_REQUESTS_FLIGHT_AREAS_GET, FlightAreasGetRequest.class), + + OFFLINE_MAP_GET("offline_map_get", ChannelName.INBOUND_REQUESTS_OFFLINE_MAP_GET, OfflineMapGetRequest.class), + + UNKNOWN("", ChannelName.DEFAULT, Object.class); + + private final String method; + + private final String channelName; + + private final Class classType; + + RequestsMethodEnum(String method, String channelName, Class classType) { + this.method = method; + this.channelName = channelName; + this.classType = classType; + } + + public String getMethod() { + return method; + } + + public String getChannelName() { + return channelName; + } + + public Class getClassType() { + return classType; + } + + public static RequestsMethodEnum find(String method) { + return Arrays.stream(RequestsMethodEnum.values()) + .filter(methodEnum -> methodEnum.method.equals(method)) + .findAny().orElse(UNKNOWN); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/RequestsRouter.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/RequestsRouter.java new file mode 100644 index 0000000..dc6c944 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/RequestsRouter.java @@ -0,0 +1,63 @@ +package org.dromara.common.sdk.mqtt.requests; + +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttGatewayPublish; +import jakarta.annotation.Resource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.messaging.MessageHeaders; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Objects; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/25 + */ +@Configuration +public class RequestsRouter { + + @Resource + private MqttGatewayPublish gatewayPublish; + + @Bean + public IntegrationFlow requestsMethodRouterFlow() { + return IntegrationFlow + .from(ChannelName.INBOUND_REQUESTS) + .transform(payload -> { + try { + TopicRequestsRequest response = Common.getObjectMapper().readValue(payload, TopicRequestsRequest.class); + return response.setData(Common.getObjectMapper().convertValue(response.getData(), RequestsMethodEnum.find(response.getMethod()).getClassType())); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }) + .route( + receiver -> RequestsMethodEnum.find(receiver.getMethod()), + mapping -> Arrays.stream(RequestsMethodEnum.values()).forEach( + methodEnum -> mapping.channelMapping(methodEnum, methodEnum.getChannelName()))) + .get(); + } + + @Bean + public IntegrationFlow replyRequestsMethod() { + return IntegrationFlow + .from(ChannelName.OUTBOUND_REQUESTS) + .handle(this::publish) + .nullChannel(); + } + + private TopicRequestsResponse publish(TopicRequestsResponse request, MessageHeaders headers) { + if (Objects.isNull(request)) { + throw new CloudSDKException(CloudSDKErrorEnum.INVALID_PARAMETER, "The return value cannot be null."); + } + gatewayPublish.publishReply(request, headers); + return request; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/RequestsSubscribe.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/RequestsSubscribe.java new file mode 100644 index 0000000..018c2c1 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/RequestsSubscribe.java @@ -0,0 +1,34 @@ +package org.dromara.common.sdk.mqtt.requests; + +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.mqtt.IMqttTopicService; +import org.dromara.common.sdk.mqtt.TopicConst; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class RequestsSubscribe { + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.REQUESTS_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway) { + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + + public void unsubscribe(GatewayManager gateway) { + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + + public void subscribeWildcardsRequests() { + topicService.subscribe(TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "+" + TopicConst.REQUESTS_SUF); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/TopicRequestsRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/TopicRequestsRequest.java new file mode 100644 index 0000000..eb851f5 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/TopicRequestsRequest.java @@ -0,0 +1,84 @@ +package org.dromara.common.sdk.mqtt.requests; + +import org.dromara.common.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicRequestsRequest extends CommonTopicRequest { + + private String method; + + private String gateway; + + public TopicRequestsRequest() { + } + + @Override + public String toString() { + return "TopicRequestsRequest{" + + "method='" + method + '\'' + + ", gateway='" + gateway + '\'' + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getTid() { + return tid; + } + + public TopicRequestsRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicRequestsRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicRequestsRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicRequestsRequest setData(T data) { + this.data = data; + return this; + } + + public String getGateway() { + return gateway; + } + + public TopicRequestsRequest setGateway(String gateway) { + this.gateway = gateway; + return this; + } + + public String getMethod() { + return method; + } + + public TopicRequestsRequest setMethod(String method) { + this.method = method; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/TopicRequestsResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/TopicRequestsResponse.java new file mode 100644 index 0000000..bc85f1c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/requests/TopicRequestsResponse.java @@ -0,0 +1,73 @@ +package org.dromara.common.sdk.mqtt.requests; + +import org.dromara.common.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicRequestsResponse extends CommonTopicResponse { + + private String method; + + @Override + public String toString() { + return "TopicRequestsResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", method='" + method + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicRequestsResponse() { + } + + public String getTid() { + return tid; + } + + public TopicRequestsResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicRequestsResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public String getMethod() { + return method; + } + + public TopicRequestsResponse setMethod(String method) { + this.method = method; + return this; + } + + public T getData() { + return data; + } + + public TopicRequestsResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicRequestsResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/IServicesErrorCode.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/IServicesErrorCode.java new file mode 100644 index 0000000..489f4a9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/IServicesErrorCode.java @@ -0,0 +1,22 @@ +package org.dromara.common.sdk.mqtt.services; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public interface IServicesErrorCode { + + /** + * Get error message. + * @return error message + */ + String getMessage(); + + /** + * Get error code. + * @return error code + */ + Integer getCode(); + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesErrorCode.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesErrorCode.java new file mode 100644 index 0000000..a174cb0 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesErrorCode.java @@ -0,0 +1,94 @@ +package org.dromara.common.sdk.mqtt.services; + +import org.dromara.common.sdk.cloudapi.control.ControlErrorCodeEnum; +import org.dromara.common.sdk.cloudapi.debug.DebugErrorCodeEnum; +import org.dromara.common.sdk.cloudapi.firmware.FirmwareErrorCodeEnum; +import org.dromara.common.sdk.cloudapi.livestream.LiveErrorCodeEnum; +import org.dromara.common.sdk.cloudapi.log.LogErrorCodeEnum; +import org.dromara.common.sdk.cloudapi.wayline.WaylineErrorCodeEnum; +import org.dromara.common.sdk.common.CommonErrorEnum; +import org.dromara.common.sdk.common.ErrorCodeSourceEnum; +import org.dromara.common.sdk.common.IErrorInfo; +import org.dromara.common.sdk.mqtt.MqttReply; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/14 + */ +public class ServicesErrorCode implements IErrorInfo { + + private static final int MOD = 100_000; + + private ErrorCodeSourceEnum source; + + private IServicesErrorCode errorCode; + + private boolean success; + + private Integer sourceCode; + + @Override + public String toString() { + return "{" + + "errorCode=" + getCode() + + ", errorMsg=" + getMessage() + + '}'; + } + + @JsonCreator + public ServicesErrorCode(int code) { + this.sourceCode = code; + if (MqttReply.CODE_SUCCESS == code) { + this.success = true; + this.errorCode = CommonErrorEnum.SUCCESS; + return; + } + this.source = ErrorCodeSourceEnum.find(code / MOD); + this.errorCode = LiveErrorCodeEnum.find(code % MOD); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = DebugErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = ControlErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = LogErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = FirmwareErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = WaylineErrorCodeEnum.find(code); + if (errorCode.getCode() != -1) { + return; + } + this.errorCode = CommonErrorEnum.find(code); + } + + @Override + public String getMessage() { + return errorCode.getMessage(); + } + + @JsonValue + public Integer getCode() { + return sourceCode; + } + + public boolean isSuccess() { + return success; + } + + public ErrorCodeSourceEnum getSource() { + return source; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesPublish.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesPublish.java new file mode 100644 index 0000000..f0c9b21 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesPublish.java @@ -0,0 +1,109 @@ +package org.dromara.common.sdk.mqtt.services; + +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.mqtt.MqttGatewayPublish; +import org.dromara.common.sdk.mqtt.TopicConst; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.util.Objects; +import java.util.UUID; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class ServicesPublish { + + @Resource + private MqttGatewayPublish gatewayPublish; + + public TopicServicesResponse> publish(TypeReference clazz, String sn, String method) { + return this.publish(clazz, sn, method, null); + } + + public TopicServicesResponse> publish(TypeReference clazz, String sn, String method, Object data) { + return this.publish(clazz, sn, method, data, MqttGatewayPublish.DEFAULT_RETRY_COUNT); + } + + public TopicServicesResponse> publish(TypeReference clazz, String sn, String method, Object data, int retryCount) { + return this.publish(clazz, sn, method, data, retryCount, MqttGatewayPublish.DEFAULT_RETRY_TIMEOUT); + } + + public TopicServicesResponse> publish(TypeReference clazz, String sn, String method, Object data, long timeout) { + return this.publish(clazz, sn, method, data, MqttGatewayPublish.DEFAULT_RETRY_COUNT, timeout); + } + + public TopicServicesResponse> publish(TypeReference clazz, String sn, String method, Object data, int retryCount, long timeout) { + return this.publish(clazz, sn, method, data, null, retryCount, timeout); + } + + public TopicServicesResponse publish(String sn, String method) { + return this.publish(sn, method, null, null); + } + + public TopicServicesResponse publish(String sn, String method, Object data) { + return this.publish(sn, method, data, null); + } + + public TopicServicesResponse publish(String sn, String method, Object data, int retryCount) { + return this.publish(sn, method, data, null, retryCount); + } + + public TopicServicesResponse publish(String sn, String method, Object data, long timeout) { + return this.publish(sn, method, data, null, timeout); + } + + public TopicServicesResponse publish(String sn, String method, Object data, int retryCount, long timeout) { + return this.publish(sn, method, data, null, retryCount, timeout); + } + + public TopicServicesResponse publish(String sn, String method, Object data, String bid) { + return this.publish(sn, method, data, bid, MqttGatewayPublish.DEFAULT_RETRY_COUNT); + } + + public TopicServicesResponse publish(String sn, String method, Object data, String bid, int retryCount) { + return this.publish(sn, method, data, bid, retryCount, MqttGatewayPublish.DEFAULT_RETRY_TIMEOUT); + } + + public TopicServicesResponse publish(String sn, String method, Object data, String bid, long timeout) { + return this.publish(sn, method, data, bid, MqttGatewayPublish.DEFAULT_RETRY_COUNT, timeout); + } + + public TopicServicesResponse publish(String sn, String method, Object data, String bid, int retryCount, long timeout) { + return (TopicServicesResponse) this.publish(null, sn, method, data, bid, retryCount, timeout); + } + + public TopicServicesResponse> publish( + TypeReference clazz, String sn, String method, Object data, String bid, int retryCount, long timeout) { + String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(sn) + TopicConst.SERVICES_SUF; + TopicServicesResponse response = (TopicServicesResponse) gatewayPublish.publishWithReply( + ServicesReplyReceiver.class, topic, new TopicServicesRequest<>() + .setTid(UUID.randomUUID().toString()) + .setBid(bid) + .setTimestamp(System.currentTimeMillis()) + .setMethod(method) + .setData(Objects.requireNonNullElse(data, "")), retryCount, timeout); + ServicesReplyReceiver replyReceiver = (ServicesReplyReceiver) response.getData(); + ServicesReplyData reply = new ServicesReplyData().setResult(replyReceiver.getResult()); + if (Objects.isNull(clazz)) { + reply.setOutput((T) Objects.requireNonNullElse( + replyReceiver.getOutput(), Objects.requireNonNullElse(replyReceiver.getInfo(), ""))); + return response.setData(reply); + } + // put together in "output" + ObjectMapper mapper = Common.getObjectMapper(); + if (Objects.nonNull(replyReceiver.getInfo())) { + reply.setOutput(mapper.convertValue(replyReceiver.getInfo(), clazz)); + } + if (Objects.nonNull(replyReceiver.getOutput())) { + reply.setOutput(mapper.convertValue(replyReceiver.getOutput(), clazz)); + } + return response.setData(reply); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesReplyData.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesReplyData.java new file mode 100644 index 0000000..da60406 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesReplyData.java @@ -0,0 +1,42 @@ +package org.dromara.common.sdk.mqtt.services; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/22 + */ +public class ServicesReplyData { + + private ServicesErrorCode result; + + private T output; + + public ServicesReplyData() { + } + + @Override + public String toString() { + return "DrcUpData{" + + "result=" + result + + ", output=" + output + + '}'; + } + + public ServicesErrorCode getResult() { + return result; + } + + public ServicesReplyData setResult(ServicesErrorCode result) { + this.result = result; + return this; + } + + public T getOutput() { + return output; + } + + public ServicesReplyData setOutput(T output) { + this.output = output; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesReplyHandler.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesReplyHandler.java new file mode 100644 index 0000000..ccd0b7a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesReplyHandler.java @@ -0,0 +1,45 @@ +package org.dromara.common.sdk.mqtt.services; + +import org.dromara.common.sdk.cloudapi.log.FileUploadListResponse; +import org.dromara.common.sdk.cloudapi.log.LogMethodEnum; +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.mqtt.Chan; +import org.dromara.common.sdk.mqtt.ChannelName; +import com.fasterxml.jackson.core.type.TypeReference; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.Objects; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +@Component +public class ServicesReplyHandler { + + /** + * Handle the reply message from topic "/services_reply". + * @param message reply message + * @throws IOException + */ + @ServiceActivator(inputChannel = ChannelName.INBOUND_SERVICES_REPLY) + public void servicesReply(Message message) throws IOException { + byte[] payload = (byte[])message.getPayload(); + + TopicServicesResponse receiver = Common.getObjectMapper() + .readValue(payload, new TypeReference>() {}); + Chan chan = Chan.getInstance(receiver.getTid(), false); + if (Objects.isNull(chan)) { + return; + } + if (LogMethodEnum.FILE_UPLOAD_LIST.getMethod().equals(receiver.getMethod())) { + receiver.getData().setOutput(Common.getObjectMapper().convertValue(receiver.getData(), + new TypeReference() {})); + } + chan.put(receiver); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesReplyReceiver.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesReplyReceiver.java new file mode 100644 index 0000000..34cad9c --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesReplyReceiver.java @@ -0,0 +1,66 @@ +package org.dromara.common.sdk.mqtt.services; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/22 + */ +public class ServicesReplyReceiver { + + private ServicesErrorCode result; + + private T info; + + private T output; + + private T files; + + public ServicesReplyReceiver() { + } + + @Override + public String toString() { + return "ServicesReplyReceiver{" + + "result=" + result + + ", info=" + info + + ", output=" + output + + ", files=" + files + + '}'; + } + + public ServicesErrorCode getResult() { + return result; + } + + public ServicesReplyReceiver setResult(ServicesErrorCode result) { + this.result = result; + return this; + } + + public T getInfo() { + return info; + } + + public ServicesReplyReceiver setInfo(T info) { + this.info = info; + return this; + } + + public T getOutput() { + return output; + } + + public ServicesReplyReceiver setOutput(T output) { + this.output = output; + return this; + } + + public T getFiles() { + return files; + } + + public ServicesReplyReceiver setFiles(T files) { + this.files = files; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesSubscribe.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesSubscribe.java new file mode 100644 index 0000000..9397bb1 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/ServicesSubscribe.java @@ -0,0 +1,30 @@ +package org.dromara.common.sdk.mqtt.services; + +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.mqtt.IMqttTopicService; +import org.dromara.common.sdk.mqtt.TopicConst; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +@Component +public class ServicesSubscribe { + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.SERVICES_SUF + TopicConst._REPLY_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway) { + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + + public void unsubscribe(GatewayManager gateway) { + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/TopicServicesRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/TopicServicesRequest.java new file mode 100644 index 0000000..2497a63 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/TopicServicesRequest.java @@ -0,0 +1,73 @@ +package org.dromara.common.sdk.mqtt.services; + +import org.dromara.common.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicServicesRequest extends CommonTopicRequest { + + private String method; + + public TopicServicesRequest() { + } + + @Override + public String toString() { + return "TopicServicesRequest{" + + "method='" + method + '\'' + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getMethod() { + return method; + } + + public TopicServicesRequest setMethod(String method) { + this.method = method; + return this; + } + + public String getTid() { + return tid; + } + + public TopicServicesRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicServicesRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicServicesRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicServicesRequest setData(T data) { + this.data = data; + return this; + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/TopicServicesResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/TopicServicesResponse.java new file mode 100644 index 0000000..5610707 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/services/TopicServicesResponse.java @@ -0,0 +1,73 @@ +package org.dromara.common.sdk.mqtt.services; + +import org.dromara.common.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicServicesResponse extends CommonTopicResponse { + + private String method; + + @Override + public String toString() { + return "TopicServicesResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", method='" + method + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicServicesResponse() { + } + + public String getTid() { + return tid; + } + + public TopicServicesResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicServicesResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public String getMethod() { + return method; + } + + public TopicServicesResponse setMethod(String method) { + this.method = method; + return this; + } + + public T getData() { + return data; + } + + public TopicServicesResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicServicesResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/DockStateDataKeyEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/DockStateDataKeyEnum.java new file mode 100644 index 0000000..9dadfd9 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/DockStateDataKeyEnum.java @@ -0,0 +1,78 @@ +package org.dromara.common.sdk.mqtt.state; + +import org.dromara.common.sdk.cloudapi.device.*; +import org.dromara.common.sdk.cloudapi.livestream.DockLivestreamAbilityUpdate; +import org.dromara.common.sdk.cloudapi.property.DockDroneCommanderFlightHeight; +import org.dromara.common.sdk.cloudapi.property.DockDroneCommanderModeLostAction; +import org.dromara.common.sdk.cloudapi.property.DockDroneOfflineMapEnable; +import org.dromara.common.sdk.cloudapi.property.DockDroneRthMode; +import org.dromara.common.sdk.exception.CloudSDKException; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; + +/** + * + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public enum DockStateDataKeyEnum { + + FIRMWARE_VERSION(Set.of("firmware_version"), DockFirmwareVersion.class), + + LIVE_CAPACITY(Set.of("live_capacity"), DockLivestreamAbilityUpdate.class), + + CONTROL_SOURCE(Set.of("control_source"), DockDroneControlSource.class), + + LIVE_STATUS(Set.of("live_status"), DockLiveStatus.class), + + WPMZ_VERSION(Set.of("wpmz_version"), DockDroneWpmzVersion.class), + + THERMAL_SUPPORTED_PALETTE_STYLE(PayloadModelConst.getAllIndexWithPosition(), DockDroneThermalSupportedPaletteStyle.class), + + RTH_MODE(Set.of("rth_mode"), DockDroneRthMode.class), + + CURRENT_RTH_MODE(Set.of("current_rth_mode"), DockDroneCurrentRthMode.class), + + COMMANDER_MODE_LOST_ACTION(Set.of("commander_mode_lost_action"), DockDroneCommanderModeLostAction.class), + + CURRENT_COMMANDER_FLIGHT_MODE(Set.of("current_commander_flight_mode"), DockDroneCurrentCommanderFlightMode.class), + + COMMANDER_FLIGHT_HEIGHT(Set.of("commander_flight_height"), DockDroneCommanderFlightHeight.class), + + MODE_CODE_REASON(Set.of("mode_code_reason"), DockDroneModeCodeReason.class), + + OFFLINE_MAP_ENABLE(Set.of("offline_map_enable"), DockDroneOfflineMapEnable.class), + + DONGLE_INFOS(Set.of("dongle_infos"), DongleInfos.class), + + SILENT_MODE(Set.of("silent_mode"), DockSilentMode.class), + + ; + + private final Set keys; + + private final Class classType; + + + DockStateDataKeyEnum(Set keys, Class classType) { + this.keys = keys; + this.classType = classType; + } + + public Class getClassType() { + return classType; + } + + public Set getKeys() { + return keys; + } + + public static DockStateDataKeyEnum find(Set keys) { + return Arrays.stream(values()).filter(keyEnum -> !Collections.disjoint(keys, keyEnum.keys)).findAny() + .orElseThrow(() -> new CloudSDKException(DockStateDataKeyEnum.class, keys)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/RcStateDataKeyEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/RcStateDataKeyEnum.java new file mode 100644 index 0000000..058cda8 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/RcStateDataKeyEnum.java @@ -0,0 +1,53 @@ +package org.dromara.common.sdk.mqtt.state; + +import org.dromara.common.sdk.cloudapi.device.*; +import org.dromara.common.sdk.cloudapi.livestream.RcLivestreamAbilityUpdate; +import org.dromara.common.sdk.exception.CloudSDKException; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; + +/** + * + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public enum RcStateDataKeyEnum { + + FIRMWARE_VERSION(Set.of("firmware_version"), FirmwareVersion.class), + + LIVE_CAPACITY(Set.of("live_capacity"), RcLivestreamAbilityUpdate.class), + + CONTROL_SOURCE(Set.of("control_source"), RcDroneControlSource.class), + + LIVE_STATUS(Set.of("live_status"), RcLiveStatus.class), + + PAYLOAD_FIRMWARE(PayloadModelConst.getAllModelWithPosition(), PayloadFirmwareVersion.class), + ; + + private final Set keys; + + private final Class classType; + + + RcStateDataKeyEnum(Set keys, Class classType) { + this.keys = keys; + this.classType = classType; + } + + public Class getClassType() { + return classType; + } + + public Set getKeys() { + return keys; + } + + public static RcStateDataKeyEnum find(Set keys) { + return Arrays.stream(values()).filter(keyEnum -> !Collections.disjoint(keys, keyEnum.keys)).findAny() + .orElseThrow(() -> new CloudSDKException(RcStateDataKeyEnum.class, keys)); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/StateDataKeyEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/StateDataKeyEnum.java new file mode 100644 index 0000000..671c691 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/StateDataKeyEnum.java @@ -0,0 +1,86 @@ +package org.dromara.common.sdk.mqtt.state; + +import org.dromara.common.sdk.cloudapi.device.*; +import org.dromara.common.sdk.cloudapi.livestream.DockLivestreamAbilityUpdate; +import org.dromara.common.sdk.cloudapi.livestream.RcLivestreamAbilityUpdate; +import org.dromara.common.sdk.cloudapi.property.DockDroneCommanderFlightHeight; +import org.dromara.common.sdk.cloudapi.property.DockDroneCommanderModeLostAction; +import org.dromara.common.sdk.cloudapi.property.DockDroneOfflineMapEnable; +import org.dromara.common.sdk.cloudapi.property.DockDroneRthMode; +import org.dromara.common.sdk.mqtt.ChannelName; + +import java.util.Arrays; + +/** + * + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +public enum StateDataKeyEnum { + + RC_AND_DRONE_FIRMWARE_VERSION(ChannelName.INBOUND_STATE_RC_AND_DRONE_FIRMWARE_VERSION, FirmwareVersion.class), + + RC_LIVE_CAPACITY(ChannelName.INBOUND_STATE_RC_LIVESTREAM_ABILITY_UPDATE, RcLivestreamAbilityUpdate.class), + + RC_DRONE_CONTROL_SOURCE(ChannelName.INBOUND_STATE_RC_CONTROL_SOURCE, RcDroneControlSource.class), + + RC_LIVE_STATUS(ChannelName.INBOUND_STATE_RC_LIVE_STATUS, RcLiveStatus.class), + + RC_PAYLOAD_FIRMWARE(ChannelName.INBOUND_STATE_RC_PAYLOAD_FIRMWARE, PayloadFirmwareVersion.class), + + DOCK_FIRMWARE_VERSION(ChannelName.INBOUND_STATE_DOCK_FIRMWARE_VERSION, DockFirmwareVersion.class), + + DOCK_LIVE_CAPACITY(ChannelName.INBOUND_STATE_DOCK_LIVESTREAM_ABILITY_UPDATE, DockLivestreamAbilityUpdate.class), + + DOCK_DRONE_CONTROL_SOURCE(ChannelName.INBOUND_STATE_DOCK_DRONE_CONTROL_SOURCE, DockDroneControlSource.class), + + DOCK_LIVE_STATUS(ChannelName.INBOUND_STATE_DOCK_LIVE_STATUS, DockLiveStatus.class), + + DOCK_DRONE_WPMZ_VERSION(ChannelName.INBOUND_STATE_DOCK_DRONE_WPMZ_VERSION, DockDroneWpmzVersion.class), + + DOCK_DRONE_THERMAL_SUPPORTED_PALETTE_STYLE(ChannelName.INBOUND_STATE_DOCK_DRONE_THERMAL_SUPPORTED_PALETTE_STYLE, DockDroneThermalSupportedPaletteStyle.class), + + DOCK_DRONE_RTH_MODE(ChannelName.INBOUND_STATE_DOCK_DRONE_RTH_MODE, DockDroneRthMode.class), + + DOCK_DRONE_CURRENT_RTH_MODE(ChannelName.INBOUND_STATE_DOCK_DRONE_CURRENT_RTH_MODE, DockDroneCurrentRthMode.class), + + DOCK_DRONE_COMMANDER_MODE_LOST_ACTION(ChannelName.INBOUND_STATE_DOCK_DRONE_COMMANDER_MODE_LOST_ACTION, DockDroneCommanderModeLostAction.class), + + DOCK_DRONE_CURRENT_COMMANDER_FLIGHT_MODE(ChannelName.INBOUND_STATE_DOCK_DRONE_CURRENT_COMMANDER_FLIGHT_MODE, DockDroneCurrentCommanderFlightMode.class), + + DOCK_DRONE_COMMANDER_FLIGHT_HEIGHT(ChannelName.INBOUND_STATE_DOCK_DRONE_COMMANDER_FLIGHT_HEIGHT, DockDroneCommanderFlightHeight.class), + + DOCK_DRONE_MODE_CODE_REASON(ChannelName.INBOUND_STATE_DOCK_DRONE_MODE_CODE_REASON, DockDroneModeCodeReason.class), + + DOCK_DRONE_OFFLINE_MAP_ENABLE(ChannelName.INBOUND_STATE_DOCK_DRONE_OFFLINE_MAP_ENABLE, DockDroneOfflineMapEnable.class), + + DOCK_AND_DRONE_DONGLE_INFOS(ChannelName.INBOUND_STATE_DOCK_AND_DRONE_DONGLE_INFOS, DongleInfos.class), + + DOCK_SILENT_MODE(ChannelName.INBOUND_STATE_DOCK_SILENT_MODE, DockSilentMode.class), + + UNKNOWN(ChannelName.DEFAULT, Object.class); + + private final String channelName; + + private final Class classType; + + StateDataKeyEnum(String channelName, Class classType) { + this.channelName = channelName; + this.classType = classType; + } + + public Class getClassType() { + return classType; + } + + public String getChannelName() { + return channelName; + } + + public static StateDataKeyEnum find(Class clazz) { + return Arrays.stream(values()).filter(keyEnum -> keyEnum.classType == clazz).findAny() + .orElse(UNKNOWN); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/StateRouter.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/StateRouter.java new file mode 100644 index 0000000..7ad9268 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/StateRouter.java @@ -0,0 +1,89 @@ +package org.dromara.common.sdk.mqtt.state; + +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.common.SDKManager; +import org.dromara.common.sdk.exception.CloudSDKErrorEnum; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttGatewayPublish; +import com.fasterxml.jackson.core.type.TypeReference; +import jakarta.annotation.Resource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import static org.dromara.common.sdk.mqtt.TopicConst.*; + +/** + * + * @author sean.zhou + * @date 2021/11/17 + * @version 0.1 + */ +@Configuration +public class StateRouter { + + @Resource + private MqttGatewayPublish gatewayPublish; + + @Bean + public IntegrationFlow stateDataRouterFlow() { + return IntegrationFlow + .from(ChannelName.INBOUND_STATE) + .transform(Message.class, source -> { + try { + TopicStateRequest response = Common.getObjectMapper().readValue((byte[]) source.getPayload(), new TypeReference() {}); + String topic = String.valueOf(source.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)); + String from = topic.substring((THING_MODEL_PRE + PRODUCT).length(), topic.indexOf(STATE_SUF)); + return response.setFrom(from) + .setData(Common.getObjectMapper().convertValue(response.getData(), getTypeReference(response.getGateway(), response.getData()))); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }) + .route(response -> StateDataKeyEnum.find(response.getData().getClass()), + mapping -> Arrays.stream(StateDataKeyEnum.values()).forEach(key -> mapping.channelMapping(key, key.getChannelName()))) + .get(); + } + + + @Bean + public IntegrationFlow replySuccessState() { + return IntegrationFlow + .from(ChannelName.OUTBOUND_STATE) + .handle(this::publish) + .nullChannel(); + + } + + private TopicStateResponse publish(TopicStateResponse request, MessageHeaders headers) { + if (Objects.isNull(request) || Objects.isNull(request.getData())) { + return null; + } + gatewayPublish.publishReply(request, headers); + return request; + } + + + private Class getTypeReference(String gatewaySn, Object data) { + Set keys = ((Map) data).keySet(); + switch (SDKManager.getDeviceSDK(gatewaySn).getType()) { + case RC: + return RcStateDataKeyEnum.find(keys).getClassType(); + case DOCK: + case DOCK2: + return DockStateDataKeyEnum.find(keys).getClassType(); + default: + throw new CloudSDKException(CloudSDKErrorEnum.WRONG_DATA, "Unexpected value: " + SDKManager.getDeviceSDK(gatewaySn).getType()); + } + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/StateSubscribe.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/StateSubscribe.java new file mode 100644 index 0000000..7e5769b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/StateSubscribe.java @@ -0,0 +1,44 @@ +package org.dromara.common.sdk.mqtt.state; + +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.common.SDKManager; +import org.dromara.common.sdk.mqtt.IMqttTopicService; +import org.dromara.common.sdk.mqtt.TopicConst; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class StateSubscribe { + + @Resource + private IMqttTopicService topicService; + + public static final String TOPIC = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + "%s" + TopicConst.STATE_SUF; + + public void subscribe(GatewayManager gateway, boolean unsubscribeSubDevice) { + SDKManager.registerDevice(gateway); + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (unsubscribeSubDevice) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + return; + } + if (null != gateway.getDroneSn()) { + topicService.subscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } + + public void unsubscribe(GatewayManager gateway) { + SDKManager.logoutDevice(gateway.getGatewaySn()); + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + if (null != gateway.getDroneSn()) { + topicService.unsubscribe(String.format(TOPIC, gateway.getDroneSn())); + } + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/TopicStateRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/TopicStateRequest.java new file mode 100644 index 0000000..38e7264 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/TopicStateRequest.java @@ -0,0 +1,96 @@ +package org.dromara.common.sdk.mqtt.state; + +import org.dromara.common.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicStateRequest extends CommonTopicRequest { + + private String gateway; + + private String from; + + private boolean needReply; + + public TopicStateRequest() { + } + + @Override + public String toString() { + return "TopicStateRequest{" + + "gateway='" + gateway + '\'' + + ", from='" + from + '\'' + + ", needReply=" + needReply + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getTid() { + return tid; + } + + public TopicStateRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicStateRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicStateRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicStateRequest setData(T data) { + this.data = data; + return this; + } + + public String getGateway() { + return gateway; + } + + public TopicStateRequest setGateway(String gateway) { + this.gateway = gateway; + return this; + } + + public String getFrom() { + return from; + } + + public TopicStateRequest setFrom(String from) { + this.from = from; + return this; + } + + public boolean isNeedReply() { + return needReply; + } + + public TopicStateRequest setNeedReply(boolean needReply) { + this.needReply = needReply; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/TopicStateResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/TopicStateResponse.java new file mode 100644 index 0000000..0d640e2 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/state/TopicStateResponse.java @@ -0,0 +1,68 @@ +package org.dromara.common.sdk.mqtt.state; + +import org.dromara.common.sdk.mqtt.CommonTopicResponse; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/11 + */ +public class TopicStateResponse extends CommonTopicResponse { + + public TopicStateResponse() { + } + + @Override + public String toString() { + return "TopicStateResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + @Override + public String getTid() { + return super.getTid(); + } + + @Override + public TopicStateResponse setTid(String tid) { + super.setTid(tid); + return this; + } + + @Override + public String getBid() { + return super.getBid(); + } + + @Override + public TopicStateResponse setBid(String bid) { + super.setBid(bid); + return this; + } + + @Override + public T getData() { + return super.getData(); + } + + @Override + public TopicStateResponse setData(T data) { + super.setData(data); + return this; + } + + @Override + public Long getTimestamp() { + return super.getTimestamp(); + } + + @Override + public TopicStateResponse setTimestamp(Long timestamp) { + super.setTimestamp(timestamp); + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/StatusRouter.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/StatusRouter.java new file mode 100644 index 0000000..7720f6a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/StatusRouter.java @@ -0,0 +1,72 @@ +package org.dromara.common.sdk.mqtt.status; + +import org.dromara.common.sdk.cloudapi.device.UpdateTopo; +import org.dromara.common.sdk.common.Common; +import org.dromara.common.sdk.exception.CloudSDKException; +import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttGatewayPublish; +import com.fasterxml.jackson.core.type.TypeReference; +import jakarta.annotation.Resource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.mqtt.support.MqttHeaders; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; +import org.springframework.util.CollectionUtils; + +import java.io.IOException; +import java.util.Objects; +import java.util.Optional; + +import static org.dromara.common.sdk.mqtt.TopicConst.*; + +/** + * + * @author sean.zhou + * @date 2021/11/12 + * @version 0.1 + */ +@Configuration +public class StatusRouter { + + @Resource + private MqttGatewayPublish gatewayPublish; + + @Bean + public IntegrationFlow statusRouterFlow() { + return IntegrationFlow + .from(ChannelName.INBOUND_STATUS) + .transform(Message.class, source -> { + try { + TopicStatusRequest response = Common.getObjectMapper().readValue((byte[]) source.getPayload(), new TypeReference>() {}); + String topic = String.valueOf(source.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)); + return response.setFrom(topic.substring((BASIC_PRE + PRODUCT).length(), topic.indexOf(STATUS_SUF))); + } catch (IOException e) { + throw new CloudSDKException(e); + } + }) + ., Boolean>route( + response -> Optional.ofNullable(response.getData()).map(UpdateTopo::getSubDevices).map(CollectionUtils::isEmpty).orElse(true), + mapping -> mapping.channelMapping(true, ChannelName.INBOUND_STATUS_OFFLINE) + .channelMapping(false, ChannelName.INBOUND_STATUS_ONLINE)) + .get(); + } + + @Bean + public IntegrationFlow replySuccessStatus() { + return IntegrationFlow + .from(ChannelName.OUTBOUND_STATUS) + .handle(this::publish) + .nullChannel(); + + } + + private TopicStatusResponse publish(TopicStatusResponse request, MessageHeaders headers) { + if (Objects.isNull(request)) { + return null; + } + gatewayPublish.publishReply(request, headers); + return request; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/StatusSubscribe.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/StatusSubscribe.java new file mode 100644 index 0000000..7ba5d7b --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/StatusSubscribe.java @@ -0,0 +1,38 @@ +package org.dromara.common.sdk.mqtt.status; + +import org.dromara.common.sdk.config.version.GatewayManager; +import org.dromara.common.sdk.common.SDKManager; +import org.dromara.common.sdk.mqtt.IMqttTopicService; +import org.dromara.common.sdk.mqtt.TopicConst; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Component +public class StatusSubscribe { + + public static final String TOPIC = TopicConst.BASIC_PRE + TopicConst.PRODUCT + "%s" + TopicConst.STATUS_SUF; + + @Resource + private IMqttTopicService topicService; + + public void subscribe(GatewayManager gateway) { + SDKManager.registerDevice(gateway); + topicService.subscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + + public void subscribeWildcardsStatus() { + topicService.subscribe(String.format(TOPIC, "+")); + } + + public void unsubscribe(GatewayManager gateway) { + SDKManager.logoutDevice(gateway.getGatewaySn()); + topicService.unsubscribe(String.format(TOPIC, gateway.getGatewaySn())); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/TopicStatusRequest.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/TopicStatusRequest.java new file mode 100644 index 0000000..866af18 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/TopicStatusRequest.java @@ -0,0 +1,84 @@ +package org.dromara.common.sdk.mqtt.status; + +import org.dromara.common.sdk.mqtt.CommonTopicRequest; + +/** + * @author sean + * @version 1.7 + * @date 2023/5/24 + */ +public class TopicStatusRequest extends CommonTopicRequest { + + private String method; + + private String from; + + public TopicStatusRequest() { + } + + @Override + public String toString() { + return "TopicStatusRequest{" + + "method='" + method + '\'' + + ", from='" + from + '\'' + + ", tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", timestamp=" + timestamp + + ", data=" + data + + '}'; + } + + public String getTid() { + return tid; + } + + public TopicStatusRequest setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicStatusRequest setBid(String bid) { + this.bid = bid; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicStatusRequest setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public T getData() { + return data; + } + + public TopicStatusRequest setData(T data) { + this.data = data; + return this; + } + + public String getMethod() { + return method; + } + + public TopicStatusRequest setMethod(String method) { + this.method = method; + return this; + } + + public String getFrom() { + return from; + } + + public TopicStatusRequest setFrom(String from) { + this.from = from; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/TopicStatusResponse.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/TopicStatusResponse.java new file mode 100644 index 0000000..115017a --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/mqtt/status/TopicStatusResponse.java @@ -0,0 +1,73 @@ +package org.dromara.common.sdk.mqtt.status; + +import org.dromara.common.sdk.mqtt.CommonTopicResponse; + +/** + * Unified Topic request format + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public class TopicStatusResponse extends CommonTopicResponse { + + private String method; + + @Override + public String toString() { + return "TopicStatusResponse{" + + "tid='" + tid + '\'' + + ", bid='" + bid + '\'' + + ", method='" + method + '\'' + + ", data=" + data + + ", timestamp=" + timestamp + + '}'; + } + + public TopicStatusResponse() { + } + + public String getTid() { + return tid; + } + + public TopicStatusResponse setTid(String tid) { + this.tid = tid; + return this; + } + + public String getBid() { + return bid; + } + + public TopicStatusResponse setBid(String bid) { + this.bid = bid; + return this; + } + + public String getMethod() { + return method; + } + + public TopicStatusResponse setMethod(String method) { + this.method = method; + return this; + } + + public T getData() { + return data; + } + + public TopicStatusResponse setData(T data) { + this.data = data; + return this; + } + + public Long getTimestamp() { + return timestamp; + } + + public TopicStatusResponse setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/swagger/SwaggerConfig.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/swagger/SwaggerConfig.java new file mode 100644 index 0000000..2db2e05 --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/swagger/SwaggerConfig.java @@ -0,0 +1,56 @@ +package org.dromara.common.sdk.swagger; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springdoc.core.GroupedOpenApi; +import org.springdoc.core.SpringDocConfigProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author sean + * @version 1.7 + * @date 2023/6/14 + */ +@Configuration +@OpenAPIDefinition(security = {@SecurityRequirement(name = "default")}) +public class SwaggerConfig { + + @Bean + public OpenAPI openAPI() { + return new OpenAPI() + .info(new Info().title("CloudSDK API").description("All HTTP interfaces encapsulated by CloudSDK.") + .license(new License().name("LICENSE").url("https://github.com/dji-sdk/DJI-Cloud-API-Demo/blob/main/LICENSE")) + .version("1.0.0")).components(components()); + } + + @Bean + public SecurityScheme securityScheme() { + return new SecurityScheme().type(SecurityScheme.Type.APIKEY).in(SecurityScheme.In.HEADER).name("x-auth-token"); + } + + @Bean + public Components components() { + return new Components() + .addSecuritySchemes("default", securityScheme()); + } + + @Bean + public GroupedOpenApi sdkOpenApi() { + return GroupedOpenApi.builder().group("CloudSDK") + .packagesToScan("org.dromara.common").build(); + } + + @Bean + public SpringDocConfigProperties springDocConfigProperties(SpringDocConfigProperties properties) { + properties.setDefaultFlatParamObject(false); + properties.setDefaultSupportFormData(true); + properties.setDefaultProducesMediaType("application/json"); + return properties; + } +} diff --git a/dk-common/common-seata/src/main/resources/common-seata.yml b/dk-common/common-seata/src/main/resources/common-seata.yml index 56be998..eacb585 100644 --- a/dk-common/common-seata/src/main/resources/common-seata.yml +++ b/dk-common/common-seata/src/main/resources/common-seata.yml @@ -13,7 +13,7 @@ seata: registry: type: nacos nacos: - application: ruoyi-seata-server + application: seata-server server-addr: ${spring.cloud.nacos.server-addr} group: ${spring.cloud.nacos.discovery.group} username: ${spring.cloud.nacos.username} diff --git a/dk-common/common-websocket/src/main/java/org/dromara/common/websocket/dto/BizCodeEnum.java b/dk-common/common-websocket/src/main/java/org/dromara/common/websocket/dto/BizCodeEnum.java new file mode 100644 index 0000000..427c644 --- /dev/null +++ b/dk-common/common-websocket/src/main/java/org/dromara/common/websocket/dto/BizCodeEnum.java @@ -0,0 +1,42 @@ +package org.dromara.common.websocket.dto; + +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @author sean + * @version 0.1 + * @date 2021/11/26 + */ +@Schema(enumAsRef = true, description = "Pilot2 will receive these bizCode, and then do corresponding processing according to the value.") +public enum BizCodeEnum { + + DEVICE_ONLINE("device_online"), + + DEVICE_OFFLINE("device_offline"), + + DEVICE_UPDATE_TOPO("device_update_topo"), + + DEVICE_OSD("device_osd"), + + MAP_ELEMENT_CREATE("map_element_create"), + + MAP_ELEMENT_UPDATE("map_element_update"), + + MAP_ELEMENT_DELETE("map_element_delete"), + + MAP_GROUP_REFRESH("map_group_refresh"); + + private final String code; + + BizCodeEnum(String code) { + this.code = code; + } + + @JsonValue + public String getCode() { + return code; + } + + +} diff --git a/dk-common/pom.xml b/dk-common/pom.xml index 941fad2..0231b69 100644 --- a/dk-common/pom.xml +++ b/dk-common/pom.xml @@ -45,6 +45,7 @@ common-nacos common-bus common-sse + common-cloudsdk dk-common diff --git a/dk-example/test-mq/src/main/resources/application.yml b/dk-example/test-mq/src/main/resources/application.yml index 8326cc3..bad4382 100644 --- a/dk-example/test-mq/src/main/resources/application.yml +++ b/dk-example/test-mq/src/main/resources/application.yml @@ -11,14 +11,14 @@ spring: active: @profiles.active@ --- # rabbitmq 配置 -spring: - rabbitmq: - host: localhost - port: 5672 - username: guest - password: guest - publisher-returns: true - publisher-confirm-type: correlated +#spring: +# rabbitmq: +# host: localhost +# port: 5672 +# username: guest +# password: guest +# publisher-returns: true +# publisher-confirm-type: correlated --- # kafka 配置 spring: @@ -39,7 +39,7 @@ spring: --- # rocketmq 配置 rocketmq: - name-server: localhost:9876 + name-server: 114.235.183.174:9876 producer: # 生产者组 group: dist-test diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/CloudApiSampleApplication.java b/dk-modules/sample/src/main/java/org/dromara/sample/CloudApiSampleApplication.java new file mode 100644 index 0000000..b36e909 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/CloudApiSampleApplication.java @@ -0,0 +1,19 @@ +package com.dji.sample; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.scheduling.annotation.EnableScheduling; + +@MapperScan("com.dji.sample.*.dao") +@SpringBootApplication +@EnableScheduling +@ComponentScan("com.dji") +public class CloudApiSampleApplication { + + public static void main(String[] args) { + SpringApplication.run(CloudApiSampleApplication.class, args); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/common/error/CommonErrorEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/common/error/CommonErrorEnum.java new file mode 100644 index 0000000..18af675 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/common/error/CommonErrorEnum.java @@ -0,0 +1,57 @@ +package com.dji.sample.common.error; + +import com.dji.sdk.common.IErrorInfo; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum CommonErrorEnum implements IErrorInfo { + + ILLEGAL_ARGUMENT(200001, "非法参数"), + + REDIS_DATA_NOT_FOUND(201404, "Redis数据不存在。"), + + DEVICE_OFFLINE(212015, "设备脱机。"), + + GET_ORGANIZATION_FAILED(210230, "无法获取组织。"), + + DEVICE_BINDING_FAILED(210231, "绑定设备失败。"), + + NON_REPEATABLE_BINDING(210232, "设备已绑定到另一个组织,无法重复绑定。"), + + GET_DEVICE_BINDING_STATUS_FAILED(210233, "无法获取设备绑定状态。"), + + SYSTEM_ERROR(600500, "系统错误"), + + SECRET_INVALID(600100, "机密无效"), + + NO_TOKEN(600101, "token为null"), + + TOKEN_EXPIRED(600102, "token已过期"), + + TOKEN_INVALID(600103, "token无效"), + + SIGN_INVALID(600104, "签名无效"); + + private String msg; + + private int code; + + CommonErrorEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/common/model/CustomClaim.java b/dk-modules/sample/src/main/java/org/dromara/sample/common/model/CustomClaim.java new file mode 100644 index 0000000..85c16a9 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/common/model/CustomClaim.java @@ -0,0 +1,88 @@ +package com.dji.sample.common.model; + +import com.auth0.jwt.interfaces.Claim; +import com.fasterxml.jackson.annotation.JsonAlias; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.lang.reflect.Field; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A custom claim for storing custom information in the token. + * @author sean.zhou + * @date 2021/11/16 + * @version 0.1 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Slf4j +public class CustomClaim { + + /** + * The id of the account. + */ + private String id; + + private String username; + + @JsonAlias("user_type") + private Integer userType; + + @JsonAlias("workspace_id") + private String workspaceId; + + /** + * Convert the custom claim data type to the Map type. + * @return map + */ + public ConcurrentHashMap convertToMap() { + ConcurrentHashMap map = new ConcurrentHashMap<>(4); + try { + Field[] declaredFields = this.getClass().getDeclaredFields(); + for (Field field : declaredFields) { + JsonAlias annotation = field.getAnnotation(JsonAlias.class); + field.setAccessible(true); + // The value of key is named underscore. + map.put(annotation != null ? annotation.value()[0] : field.getName(), + field.get(this).toString()); + } + } catch (IllegalAccessException e) { + log.info("CustomClaim converts failed. {}", this.toString()); + e.printStackTrace(); + } + return map; + } + + /** + * Convert the data in Map into a custom claim object. + * @param claimMap + */ + public CustomClaim (Map claimMap) { + Field[] declaredFields = this.getClass().getDeclaredFields(); + for (Field field : declaredFields) { + field.setAccessible(true); + JsonAlias annotation = field.getAnnotation(JsonAlias.class); + + Claim value = claimMap.get(annotation == null ? field.getName() : annotation.value()[0]); + try { + Class type = field.getType(); + if (Integer.class.equals(type)) { + field.set(this, Integer.valueOf(value.asString())); + continue; + } + if (String.class.equals(type)) { + field.set(this, value.asString()); + continue; + } + } catch (IllegalAccessException e) { + log.info("Claim parses failed. {}", claimMap.toString()); + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/common/util/JwtUtil.java b/dk-modules/sample/src/main/java/org/dromara/sample/common/util/JwtUtil.java new file mode 100644 index 0000000..d1e9c03 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/common/util/JwtUtil.java @@ -0,0 +1,144 @@ +package com.dji.sample.common.util; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTCreator; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.TokenExpiredException; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.dji.sample.common.model.CustomClaim; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.util.*; + +@Slf4j +@Component +public class JwtUtil { + + private static String issuer; + + private static String subject; + + private static long age; + + private static String secret; + + public static Algorithm algorithm; + + @Value("${jwt.issuer: DJI}") + private void setIssuer(String issuer) { + JwtUtil.issuer = issuer; + } + + @Value("${jwt.subject: CloudApiSample}") + private void setSubject(String subject) { + JwtUtil.subject = subject; + } + + @Value("${jwt.age: 86400}") + private void setAge(long age) { + JwtUtil.age = age * 1000; + } + + @Value("${jwt.secret: CloudApiSample}") + private void setSecret(String secret) { + JwtUtil.secret = secret; + setAlgorithm(); + } + + private void setAlgorithm() { + JwtUtil.algorithm = Algorithm.HMAC256(secret); + } + + private JwtUtil() { + + } + + /** + * Create a token based on custom information. + * @param claims custom information + * @return token + */ + public static String createToken(Map claims) { + return JwtUtil.createToken(claims, age, algorithm, subject, issuer); + } + + /** + * + * @param claims + * @param age unit: s + * @param algorithm + * @param subject + * @param issuer + * @return + */ + public static String createToken(Map claims, Long age, Algorithm algorithm, String subject, String issuer) { + if (Objects.isNull(algorithm)) { + throw new IllegalArgumentException(); + } + + Date now = new Date(); + JWTCreator.Builder builder = JWT.create(); + // Add custom information to the token's payload segment. + claims.forEach((k, v) -> { + if (Objects.nonNull(v.getClass().getClassLoader())) { + log.error("claim can't be set to a custom object."); + return; + } + if (v instanceof Map) { + builder.withClaim(k, (Map) v); + } else if (v instanceof List) { + builder.withClaim(k, (List) v); + } else { + builder.withClaim(k, String.valueOf(v)); + } + }); + + if (StringUtils.hasText(subject)) { + builder.withSubject(subject); + } + + if (StringUtils.hasText(issuer)) { + builder.withIssuer(issuer); + } + + if (Objects.nonNull(age)) { + builder.withExpiresAt(new Date(now.getTime() + age)); + } + + String token = builder + .withIssuedAt(now) + .withNotBefore(now) + .sign(algorithm); + log.debug("token created. " + token); + return token; + } + + /** + * Verify that the token is valid. + * @param token + * @return + * @throws TokenExpiredException + */ + public static DecodedJWT verifyToken(String token) { + return JWT.require(algorithm).build().verify(token); + } + + /** + * Parses the custom information in the token into a CustomClaim object. + * @param token + * @return custom claim + */ + public static Optional parseToken(String token) { + DecodedJWT jwt; + try { + jwt = verifyToken(token); + } catch (Exception e) { + e.printStackTrace(); + return Optional.empty(); + } + return Optional.of(new CustomClaim(jwt.getClaims())); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/common/util/SpringBeanUtilsTest.java b/dk-modules/sample/src/main/java/org/dromara/sample/common/util/SpringBeanUtilsTest.java new file mode 100644 index 0000000..cbe4ab1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/common/util/SpringBeanUtilsTest.java @@ -0,0 +1,30 @@ +package com.dji.sample.common.util; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +@Component +public class SpringBeanUtilsTest implements ApplicationContextAware { + + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringBeanUtilsTest.applicationContext = applicationContext; + } + + public static T getBean(Class clazz) { + return applicationContext.getBean(clazz); + } + + public static Object getBean(String beanName) { + return applicationContext.getBean(beanName); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/ApplicationBootInitial.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/ApplicationBootInitial.java new file mode 100644 index 0000000..16a691c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/ApplicationBootInitial.java @@ -0,0 +1,52 @@ +package com.dji.sample.component; + +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.common.SDKManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +/** + * @author sean.zhou + * @date 2021/11/24 + * @version 0.1 + */ +@Component +public class ApplicationBootInitial implements CommandLineRunner { + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + /** + * Subscribe to the devices that exist in the redis when the program starts, + * to prevent the data from being different from the pilot side due to program interruptions. + * @param args + * @throws Exception + */ + @Override + public void run(String... args) throws Exception { + int start = RedisConst.DEVICE_ONLINE_PREFIX.length(); + + RedisOpsUtils.getAllKeys(RedisConst.DEVICE_ONLINE_PREFIX + "*") + .stream() + .map(key -> key.substring(start)) + .map(deviceRedisService::getDeviceOnline) + .map(Optional::get) + .filter(device -> DeviceDomainEnum.DRONE != device.getDomain()) + .forEach(device -> deviceService.subDeviceOnlineSubscribeTopic( + SDKManager.registerDevice(device.getDeviceSn(), device.getChildDeviceSn(), device.getDomain(), + device.getType(), device.getSubType(), device.getThingVersion(), + deviceRedisService.getDeviceOnline(device.getChildDeviceSn()).map(DeviceDTO::getThingVersion).orElse(null)))); + + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/AuthInterceptor.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/AuthInterceptor.java new file mode 100644 index 0000000..9933466 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/AuthInterceptor.java @@ -0,0 +1,60 @@ +package com.dji.sample.component; + +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.common.util.JwtUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Optional; + +@Slf4j +@Component +public class AuthInterceptor implements HandlerInterceptor { + + public static final String PARAM_TOKEN = "x-auth-token"; + + public static final String TOKEN_CLAIM = "customClaim"; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String uri = request.getRequestURI(); + log.debug("request uri: {}, IP: {}", uri, request.getRemoteAddr()); + // The options method is passed directly. + if (HttpMethod.OPTIONS.matches(request.getMethod())) { + response.setStatus(HttpStatus.OK.value()); + return false; + } + String token = request.getHeader(PARAM_TOKEN); + // Check if the token exists. + if (!StringUtils.hasText(token)) { + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + log.error(CommonErrorEnum.NO_TOKEN.getMessage()); + return false; + } + + // Check if the current token is valid. + Optional customClaimOpt = JwtUtil.parseToken(token); + if (customClaimOpt.isEmpty()) { + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + return false; + } + + // Put the custom data from the token into the request. + request.setAttribute(TOKEN_CLAIM, customClaimOpt.get()); + return true; + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + // Delete the custom data in the request after the request ends. + request.removeAttribute(TOKEN_CLAIM); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/CorsFilter.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/CorsFilter.java new file mode 100644 index 0000000..a4c245f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/CorsFilter.java @@ -0,0 +1,35 @@ +package com.dji.sample.component; + +import org.springframework.stereotype.Component; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +import static com.dji.sample.component.AuthInterceptor.PARAM_TOKEN; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/22 + */ +@Component +public class CorsFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { + HttpServletResponse res = (HttpServletResponse) response; + res.addHeader("Access-Control-Allow-Credentials", "true"); + res.addHeader("Access-Control-Allow-Origin", "*"); + res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); + res.addHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers," + + "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, "+ + "Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive," + + " User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma," + PARAM_TOKEN); + if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) { + return; + } + filterChain.doFilter(request, response); + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/GlobalExceptionHandler.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/GlobalExceptionHandler.java new file mode 100644 index 0000000..f7e79c2 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/GlobalExceptionHandler.java @@ -0,0 +1,42 @@ +package com.dji.sample.component; + +import com.dji.sdk.common.HttpResultResponse; +import org.springframework.validation.BindException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/1 + */ +@ControllerAdvice +@ResponseBody +public class GlobalExceptionHandler { + + /** + * Please do not return directly like this, there is a risk. + * @param e + * @return + */ + @ExceptionHandler(Exception.class) + public HttpResultResponse exceptionHandler(Exception e) { + e.printStackTrace(); + return HttpResultResponse.error(e.getLocalizedMessage()); + } + + @ExceptionHandler(NullPointerException.class) + public HttpResultResponse nullPointerExceptionHandler(NullPointerException e) { + e.printStackTrace(); + return HttpResultResponse.error("A null object appeared."); + } + + @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class}) + public HttpResultResponse methodArgumentNotValidExceptionHandler(BindException e) { + e.printStackTrace(); + return HttpResultResponse.error(e.getFieldError().getField() + e.getFieldError().getDefaultMessage()); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/GlobalScheduleService.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/GlobalScheduleService.java new file mode 100644 index 0000000..fe4dfd2 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/GlobalScheduleService.java @@ -0,0 +1,61 @@ +package com.dji.sample.component; + +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.mqtt.IMqttTopicService; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +/** + * @author sean.zhou + * @date 2021/11/24 + * @version 0.1 + */ +@Component +@Slf4j +public class GlobalScheduleService { + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IMqttTopicService topicService; + + @Autowired + private ObjectMapper mapper; + /** + * Check the status of the devices every 30 seconds. It is recommended to use cache. + */ + @Scheduled(initialDelay = 10, fixedRate = 30, timeUnit = TimeUnit.SECONDS) + private void deviceStatusListen() { + int start = RedisConst.DEVICE_ONLINE_PREFIX.length(); + + RedisOpsUtils.getAllKeys(RedisConst.DEVICE_ONLINE_PREFIX + "*").forEach(key -> { + long expire = RedisOpsUtils.getExpire(key); + if (expire <= 30) { + DeviceDTO device = (DeviceDTO) RedisOpsUtils.get(key); + if (null == device) { + return; + } + if (DeviceDomainEnum.DRONE == device.getDomain()) { + deviceService.subDeviceOffline(key.substring(start)); + } else { + deviceService.gatewayOffline(key.substring(start)); + } + RedisOpsUtils.del(key); + } + }); + + log.info("Subscriptions: {}", Arrays.toString(topicService.getSubscribedTopic())); + } + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/config/MqttMessageChannel.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/config/MqttMessageChannel.java new file mode 100644 index 0000000..aba87cb --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/config/MqttMessageChannel.java @@ -0,0 +1,75 @@ +package com.dji.sample.component.mqtt.config; + +import com.dji.sdk.mqtt.ChannelName; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.channel.DirectChannel; +import org.springframework.integration.channel.ExecutorChannel; +import org.springframework.messaging.MessageChannel; + +import java.util.concurrent.Executor; + +/** + * Definition classes for all channels + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Configuration +public class MqttMessageChannel { + + @Autowired + private Executor threadPool; + + @Bean(name = ChannelName.INBOUND) + public MessageChannel inboundChannel() { + return new ExecutorChannel(threadPool); + } + + @Bean(name = ChannelName.DEFAULT) + public MessageChannel defaultChannel() { + return new DirectChannel(); + } + + @Bean(name = ChannelName.INBOUND_STATUS) + public MessageChannel statusChannel() { + return new DirectChannel(); + } + + @Bean(name = ChannelName.INBOUND_STATE) + public MessageChannel stateChannel() { + return new DirectChannel(); + } + + @Bean(name = ChannelName.INBOUND_SERVICES_REPLY) + public MessageChannel serviceReplyChannel() { + return new DirectChannel(); + } + + @Bean(name = ChannelName.INBOUND_OSD) + public MessageChannel osdChannel() { + return new ExecutorChannel(threadPool); + } + + @Bean(name = ChannelName.INBOUND_REQUESTS) + public MessageChannel requestsChannel() { + return new DirectChannel(); + } + + @Bean(name = ChannelName.INBOUND_EVENTS) + public MessageChannel eventsChannel() { + return new DirectChannel(); + } + + @Bean(name = ChannelName.INBOUND_PROPERTY_SET_REPLY) + public MessageChannel propertySetReply() { + return new DirectChannel(); + } + + @Bean(name = ChannelName.INBOUND_DRC_UP) + public MessageChannel drcUp() { + return new DirectChannel(); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/config/MqttPropertyConfiguration.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/config/MqttPropertyConfiguration.java new file mode 100644 index 0000000..1cc5b17 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/config/MqttPropertyConfiguration.java @@ -0,0 +1,122 @@ +package com.dji.sample.component.mqtt.config; + +import com.auth0.jwt.algorithms.Algorithm; +import com.dji.sample.common.util.JwtUtil; +import com.dji.sample.component.mqtt.model.MqttClientOptions; +import com.dji.sample.component.mqtt.model.MqttProtocolEnum; +import com.dji.sample.component.mqtt.model.MqttUseEnum; +import com.dji.sdk.cloudapi.control.DrcModeMqttBroker; +import lombok.Data; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory; +import org.springframework.integration.mqtt.core.MqttPahoClientFactory; +import org.springframework.util.StringUtils; + +import java.util.Map; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Configuration +@Data +@ConfigurationProperties +public class MqttPropertyConfiguration { + + private static Map mqtt; + + private String password; + + public void setMqtt(Map mqtt) { + MqttPropertyConfiguration.mqtt = mqtt; + } + + /** + * Get the configuration options of the basic link of the mqtt client. + * @return + */ + static MqttClientOptions getBasicClientOptions() { + if (!mqtt.containsKey(MqttUseEnum.BASIC)) { + throw new Error("请先配置基本的mqtt连接参数,否则无法启动应用程序。"); + } + return mqtt.get(MqttUseEnum.BASIC); + } + + /** + * Get the mqtt address of the basic link. + * @return + */ + public static String getBasicMqttAddress() { + return getMqttAddress(getBasicClientOptions()); + } + + /** + * Splice the mqtt address according to the parameters of different clients. + * @param options + * @return + */ + private static String getMqttAddress(MqttClientOptions options) { + StringBuilder addr = new StringBuilder() + .append(options.getProtocol().getProtocolAddr()) + .append(options.getHost().trim()) + .append(":") + .append(options.getPort()); + if ((options.getProtocol() == MqttProtocolEnum.WS || options.getProtocol() == MqttProtocolEnum.WSS) + && StringUtils.hasText(options.getPath())) { + addr.append(options.getPath()); + } + return addr.toString(); + } + + /** + * Get the connection parameters of the mqtt client of the drc link. + * @param clientId + * @param username + * @param age The validity period of the token. unit: s + * @param map Custom data added in token. + * @return + */ + public static DrcModeMqttBroker getMqttBrokerWithDrc(String clientId, String username, Long age, Map map) { + if (!mqtt.containsKey(MqttUseEnum.DRC)) { + throw new RuntimeException("请先在后端配置文件中配置mqtt的drc链接参数。"); + } + Algorithm algorithm = JwtUtil.algorithm; + + String token = JwtUtil.createToken(map, age, algorithm, null, null); + + return new DrcModeMqttBroker() + .setAddress(getMqttAddress(mqtt.get(MqttUseEnum.DRC))) + .setUsername(username) + .setClientId(clientId) + .setExpireTime(System.currentTimeMillis() / 1000 + age) + .setPassword("yongqiang666") + .setEnableTls(false); + } + + + @Bean + public MqttConnectOptions mqttConnectOptions() { + MqttClientOptions customizeOptions = getBasicClientOptions(); + MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); + mqttConnectOptions.setServerURIs(new String[]{ getBasicMqttAddress() }); + mqttConnectOptions.setUserName(customizeOptions.getUsername()); + mqttConnectOptions.setPassword(StringUtils.hasText(customizeOptions.getPassword()) ? + customizeOptions.getPassword().toCharArray() : new char[0]); + mqttConnectOptions.setAutomaticReconnect(true); + mqttConnectOptions.setKeepAliveInterval(10); + return mqttConnectOptions; + } + + @Bean + public MqttPahoClientFactory mqttClientFactory() { + DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory(); + factory.setConnectionOptions(mqttConnectOptions()); + return factory; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/EventsReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/EventsReceiver.java new file mode 100644 index 0000000..f24f6af --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/EventsReceiver.java @@ -0,0 +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.*; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EventsReceiver extends EventsDataRequest { + + private String bid; + + private String sn; + + @Override + public EventsErrorCode getResult() { + return super.getResult(); + } + + @Override + public EventsReceiver setResult(EventsErrorCode result) { + super.setResult(result); + return this; + } + + @Override + public T getOutput() { + return super.getOutput(); + } + + @Override + public EventsReceiver setOutput(T output) { + super.setOutput(output); + return this; + } + + public String getBid() { + return bid; + } + + public EventsReceiver setBid(String bid) { + this.bid = bid; + return this; + } + + public String getSn() { + return sn; + } + + public EventsReceiver setSn(String sn) { + this.sn = sn; + return this; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MapKeyConst.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MapKeyConst.java new file mode 100644 index 0000000..632152e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MapKeyConst.java @@ -0,0 +1,16 @@ +package com.dji.sample.component.mqtt.model; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/14 + */ +public final class MapKeyConst { + + private MapKeyConst(){ + + } + + public static final String ACL = "acl"; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MqttClientOptions.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MqttClientOptions.java new file mode 100644 index 0000000..d1168bd --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MqttClientOptions.java @@ -0,0 +1,31 @@ +package com.dji.sample.component.mqtt.model; + +import lombok.Data; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/18 + */ +@Data +public class MqttClientOptions { + + private MqttProtocolEnum protocol; + + private String host; + + private Integer port; + + private String username; + + private String password; + + private String clientId; + + private String path; + + /** + * The topic to subscribe to immediately when client connects. Only required for basic link. + */ + private String inboundTopic; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MqttProtocolEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MqttProtocolEnum.java new file mode 100644 index 0000000..49bce90 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MqttProtocolEnum.java @@ -0,0 +1,30 @@ +package com.dji.sample.component.mqtt.model; + +import lombok.Getter; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/18 + */ +@Getter +public enum MqttProtocolEnum { + + MQTT("tcp"), + + MQTTS("ssl"), + + WS("ws"), + + WSS("wss"); + + String protocol; + + MqttProtocolEnum(String protocol) { + this.protocol = protocol; + } + + public String getProtocolAddr() { + return protocol + "://"; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MqttUseEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MqttUseEnum.java new file mode 100644 index 0000000..3f56704 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/mqtt/model/MqttUseEnum.java @@ -0,0 +1,19 @@ +package com.dji.sample.component.mqtt.model; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/18 + */ +public enum MqttUseEnum { + + /** + * The broker is used for basic link. + */ + BASIC, + + /** + * This broker is used for the drc link. + */ + DRC +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/mybatis/MybatisPlusConfiguration.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/mybatis/MybatisPlusConfiguration.java new file mode 100644 index 0000000..2992641 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/mybatis/MybatisPlusConfiguration.java @@ -0,0 +1,24 @@ +package com.dji.sample.component.mybatis; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Configuration +public class MybatisPlusConfiguration { + + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // select database + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + return interceptor; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/mybatis/MybatisPlusMetaObjectHandler.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/mybatis/MybatisPlusMetaObjectHandler.java new file mode 100644 index 0000000..ffd6bb1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/mybatis/MybatisPlusMetaObjectHandler.java @@ -0,0 +1,37 @@ +package com.dji.sample.component.mybatis; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.ZoneId; + +/** + * Automatic filling for set values + */ +@Component +public class MybatisPlusMetaObjectHandler implements MetaObjectHandler { + + /** + * Automatic filling when inserting into the database. + * @param metaObject + */ + @Override + public void insertFill(MetaObject metaObject) { + this.strictInsertFill(metaObject, "createTime", Long.class, + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + this.strictInsertFill(metaObject, "updateTime", Long.class, + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + } + + /** + * Automatic filling when updating the data. + * @param metaObject + */ + @Override + public void updateFill(MetaObject metaObject) { + this.strictUpdateFill(metaObject, "updateTime", Long.class, + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/model/OssConfiguration.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/model/OssConfiguration.java new file mode 100644 index 0000000..496c16a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/model/OssConfiguration.java @@ -0,0 +1,93 @@ +package com.dji.sample.component.oss.model; + +import com.dji.sdk.cloudapi.storage.OssTypeEnum; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +@ConfigurationProperties(prefix = "oss") +@Component +public class OssConfiguration { + + /** + * @see OssTypeEnum + */ + public static OssTypeEnum provider; + + /** + * Whether to use the object storage service. + */ + public static boolean enable; + + /** + * The protocol needs to be included at the beginning of the address. + */ + public static String endpoint; + + public static String accessKey; + + public static String secretKey; + + public static String region; + + public static Long expire; + + public static String roleSessionName; + + public static String roleArn; + + public static String bucket; + + public static String objectDirPrefix; + + public void setProvider(OssTypeEnum provider) { + OssConfiguration.provider = provider; + } + + public void setEnable(boolean enable) { + OssConfiguration.enable = enable; + } + + public void setEndpoint(String endpoint) { + OssConfiguration.endpoint = endpoint; + } + + public void setAccessKey(String accessKey) { + OssConfiguration.accessKey = accessKey; + } + + public void setSecretKey(String secretKey) { + OssConfiguration.secretKey = secretKey; + } + + public void setRegion(String region) { + OssConfiguration.region = region; + } + + public void setExpire(Long expire) { + OssConfiguration.expire = expire; + } + + public void setRoleSessionName(String roleSessionName) { + OssConfiguration.roleSessionName = roleSessionName; + } + + public void setRoleArn(String roleArn) { + OssConfiguration.roleArn = roleArn; + } + + public void setBucket(String bucket) { + OssConfiguration.bucket = bucket; + } + + public void setObjectDirPrefix(String objectDirPrefix) { + OssConfiguration.objectDirPrefix = objectDirPrefix; + } +} + + + diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/IOssService.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/IOssService.java new file mode 100644 index 0000000..3b26050 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/IOssService.java @@ -0,0 +1,51 @@ +package com.dji.sample.component.oss.service; + +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; + +import java.io.InputStream; +import java.net.URL; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/23 + */ +public interface IOssService { + + OssTypeEnum getOssType(); + + /** + * Get temporary credentials. + * @return + */ + CredentialsToken getCredentials(); + + /** + * Get the address of the object based on the bucket name and the object name. + * @param bucket bucket name + * @param objectKey object name + * @return download link + */ + URL getObjectUrl(String bucket, String objectKey); + + /** + * Deletes the object in the storage bucket. + * @param bucket + * @param objectKey + * @return + */ + Boolean deleteObject(String bucket, String objectKey); + + /** + * Get the contents of an object. + * @param bucket + * @param objectKey + * @return + */ + InputStream getObject(String bucket, String objectKey); + + void putObject(String bucket, String objectKey, InputStream input); + + void createClient(); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/AliyunOssServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/AliyunOssServiceImpl.java new file mode 100644 index 0000000..ff4c59f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/AliyunOssServiceImpl.java @@ -0,0 +1,120 @@ +package com.dji.sample.component.oss.service.impl; + +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.OSSException; +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; +import com.aliyuncs.http.MethodType; +import com.aliyuncs.profile.DefaultProfile; +import com.aliyuncs.profile.IClientProfile; +import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest; +import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse; +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.oss.service.IOssService; +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.net.URL; +import java.util.Date; +import java.util.Objects; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/23 + */ +@Service +@Slf4j +public class AliyunOssServiceImpl implements IOssService { + + private OSS ossClient; + + @Override + public OssTypeEnum getOssType() { + return OssTypeEnum.ALIYUN; + } + + @Override + public CredentialsToken getCredentials() { + + try { + + + String regionId = ""; + // 添加endpoint。适用于Java SDK 3.12.0及以上版本。 + DefaultProfile.addEndpoint(regionId, "Sts", "sts.cn-hangzhou.aliyuncs.com"); + // 添加endpoint。适用于Java SDK 3.12.0以下版本。 + // DefaultProfile.addEndpoint("",regionId, "Sts", endpoint); + // 构造default profile。 + IClientProfile profile = DefaultProfile.getProfile(regionId, OssConfiguration.accessKey, OssConfiguration.secretKey); + // 构造client。 + DefaultAcsClient client = new DefaultAcsClient(profile); + AssumeRoleRequest request = new AssumeRoleRequest(); + // 适用于Java SDK 3.12.0及以上版本。 + request.setSysMethod(MethodType.POST); + // 适用于Java SDK 3.12.0以下版本。 + //request.setMethod(MethodType.POST); + request.setRoleArn(OssConfiguration.roleArn); + request.setRoleSessionName(OssConfiguration.roleSessionName); + request.setDurationSeconds(OssConfiguration.expire); + AssumeRoleResponse response = client.getAcsResponse(request); + + return new CredentialsToken(response.getCredentials().getAccessKeyId(), response.getCredentials().getAccessKeySecret(), response.getCredentials().getSecurityToken(), OssConfiguration.expire); + } catch (ClientException e) { + log.debug("Failed to obtain sts."); + e.printStackTrace(); + } + return null; + } + + @Override + public URL getObjectUrl(String bucket, String objectKey) { + // First check if the object can be fetched. + boolean isExist = ossClient.doesObjectExist(bucket, objectKey); + if (!isExist) { + throw new OSSException("The object does not exist."); + } + + return ossClient.generatePresignedUrl(bucket, objectKey, + new Date(System.currentTimeMillis() + OssConfiguration.expire * 1000)); + } + + @Override + public Boolean deleteObject(String bucket, String objectKey) { + if (!ossClient.doesObjectExist(bucket, objectKey)) { + return true; + } + ossClient.deleteObject(bucket, objectKey); + return true; + } + + @Override + public InputStream getObject(String bucket, String objectKey) { + return ossClient.getObject(bucket, objectKey).getObjectContent(); + } + + @Override + public void putObject(String bucket, String objectKey, InputStream input) { + if (ossClient.doesObjectExist(bucket, objectKey)) { + throw new RuntimeException("The filename already exists."); + } + PutObjectResult objectResult = ossClient.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata())); + log.info("Upload FlighttaskCreateFile: {}", objectResult.getETag()); + } + + public void createClient() { + if (Objects.nonNull(this.ossClient)) { + return; + } + this.ossClient = new OSSClientBuilder() + .build(OssConfiguration.endpoint, OssConfiguration.accessKey, OssConfiguration.secretKey); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/AmazonS3ServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/AmazonS3ServiceImpl.java new file mode 100644 index 0000000..dabc0bd --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/AmazonS3ServiceImpl.java @@ -0,0 +1,126 @@ +package com.dji.sample.component.oss.service.impl; + +import com.amazonaws.HttpMethod; +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.*; +import com.amazonaws.services.securitytoken.AWSSecurityTokenService; +import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder; +import com.amazonaws.services.securitytoken.model.AssumeRoleRequest; +import com.amazonaws.services.securitytoken.model.AssumeRoleResult; +import com.amazonaws.services.securitytoken.model.Credentials; +import com.dji.sample.component.AuthInterceptor; +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.oss.service.IOssService; +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/27 + */ +@Slf4j +@Service +public class AmazonS3ServiceImpl implements IOssService { + + private AmazonS3 client; + + @Override + public OssTypeEnum getOssType() { + return OssTypeEnum.AWS; + } + + @Override + public CredentialsToken getCredentials() { + AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard() + .withCredentials(new AWSStaticCredentialsProvider( + new BasicAWSCredentials(OssConfiguration.accessKey, OssConfiguration.secretKey))) + .withRegion(OssConfiguration.region).build(); + + AssumeRoleRequest request = new AssumeRoleRequest() + .withRoleArn(OssConfiguration.roleArn) + .withRoleSessionName(OssConfiguration.roleSessionName) + .withDurationSeconds(Math.toIntExact(OssConfiguration.expire)); + AssumeRoleResult result = stsClient.assumeRole(request); + Credentials credentials = result.getCredentials(); + return new CredentialsToken(credentials.getAccessKeyId(), credentials.getSecretAccessKey(), + credentials.getSessionToken(), (credentials.getExpiration().getTime() - System.currentTimeMillis()) / 1000); + } + + @Override + public URL getObjectUrl(String bucket, String objectKey) { + return client.generatePresignedUrl(bucket, objectKey, + new Date(System.currentTimeMillis() + OssConfiguration.expire * 1000), HttpMethod.GET); + } + + @Override + public Boolean deleteObject(String bucket, String objectKey) { + if (!client.doesObjectExist(bucket, objectKey)) { + return true; + } + client.deleteObject(bucket, objectKey); + return true; + } + + public InputStream getObject(String bucket, String objectKey) { + return client.getObject(bucket, objectKey).getObjectContent().getDelegateStream(); + } + + @Override + public void putObject(String bucket, String objectKey, InputStream input) { + if (client.doesObjectExist(bucket, objectKey)) { + throw new RuntimeException("The filename already exists."); + } + PutObjectResult objectResult = client.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata())); + log.info("Upload FlighttaskCreateFile: {}", objectResult.toString()); + } + + public void createClient() { + if (Objects.nonNull(this.client)) { + return; + } + this.client = AmazonS3ClientBuilder.standard() + .withCredentials( + new AWSStaticCredentialsProvider( + new BasicAWSCredentials(OssConfiguration.accessKey, OssConfiguration.secretKey))) + .withRegion(OssConfiguration.region) + .build(); + } + + /** + * Configuring cross-origin resource sharing + */ + @PostConstruct + private void configCORS() { + if (!OssConfiguration.enable || !OssTypeEnum.AWS.getType().equals(OssConfiguration.provider)) { + return; + } + List allowedMethods = new ArrayList<>(); + allowedMethods.add(CORSRule.AllowedMethods.GET); + allowedMethods.add(CORSRule.AllowedMethods.POST); + allowedMethods.add(CORSRule.AllowedMethods.DELETE); + + CORSRule rule = new CORSRule() + .withId("CORSAccessRule") + .withAllowedOrigins(List.of("*")) + .withAllowedHeaders(List.of(AuthInterceptor.PARAM_TOKEN)) + .withAllowedMethods(allowedMethods); + + client.setBucketCrossOriginConfiguration(OssConfiguration.bucket, + new BucketCrossOriginConfiguration().withRules(rule)); + + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/MinIOServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/MinIOServiceImpl.java new file mode 100644 index 0000000..2f7c04a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/MinIOServiceImpl.java @@ -0,0 +1,140 @@ +package com.dji.sample.component.oss.service.impl; + +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.auth.BasicSessionCredentials; +import com.amazonaws.client.builder.AwsClientBuilder; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import com.amazonaws.services.s3.model.S3Object; +import com.amazonaws.services.securitytoken.AWSSecurityTokenService; +import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder; +import com.amazonaws.services.securitytoken.model.AssumeRoleRequest; +import com.amazonaws.services.securitytoken.model.AssumeRoleResult; +import com.amazonaws.services.securitytoken.model.Credentials; +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.oss.service.IOssService; +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; +import io.minio.*; +import io.minio.credentials.AssumeRoleProvider; +import io.minio.errors.*; +import io.minio.http.Method; +import lombok.extern.slf4j.Slf4j; +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; + +import static com.dji.sample.component.oss.model.OssConfiguration.*; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/23 + */ +@Service +@Slf4j +public class MinIOServiceImpl implements IOssService { + + private MinioClient client; + + @Override + public OssTypeEnum getOssType() { + return OssTypeEnum.MINIO; + } + + @Override + public CredentialsToken getCredentials() { + try { + AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpoint, region); + BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey); + AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(basicAWSCredentials); + AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard() + .withEndpointConfiguration(endpointConfiguration) + .withCredentials(credentialsProvider).build(); + Credentials credentials = stsClient.getSessionToken().getCredentials(); + return new CredentialsToken(credentials.getAccessKeyId(), credentials.getSecretAccessKey(), credentials.getSessionToken(), OssConfiguration.expire); + } catch (Exception e) { + log.debug("Failed to obtain sts."); + e.printStackTrace(); + } + return null; + } + + @Override + public URL getObjectUrl(String bucket, String objectKey) { + try { + return new URL( + client.getPresignedObjectUrl( + GetPresignedObjectUrlArgs.builder() + .method(Method.GET) + .bucket(bucket) + .object(objectKey) + .expiry(Math.toIntExact(OssConfiguration.expire)) + .build())); + } catch (ErrorResponseException | InsufficientDataException | InternalException | + InvalidKeyException | InvalidResponseException | IOException | + NoSuchAlgorithmException | XmlParserException | ServerException e) { + throw new RuntimeException("The file does not exist on the OssConfiguration."); + } + } + + @Override + public Boolean deleteObject(String bucket, String objectKey) { + try { + client.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectKey).build()); + } catch (MinioException | NoSuchAlgorithmException | IOException | InvalidKeyException e) { + log.error("Failed to delete file."); + e.printStackTrace(); + return false; + } + return true; + } + + @Override + public InputStream getObject(String bucket, String objectKey) { + try { + GetObjectResponse object = client.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 InputStream.nullInputStream(); + } + + @Override + public void putObject(String bucket, String objectKey, InputStream input) { + try { + 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 FlighttaskCreateFile: {}", response.etag()); + } catch (MinioException | IOException | InvalidKeyException | NoSuchAlgorithmException ex) { + log.error("Failed to upload FlighttaskCreateFile {}.", objectKey); + ex.printStackTrace(); + } + } + } + + public void createClient() { + if (Objects.nonNull(this.client)) { + return; + } + this.client = MinioClient.builder() + .endpoint(OssConfiguration.endpoint) + .credentials(accessKey, secretKey) + .region(region) + .build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/OssAspectHandler.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/OssAspectHandler.java new file mode 100644 index 0000000..633c5a8 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/OssAspectHandler.java @@ -0,0 +1,31 @@ +package com.dji.sample.component.oss.service.impl; + +import com.dji.sample.component.oss.model.OssConfiguration; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/20 + */ +@Component +@Aspect +public class OssAspectHandler { + + @Autowired + private OssServiceContext ossServiceContext; + + @Before("execution(public * com.dji.sample.component.oss.service.impl.OssServiceContext.*(..))") + public void before() { + if (!OssConfiguration.enable) { + throw new IllegalArgumentException("请启用OSS配置。"); + } + if (this.ossServiceContext.getOssService() == null) { + throw new IllegalArgumentException("请检查OSS配置配置。"); + } + this.ossServiceContext.createClient(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/OssServiceContext.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/OssServiceContext.java new file mode 100644 index 0000000..b8aa1d0 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/oss/service/impl/OssServiceContext.java @@ -0,0 +1,68 @@ +package com.dji.sample.component.oss.service.impl; + +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.oss.service.IOssService; +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.io.InputStream; +import java.net.URL; +import java.util.Arrays; +import java.util.List; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/30 + */ +@Service +public class OssServiceContext { + + private IOssService ossService; + + @Autowired + public OssServiceContext(List ossServices, OssConfiguration configuration) { + if (!OssConfiguration.enable) { + return; + } + this.ossService = ossServices.stream() + .filter(ossService -> ossService.getOssType() == OssConfiguration.provider) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Oss提供程序非法。可选: " + + Arrays.toString(Arrays.stream(OssTypeEnum.values()).map(OssTypeEnum::getType).toArray()))); + } + + IOssService getOssService() { + return this.ossService; + } + + public CredentialsToken getCredentials() { + return this.ossService.getCredentials(); + } + + public URL getObjectUrl(String bucket, String objectKey) { + if (!StringUtils.hasText(bucket) || !StringUtils.hasText(objectKey)) { + throw new IllegalArgumentException(); + } + return this.ossService.getObjectUrl(bucket, objectKey); + } + + public Boolean deleteObject(String bucket, String objectKey) { + return this.ossService.deleteObject(bucket, 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); + } + + void createClient() { + this.ossService.createClient(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/redis/RedisConfiguration.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/redis/RedisConfiguration.java new file mode 100644 index 0000000..f73261e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/redis/RedisConfiguration.java @@ -0,0 +1,63 @@ +package com.dji.sample.component.redis; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/19 + */ +@Configuration +@EnableRedisRepositories +public class RedisConfiguration { + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(factory); + + ObjectMapper objectMapper = new ObjectMapper(); + JavaTimeModule timeModule = new JavaTimeModule(); + timeModule.addDeserializer(LocalDateTime.class, + new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + timeModule.addSerializer(LocalDateTime.class, + new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + objectMapper.disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS); + objectMapper.registerModules(timeModule); + objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), + ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); + + objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + + + StringRedisSerializer serializer = new StringRedisSerializer(); + redisTemplate.setKeySerializer(serializer); + redisTemplate.setHashKeySerializer(serializer); + + GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper); + redisTemplate.setValueSerializer(jsonRedisSerializer); + redisTemplate.setHashValueSerializer(jsonRedisSerializer); + redisTemplate.afterPropertiesSet(); + return redisTemplate; + + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/redis/RedisConst.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/redis/RedisConst.java new file mode 100644 index 0000000..a2b2523 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/redis/RedisConst.java @@ -0,0 +1,65 @@ +package com.dji.sample.component.redis; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/21 + */ +public final class RedisConst { + + public static final int WAYLINE_JOB_BLOCK_TIME = 600; + + private RedisConst() { + + } + + public static final String DELIMITER = ":"; + + public static final Integer DEVICE_ALIVE_SECOND = 60; + + public static final Integer WEBSOCKET_ALIVE_SECOND = 60 * 60 * 24; + + public static final String DEVICE_ONLINE_PREFIX = "online" + DELIMITER; + + public static final String WEBSOCKET_PREFIX = "webSocket" + DELIMITER; + + public static final String WEBSOCKET_ALL = WEBSOCKET_PREFIX + "all"; + + public static final String HMS_PREFIX = "hms" + DELIMITER; + + public static final String FIRMWARE_UPGRADING_PREFIX = "upgrading" + DELIMITER; + + public static final String STATE_PAYLOAD_PREFIX = "payload" + DELIMITER; + + public static final String LOGS_FILE_PREFIX = "logs_file" + DELIMITER; + + public static final String WAYLINE_JOB_TIMED_EXECUTE = "wayline_job_timed_execute"; + + public static final String WAYLINE_JOB_CONDITION_PREPARE = "wayline_job_condition_prepare"; + + public static final String WAYLINE_JOB_CONDITION_PREFIX = WAYLINE_JOB_CONDITION_PREPARE + DELIMITER; + + public static final String WAYLINE_JOB_BLOCK_PREFIX = "wayline_job_block" + DELIMITER; + + public static final String WAYLINE_JOB_RUNNING_PREFIX = "wayline_job_running" + DELIMITER; + + public static final String WAYLINE_JOB_PAUSED_PREFIX = "wayline_job_paused" + DELIMITER; + + public static final String OSD_PREFIX = "osd" + DELIMITER; + + public static final String MEDIA_FILE_PREFIX = "media_file" + DELIMITER; + + public static final String MEDIA_HIGHEST_PRIORITY_PREFIX = "media_highest_priority" + DELIMITER; + + public static final String LIVE_CAPACITY = "live_capacity"; + + public static final String DRC_PREFIX = "drc" + DELIMITER; + + public static final Integer DRC_MODE_ALIVE_SECOND = 3600; + + public static final String MQTT_ACL_PREFIX = "mqtt_acl" + DELIMITER; + + public static final String FILE_UPLOADING_PREFIX = "file_uploading" + DELIMITER; + + public static final String DRONE_CONTROL_PREFiX = "control_source" + DELIMITER; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/redis/RedisOpsUtils.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/redis/RedisOpsUtils.java new file mode 100644 index 0000000..a3e83b3 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/redis/RedisOpsUtils.java @@ -0,0 +1,263 @@ +package com.dji.sample.component.redis; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/19 + */ +@Component +public class RedisOpsUtils { + + private static RedisTemplate redisTemplate; + + @Autowired + public void setRedisTemplate(RedisTemplate redisTemplate) { + RedisOpsUtils.redisTemplate = redisTemplate; + } + + /** + * HSET + * @param key + * @param field + * @param value + */ + public static void hashSet(String key, String field, Object value) { + redisTemplate.opsForHash().put(key, field, value); + } + + /** + * HGET + * @param key + * @param field + * @return + */ + public static Object hashGet(String key, String field) { + return redisTemplate.opsForHash().get(key, field); + } + + /** + * HKEYS + * @param key + * @return + */ + public static Set hashKeys(String key) { + return redisTemplate.opsForHash().keys(key); + } + + /** + * HEXISTS + * @param key + * @param field + * @return + */ + public static boolean hashCheck(String key, String field) { + return redisTemplate.opsForHash().hasKey(key, field); + } + + /** + * HDEL + * @param key + * @param fields + * @return + */ + public static boolean hashDel(String key, Object[] fields) { + return redisTemplate.opsForHash().delete(key, fields) > 0; + } + + /** + * HLEN + * @param key + * @return + */ + public static long hashLen(String key) { + return redisTemplate.opsForHash().size(key); + } + + /** + * EXPIRE + * @param key + * @param timeout + * @return + */ + public static boolean expireKey(String key, long timeout) { + return redisTemplate.expire(key, timeout, TimeUnit.SECONDS); + } + + /** + * SET + * @param key + * @param value + */ + public static void set(String key, Object value) { + redisTemplate.opsForValue().set(key, value); + } + + /** + * GET + * @param key + * @return + */ + public static Object get(String key) { + return redisTemplate.opsForValue().get(key); + } + + /** + * SETEX + * @param key + * @param value + * @param expire + */ + public static void setWithExpire(String key, Object value, long expire) { + redisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS); + } + + /** + * TTL + * @param key + * @return + */ + public static long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * EXISTS + * @param key + * @return + */ + public static boolean checkExist(String key) { + return redisTemplate.hasKey(key); + } + + /** + * DEL + * @param key + * @return + */ + public static boolean del(String key) { + return RedisOpsUtils.checkExist(key) && redisTemplate.delete(key); + } + + /** + * KEYS + * @param pattern + * @return + */ + public static Set getAllKeys(String pattern) { + return redisTemplate.keys(pattern); + } + + /** + * RPUSH + * @param key + * @param value + */ + public static void listRPush(String key, Object... value) { + if (value.length == 0) { + return; + } + for (Object val : value) { + redisTemplate.opsForList().rightPush(key, val); + } + } + + /** + * LRANGE + * @param key + * @param start + * @param end + * @return + */ + public static List listGet(String key, long start, long end) { + return redisTemplate.opsForList().range(key, start, end); + } + + /** + * LRANGE + * @param key + * @return + */ + public static List listGetAll(String key) { + return redisTemplate.opsForList().range(key, 0, -1); + } + + /** + * LLen + * @param key + * @return + */ + public static Long listLen(String key) { + return redisTemplate.opsForList().size(key); + } + + /** + * ZADD + * @param key + * @param value + * @param score + */ + public static Boolean zAdd(String key, Object value, double score) { + return redisTemplate.opsForZSet().add(key, value, score); + } + + /** + * ZREM + * @param key + * @param value + */ + public static Boolean zRemove(String key, Object... value) { + return redisTemplate.opsForZSet().remove(key, value) > 0; + } + /** + * ZRANGE + * @param key + * @param start + * @param end + * @return + */ + public static Set zRange(String key, long start, long end) { + return redisTemplate.opsForZSet().range(key, start, end); + } + + /** + * ZRANGE + * @param key + * @return + */ + public static Object zGetMin(String key) { + Set objects = zRange(key, 0, 0); + if (CollectionUtils.isEmpty(objects)) { + return null; + } + return objects.iterator().next(); + } + + /** + * ZSCORE + * @param key + * @param value + * @return + */ + public static Double zScore(String key, Object value) { + return redisTemplate.opsForZSet().score(key, value); + } + + /** + * ZINCRBY + * @param key + * @param value + * @param delta + */ + public static Double zIncrement(String key, Object value, double delta) { + return redisTemplate.opsForZSet().incrementScore(key, value, delta); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/AuthPrincipalHandler.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/AuthPrincipalHandler.java new file mode 100644 index 0000000..05fbd2d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/AuthPrincipalHandler.java @@ -0,0 +1,70 @@ +package com.dji.sample.component.websocket.config; + +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.common.util.JwtUtil; +import com.dji.sample.component.AuthInterceptor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServletServerHttpRequest; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.server.support.DefaultHandshakeHandler; + +import javax.servlet.http.HttpServletRequest; +import java.security.Principal; +import java.util.Map; +import java.util.Optional; + +/** + * @author sean.zhou + * @date 2021/11/16 + * @version 0.1 + */ +@Slf4j +@Component +public class AuthPrincipalHandler extends DefaultHandshakeHandler { + + @Override + protected boolean isValidOrigin(ServerHttpRequest request) { + + if (request instanceof ServletServerHttpRequest) { + HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest(); + String token = servletRequest.getParameter(AuthInterceptor.PARAM_TOKEN); + + if (!StringUtils.hasText(token)) { + return false; + } + log.debug("token:" + token); + Optional customClaim = JwtUtil.parseToken(token); + if (customClaim.isEmpty()) { + return false; + } + + servletRequest.setAttribute(AuthInterceptor.TOKEN_CLAIM, customClaim.get()); + return true; + } + return false; + + } + + /** + * The principal's name: {workspaceId}/{userType}/{userId} + * @param request + * @param wsHandler + * @param attributes + * @return + */ + @Override + protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map attributes) { + if (request instanceof ServletServerHttpRequest) { + + // get the custom claim + CustomClaim claim = (CustomClaim) ((ServletServerHttpRequest) request).getServletRequest() + .getAttribute(AuthInterceptor.TOKEN_CLAIM); + + return () -> claim.getWorkspaceId() + "/" + claim.getUserType() + "/" + claim.getId(); + } + return () -> null; + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/MyConcurrentWebSocketSession.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/MyConcurrentWebSocketSession.java new file mode 100644 index 0000000..6941064 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/MyConcurrentWebSocketSession.java @@ -0,0 +1,25 @@ +package com.dji.sample.component.websocket.config; + +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/24 + */ +public class MyConcurrentWebSocketSession extends ConcurrentWebSocketSessionDecorator { + + private static final int SEND_BUFFER_SIZE_LIMIT = 1024 * 1024; + + private static final int SEND_TIME_LIMIT = 1000; + + private MyConcurrentWebSocketSession(WebSocketSession delegate, int sendTimeLimit, int bufferSizeLimit) { + super(delegate, sendTimeLimit, bufferSizeLimit); + } + + MyConcurrentWebSocketSession(WebSocketSession delegate) { + this(delegate, SEND_TIME_LIMIT, SEND_BUFFER_SIZE_LIMIT); + } + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/MyWebSocketFactory.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/MyWebSocketFactory.java new file mode 100644 index 0000000..22fb995 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/MyWebSocketFactory.java @@ -0,0 +1,27 @@ +package com.dji.sample.component.websocket.config; + +import com.dji.sample.component.websocket.service.IWebSocketManageService; +import com.dji.sdk.websocket.WebSocketDefaultFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; +import org.springframework.web.socket.WebSocketHandler; + +/** + * + * @author sean.zhou + * @date 2021/11/16 + * @version 0.1 + */ +@Component +@Primary +public class MyWebSocketFactory extends WebSocketDefaultFactory { + + @Autowired + private IWebSocketManageService webSocketManageService; + + @Override + public WebSocketHandler decorate(WebSocketHandler handler) { + return new MyWebSocketHandler(handler, webSocketManageService); + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/MyWebSocketHandler.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/MyWebSocketHandler.java new file mode 100644 index 0000000..d6016b0 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/config/MyWebSocketHandler.java @@ -0,0 +1,58 @@ +package com.dji.sample.component.websocket.config; + +import com.dji.sample.component.websocket.service.IWebSocketManageService; +import com.dji.sdk.websocket.WebSocketDefaultHandler; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.StringUtils; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.WebSocketMessage; +import org.springframework.web.socket.WebSocketSession; + +import java.security.Principal; + +/** + * + * @author sean.zhou + * @date 2021/11/16 + * @version 0.1 + */ +@Slf4j +public class MyWebSocketHandler extends WebSocketDefaultHandler { + + private IWebSocketManageService webSocketManageService; + + MyWebSocketHandler(WebSocketHandler delegate, IWebSocketManageService webSocketManageService) { + super(delegate); + this.webSocketManageService = webSocketManageService; + } + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + Principal principal = session.getPrincipal(); + if (StringUtils.hasText(principal.getName())) { + webSocketManageService.put(principal.getName(), new MyConcurrentWebSocketSession(session)); + log.debug("{} is connected. ID: {}. WebSocketSession[current count: {}]", + principal.getName(), session.getId(), webSocketManageService.getConnectedCount()); + return; + } + session.close(); + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { + Principal principal = session.getPrincipal(); + if (StringUtils.hasText(principal.getName())) { + webSocketManageService.remove(principal.getName(), session.getId()); + log.debug("{} is disconnected. ID: {}. WebSocketSession[current count: {}]", + principal.getName(), session.getId(), webSocketManageService.getConnectedCount()); + } + + } + + @Override + public void handleMessage(WebSocketSession session, WebSocketMessage message) throws Exception { + log.debug("received message: {}", message.getPayload()); + } + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/model/BizCodeEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/model/BizCodeEnum.java new file mode 100644 index 0000000..2e5c630 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/model/BizCodeEnum.java @@ -0,0 +1,93 @@ +package com.dji.sample.component.websocket.model; + +/** + * @author sean + * @version 0.1 + * @date 2021/11/26 + */ +public enum BizCodeEnum { + + DEVICE_ONLINE("device_online"), + + DEVICE_OFFLINE("device_offline"), + + DEVICE_UPDATE_TOPO("device_update_topo"), + + DEVICE_OSD("device_osd"), + + RC_OSD("gateway_osd"), + + DOCK_OSD("dock_osd"), + + MAP_ELEMENT_CREATE("map_element_create"), + + MAP_ELEMENT_UPDATE("map_element_update"), + + MAP_ELEMENT_DELETE("map_element_delete"), + + MAP_GROUP_REFRESH("map_group_refresh"), + + FLIGHT_TASK_PROGRESS("flighttask_progress"), + + DEVICE_HMS("device_hms"), + + DEVICE_REBOOT("device_reboot"), + + DRONE_OPEN("drone_open"), + + DRONE_CLOSE("drone_close"), + + DEVICE_CHECK("device_check"), + + DRONE_FORMAT("drone_format"), + + DEVICE_FORMAT("device_format"), + + COVER_OPEN("cover_open"), + + COVER_CLOSE("cover_close"), + + PUTTER_OPEN("putter_open"), + + PUTTER_CLOSE("putter_close"), + + CHARGE_OPEN("charge_open"), + + CHARGE_CLOSE("charge_close"), + + FILE_UPLOAD_CALLBACK("file_upload_callback"), + + FILE_UPLOAD_PROGRESS("fileupload_progress"), + + OTA_PROGRESS("ota_progress"), + + HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA("highest_priority_upload_flighttask_media"), + + CONTROL_SOURCE_CHANGE("control_source_change"), + + FLY_TO_POINT_PROGRESS("fly_to_point_progress"), + + TAKE_OFF_TO_POINT_PROGRESS("takeoff_to_point_progress"), + + DRC_STATUS_NOTIFY("drc_status_notify"), + + JOYSTICK_INVALID_NOTIFY("joystick_invalid_notify"), + + FLIGHT_AREAS_SYNC_PROGRESS("flight_areas_sync_progress"), + + FLIGHT_AREAS_DRONE_LOCATION("flight_areas_drone_location"), + + FLIGHT_AREAS_UPDATE("flight_areas_update"), + + ; + + private String code; + + BizCodeEnum(String code) { + this.code = code; + } + + public String getCode() { + return code; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/IWebSocketManageService.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/IWebSocketManageService.java new file mode 100644 index 0000000..21d3009 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/IWebSocketManageService.java @@ -0,0 +1,23 @@ +package com.dji.sample.component.websocket.service; + +import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession; + +import java.util.Collection; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/25 + */ +public interface IWebSocketManageService { + + void put(String key, MyConcurrentWebSocketSession val); + + void remove(String key, String sessionId); + + Collection getValueWithWorkspace(String workspaceId); + + Collection getValueWithWorkspaceAndUserType(String workspaceId, Integer userType); + + Long getConnectedCount(); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/IWebSocketMessageService.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/IWebSocketMessageService.java new file mode 100644 index 0000000..ee51adb --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/IWebSocketMessageService.java @@ -0,0 +1,32 @@ +package com.dji.sample.component.websocket.service; + +import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession; +import com.dji.sdk.websocket.WebSocketMessageResponse; + +import java.util.Collection; + +/** + * @author sean.zhou + * @date 2021/11/24 + * @version 0.1 + */ +public interface IWebSocketMessageService { + + /** + * Send a message to the specific connection. + * @param session A WebSocket connection object + * @param message message + */ + void sendMessage(MyConcurrentWebSocketSession session, WebSocketMessageResponse message); + + /** + * Send the same message to specific connection. + * @param sessions A collection of WebSocket connection objects. + * @param message message + */ + void sendBatch(Collection sessions, WebSocketMessageResponse message); + + void sendBatch(String workspaceId, Integer userType, String bizCode, Object data); + + void sendBatch(String workspaceId, String bizCode, Object data); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/impl/WebSocketManageServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/impl/WebSocketManageServiceImpl.java new file mode 100644 index 0000000..755e78d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/impl/WebSocketManageServiceImpl.java @@ -0,0 +1,86 @@ +package com.dji.sample.component.websocket.service.impl; + +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession; +import com.dji.sample.component.websocket.service.IWebSocketManageService; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/25 + */ +@Slf4j +@Service +public class WebSocketManageServiceImpl implements IWebSocketManageService { + + private static final ConcurrentHashMap SESSIONS = new ConcurrentHashMap<>(16); + + @Override + public void put(String key, MyConcurrentWebSocketSession val) { + String[] name = key.split("/"); + if (name.length != 3) { + log.debug("The key is out of format. [{workspaceId}/{userType}/{userId}]"); + return; + } + String sessionId = val.getId(); + String workspaceKey = RedisConst.WEBSOCKET_PREFIX + name[0]; + String userTypeKey = RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(Integer.parseInt(name[1])).getDesc(); + RedisOpsUtils.hashSet(workspaceKey, sessionId, name[2]); + RedisOpsUtils.hashSet(userTypeKey, sessionId, name[2]); + SESSIONS.put(sessionId, val); + RedisOpsUtils.expireKey(workspaceKey, RedisConst.WEBSOCKET_ALIVE_SECOND); + RedisOpsUtils.expireKey(userTypeKey, RedisConst.WEBSOCKET_ALIVE_SECOND); + } + + @Override + public void remove(String key, String sessionId) { + String[] name = key.split("/"); + if (name.length != 3) { + log.debug("The key is out of format. [{workspaceId}/{userType}/{userId}]"); + return; + } + RedisOpsUtils.hashDel(RedisConst.WEBSOCKET_PREFIX + name[0], new String[] {sessionId}); + RedisOpsUtils.hashDel(RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(Integer.parseInt(name[1])).getDesc(), new String[] {sessionId}); + SESSIONS.remove(sessionId); + } + + @Override + public Collection getValueWithWorkspace(String workspaceId) { + if (!StringUtils.hasText(workspaceId)) { + return Collections.emptySet(); + } + String key = RedisConst.WEBSOCKET_PREFIX + workspaceId; + + return RedisOpsUtils.hashKeys(key) + .stream() + .map(SESSIONS::get) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + } + + @Override + public Collection getValueWithWorkspaceAndUserType(String workspaceId, Integer userType) { + String key = RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(userType).getDesc(); + return RedisOpsUtils.hashKeys(key) + .stream() + .map(SESSIONS::get) + .filter(getValueWithWorkspace(workspaceId)::contains) + .collect(Collectors.toSet()); + } + + @Override + public Long getConnectedCount() { + return SESSIONS.mappingCount(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/impl/WebSocketMessageServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/impl/WebSocketMessageServiceImpl.java new file mode 100644 index 0000000..3667af1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/component/websocket/service/impl/WebSocketMessageServiceImpl.java @@ -0,0 +1,99 @@ +package com.dji.sample.component.websocket.service.impl; + +import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession; +import com.dji.sample.component.websocket.service.IWebSocketManageService; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sdk.websocket.WebSocketMessageResponse; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import org.springframework.web.socket.TextMessage; + +import java.io.IOException; +import java.util.Collection; +import java.util.Objects; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/24 + */ +@Service +@Slf4j +public class WebSocketMessageServiceImpl implements IWebSocketMessageService { + + @Autowired + private ObjectMapper mapper; + + @Autowired + private IWebSocketManageService webSocketManageService; + + @Override + public void sendMessage(MyConcurrentWebSocketSession session, WebSocketMessageResponse message) { + if (session == null) { + return; + } + + try { + if (!session.isOpen()) { + session.close(); + log.debug("This session is closed."); + return; + } + + + session.sendMessage(new TextMessage(mapper.writeValueAsBytes(message))); + } catch (IOException e) { + log.info("Failed to publish the message. {}", message.toString()); + e.printStackTrace(); + } + } + + @Override + public void sendBatch(Collection sessions, WebSocketMessageResponse message) { + if (sessions.isEmpty()) { + return; + } + + try { + + TextMessage data = new TextMessage(mapper.writeValueAsBytes(message)); + + for (MyConcurrentWebSocketSession session : sessions) { + if (!session.isOpen()) { + session.close(); + log.debug("This session is closed."); + return; + } + session.sendMessage(data); + } + + } catch (IOException e) { + log.info("Failed to publish the message. {}", message.toString()); + + e.printStackTrace(); + } + } + + @Override + public void sendBatch(String workspaceId, Integer userType, String bizCode, Object data) { + if (!StringUtils.hasText(workspaceId)) { + throw new RuntimeException("工作区ID不存在。"); + } + Collection sessions = Objects.isNull(userType) ? + webSocketManageService.getValueWithWorkspace(workspaceId) : + webSocketManageService.getValueWithWorkspaceAndUserType(workspaceId, userType); + + this.sendBatch(sessions, new WebSocketMessageResponse() + .setData(Objects.requireNonNullElse(data, "")) + .setTimestamp(System.currentTimeMillis()) + .setBizCode(bizCode)); + } + + @Override + public void sendBatch(String workspaceId, String bizCode, Object data) { + this.sendBatch(workspaceId, null, bizCode, data); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/configuration/GlobalThreadPoolConfiguration.java b/dk-modules/sample/src/main/java/org/dromara/sample/configuration/GlobalThreadPoolConfiguration.java new file mode 100644 index 0000000..af7a92d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/configuration/GlobalThreadPoolConfiguration.java @@ -0,0 +1,42 @@ +package com.dji.sample.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.concurrent.*; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +@Configuration +public class GlobalThreadPoolConfiguration { + + @Value("${thread.pool.core-pool-size: 10}") + private int corePoolSize; + + @Value("${thread.pool.maximum-pool-size: 20}") + private int maximumPoolSize; + + @Value("${thread.pool.keep-alive-time: 60}") + private long keepAliveTime; + + @Value("${thread.pool.queue.capacity: 1000}") + private int capacity; + + /** + * A custom thread pool. + * @return + */ + @Bean + public Executor threadPool() { + return new ThreadPoolExecutor(corePoolSize, + maximumPoolSize, keepAliveTime, + TimeUnit.SECONDS, new LinkedBlockingQueue<>(capacity), + Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardOldestPolicy()); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/configuration/SpringBeanConfiguration.java b/dk-modules/sample/src/main/java/org/dromara/sample/configuration/SpringBeanConfiguration.java new file mode 100644 index 0000000..9bfd8ce --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/configuration/SpringBeanConfiguration.java @@ -0,0 +1,49 @@ +package com.dji.sample.configuration; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +@Configuration +public class SpringBeanConfiguration { + + @Bean +// @ConditionalOnMissingBean(ObjectMapper.class) + public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { + ObjectMapper objectMapper = builder.createXmlMapper(false).build(); + objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + + JavaTimeModule timeModule = new JavaTimeModule(); + timeModule.addDeserializer(LocalDateTime.class, + new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + timeModule.addSerializer(LocalDateTime.class, + new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + + objectMapper.disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS); + objectMapper.registerModules(timeModule); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); + objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); + objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true); + objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer() { + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(""); + } + }); + return objectMapper; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/configuration/mvc/GlobalMVCConfigurer.java b/dk-modules/sample/src/main/java/org/dromara/sample/configuration/mvc/GlobalMVCConfigurer.java new file mode 100644 index 0000000..bb03a1d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/configuration/mvc/GlobalMVCConfigurer.java @@ -0,0 +1,40 @@ +package com.dji.sample.configuration.mvc; + +import com.dji.sample.component.AuthInterceptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.ArrayList; +import java.util.List; + +@Configuration +public class GlobalMVCConfigurer implements WebMvcConfigurer { + + @Autowired + private AuthInterceptor authInterceptor; + + private static List excludePaths = new ArrayList<>(); + + @Value("${url.manage.prefix}") + private String managePrefix; + + @Value("${url.manage.version}") + private String manageVersion; + + + @Override + public void addInterceptors(InterceptorRegistry registry) { + // Exclude the login interface. + excludePaths.add("/" + managePrefix + manageVersion + "/login"); + excludePaths.add("/" + managePrefix + manageVersion + "/token/refresh"); + excludePaths.add("/swagger-ui.html"); + excludePaths.add("/swagger-ui/**"); + excludePaths.add("/v3/**"); + excludePaths.add("/ui/**"); + // Intercept for all request interfaces. + registry.addInterceptor(authInterceptor).addPathPatterns("/**").excludePathPatterns(excludePaths); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/controller/DockController.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/controller/DockController.java new file mode 100644 index 0000000..dd55cbe --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/controller/DockController.java @@ -0,0 +1,68 @@ +package com.dji.sample.control.controller; + +import com.dji.sample.control.model.enums.DroneAuthorityEnum; +import com.dji.sample.control.model.enums.RemoteDebugMethodEnum; +import com.dji.sample.control.model.param.*; +import com.dji.sample.control.service.IControlService; +import com.dji.sdk.common.HttpResultResponse; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * @author sean + * @version 1.2 + * @date 2022/7/29 + */ +@RestController +@Slf4j +@RequestMapping("${url.control.prefix}${url.control.version}/devices") +public class DockController { + + @Autowired + private IControlService controlService; + + @PostMapping("/{sn}/jobs/{service_identifier}") + public HttpResultResponse createControlJob(@PathVariable String sn, + @PathVariable("service_identifier") String serviceIdentifier, + @Valid @RequestBody(required = false) RemoteDebugParam param) { + return controlService.controlDockDebug(sn, RemoteDebugMethodEnum.find(serviceIdentifier), param); + } + + @PostMapping("/{sn}/jobs/fly-to-point") + public HttpResultResponse flyToPoint(@PathVariable String sn, @Valid @RequestBody FlyToPointParam param) { + return controlService.flyToPoint(sn, param); + } + + @DeleteMapping("/{sn}/jobs/fly-to-point") + public HttpResultResponse flyToPointStop(@PathVariable String sn) { + return controlService.flyToPointStop(sn); + } + + @PostMapping("/{sn}/jobs/takeoff-to-point") + public HttpResultResponse takeoffToPoint(@PathVariable String sn, @Valid @RequestBody TakeoffToPointParam param) { + return controlService.takeoffToPoint(sn, param); + } + + @PostMapping("/{sn}/authority/flight") + public HttpResultResponse seizeFlightAuthority(@PathVariable String sn) { + return controlService.seizeAuthority(sn, DroneAuthorityEnum.FLIGHT, null); + } + + @PostMapping("/{sn}/authority/payload") + public HttpResultResponse seizePayloadAuthority(@PathVariable String sn, @Valid @RequestBody DronePayloadParam param) { + return controlService.seizeAuthority(sn, DroneAuthorityEnum.PAYLOAD, param); + } + + @PostMapping("/{sn}/payload/commands") + public HttpResultResponse payloadCommands(@PathVariable String sn, @Valid @RequestBody PayloadCommandsParam param) throws Exception { + param.setSn(sn); + return controlService.payloadCommands(param); + } + + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/controller/DrcController.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/controller/DrcController.java new file mode 100644 index 0000000..f40670c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/controller/DrcController.java @@ -0,0 +1,55 @@ +package com.dji.sample.control.controller; + +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.control.model.dto.JwtAclDTO; +import com.dji.sample.control.model.param.DrcConnectParam; +import com.dji.sample.control.model.param.DrcModeParam; +import com.dji.sample.control.service.IDrcService; +import com.dji.sdk.cloudapi.control.DrcModeMqttBroker; +import com.dji.sdk.common.HttpResultResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/11 + */ +@RestController +@Slf4j +@RequestMapping("${url.control.prefix}${url.control.version}") +public class DrcController { + + @Autowired + private IDrcService drcService; + + @PostMapping("/workspaces/{workspace_id}/drc/connect") + public HttpResultResponse drcConnect(@PathVariable("workspace_id") String workspaceId, HttpServletRequest request, @Valid @RequestBody DrcConnectParam param) { + CustomClaim claims = (CustomClaim) request.getAttribute(TOKEN_CLAIM); + + DrcModeMqttBroker brokerDTO = drcService.userDrcAuth(workspaceId, claims.getId(), claims.getUsername(), param); + return HttpResultResponse.success(brokerDTO); + } + + @PostMapping("/workspaces/{workspace_id}/drc/enter") + public HttpResultResponse drcEnter(@PathVariable("workspace_id") String workspaceId, @Valid @RequestBody DrcModeParam param) { + JwtAclDTO acl = drcService.deviceDrcEnter(workspaceId, param); + + return HttpResultResponse.success(acl); + } + + @PostMapping("/workspaces/{workspace_id}/drc/exit") + public HttpResultResponse drcExit(@PathVariable("workspace_id") String workspaceId, @Valid @RequestBody DrcModeParam param) { + drcService.deviceDrcExit(workspaceId, param); + + return HttpResultResponse.success(); + } + + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/AirConditionerMode.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/AirConditionerMode.java new file mode 100644 index 0000000..901cccd --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/AirConditionerMode.java @@ -0,0 +1,22 @@ +package com.dji.sample.control.model.dto; + +import com.dji.sample.control.service.impl.RemoteDebugHandler; +import com.dji.sdk.cloudapi.device.AirConditionerStateEnum; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AirConditionerMode extends RemoteDebugHandler { + + private AirConditionerStateEnum action; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/AlarmState.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/AlarmState.java new file mode 100644 index 0000000..62cf797 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/AlarmState.java @@ -0,0 +1,23 @@ +package com.dji.sample.control.model.dto; + +import com.dji.sample.control.service.impl.RemoteDebugHandler; +import com.dji.sdk.cloudapi.device.SwitchActionEnum; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AlarmState extends RemoteDebugHandler { + + private SwitchActionEnum action; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/BatteryStoreMode.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/BatteryStoreMode.java new file mode 100644 index 0000000..871d29c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/BatteryStoreMode.java @@ -0,0 +1,22 @@ +package com.dji.sample.control.model.dto; + +import com.dji.sample.control.service.impl.RemoteDebugHandler; +import com.dji.sdk.cloudapi.device.BatteryStoreModeEnum; +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 BatteryStoreMode extends RemoteDebugHandler { + + private BatteryStoreModeEnum action; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/JwtAclDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/JwtAclDTO.java new file mode 100644 index 0000000..9bc6959 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/JwtAclDTO.java @@ -0,0 +1,26 @@ +package com.dji.sample.control.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/12 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class JwtAclDTO { + + private List sub; + + private List pub; + + private List all; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/LinkWorkMode.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/LinkWorkMode.java new file mode 100644 index 0000000..599e5d6 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/LinkWorkMode.java @@ -0,0 +1,35 @@ +package com.dji.sample.control.model.dto; + +import com.dji.sample.control.service.impl.RemoteDebugHandler; +import com.dji.sdk.cloudapi.device.LinkWorkModeEnum; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.Map; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@NoArgsConstructor +public class LinkWorkMode extends RemoteDebugHandler { + + private LinkWorkModeEnum linkWorkMode; + + @JsonCreator + public LinkWorkMode(@JsonProperty("action") Integer linkWorkMode) { + this.linkWorkMode = LinkWorkModeEnum.find(linkWorkMode); + } + + @JsonValue + public Map toMap() { + return Map.of("link_workmode", linkWorkMode.getMode()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/RemoteDebugOpenState.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/RemoteDebugOpenState.java new file mode 100644 index 0000000..3e67a3e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/RemoteDebugOpenState.java @@ -0,0 +1,25 @@ +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.service.IDeviceService; +import com.dji.sdk.cloudapi.device.DockModeCodeEnum; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/14 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class RemoteDebugOpenState extends RemoteDebugHandler { + + @Override + public boolean canPublish(String sn) { + IDeviceService deviceService = SpringBeanUtilsTest.getBean(IDeviceService.class); + DockModeCodeEnum dockMode = deviceService.getDockMode(sn); + return DockModeCodeEnum.IDLE == dockMode; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/ResultNotifyDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/ResultNotifyDTO.java new file mode 100644 index 0000000..0de9461 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/ResultNotifyDTO.java @@ -0,0 +1,24 @@ +package com.dji.sample.control.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ResultNotifyDTO { + + private Integer result; + + private String message; + + private String sn; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/ReturnHomeCancelState.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/ReturnHomeCancelState.java new file mode 100644 index 0000000..73b203f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/ReturnHomeCancelState.java @@ -0,0 +1,28 @@ +package com.dji.sample.control.model.dto; + +import com.dji.sample.common.util.SpringBeanUtilsTest; +import com.dji.sample.control.service.impl.RemoteDebugHandler; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.device.DroneModeCodeEnum; +import com.dji.sdk.cloudapi.device.OsdDockDrone; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/19 + */ + +public class ReturnHomeCancelState extends RemoteDebugHandler { + + @Override + public boolean canPublish(String sn) { + IDeviceRedisService deviceRedisService = SpringBeanUtilsTest.getBean(IDeviceRedisService.class); + return deviceRedisService.getDeviceOnline(sn) + .map(DeviceDTO::getChildDeviceSn) + .flatMap(deviceSn -> deviceRedisService.getDeviceOsd(deviceSn, OsdDockDrone.class)) + .map(osd -> DroneModeCodeEnum.RETURN_AUTO == osd.getModeCode()) + .orElse(false); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/ReturnHomeState.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/ReturnHomeState.java new file mode 100644 index 0000000..a30f125 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/dto/ReturnHomeState.java @@ -0,0 +1,34 @@ +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 ReturnHomeState 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 -> osd.getElevation() > 0 && modeCodeCanReturnHome(osd.getModeCode())) + .orElse(false); + } + + private boolean modeCodeCanReturnHome(DroneModeCodeEnum modeCode) { + return DroneModeCodeEnum.TAKEOFF_FINISHED == modeCode || DroneModeCodeEnum.TAKEOFF_AUTO == modeCode + || DroneModeCodeEnum.WAYLINE == modeCode || DroneModeCodeEnum.PANORAMIC_SHOT == modeCode + || DroneModeCodeEnum.ACTIVE_TRACK == modeCode || DroneModeCodeEnum.APAS == modeCode + || DroneModeCodeEnum.VIRTUAL_JOYSTICK == modeCode || DroneModeCodeEnum.MANUAL == modeCode; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/CameraModeEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/CameraModeEnum.java new file mode 100644 index 0000000..a6dfe3c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/CameraModeEnum.java @@ -0,0 +1,26 @@ +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/3/3 + */ +public enum CameraModeEnum { + + PHOTO, VIDEO; + + @JsonValue + public int getVal() { + return ordinal(); + } + + @JsonCreator + public static CameraModeEnum find(int val) { + return Arrays.stream(values()).filter(modeEnum -> modeEnum.ordinal() == val).findAny().get(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/DrcMethodEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/DrcMethodEnum.java new file mode 100644 index 0000000..93697d7 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/DrcMethodEnum.java @@ -0,0 +1,22 @@ +package com.dji.sample.control.model.enums; + +import lombok.Getter; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/11 + */ +@Getter +public enum DrcMethodEnum { + + DRC_MODE_ENTER("drc_mode_enter"), + + DRC_MODE_EXIT("drc_mode_exit"); + + String method; + + DrcMethodEnum(String method) { + this.method = method; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/DroneAuthorityEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/DroneAuthorityEnum.java new file mode 100644 index 0000000..e751f7e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/DroneAuthorityEnum.java @@ -0,0 +1,25 @@ +package com.dji.sample.control.model.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +public enum DroneAuthorityEnum { + + FLIGHT(1), PAYLOAD(2); + + int val; + + DroneAuthorityEnum(int val) { + this.val = val; + } + + @JsonValue + public int getVal() { + return val; + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/DroneControlMethodEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/DroneControlMethodEnum.java new file mode 100644 index 0000000..dcb6a21 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/DroneControlMethodEnum.java @@ -0,0 +1,28 @@ +package com.dji.sample.control.model.enums; + +import lombok.Getter; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/21 + */ +@Getter +public enum DroneControlMethodEnum { + + FLIGHT_AUTHORITY_GRAB("flight_authority_grab"), + + PAYLOAD_AUTHORITY_GRAB("payload_authority_grab"), + + FLY_TO_POINT("fly_to_point"), + + FLY_TO_POINT_STOP("fly_to_point_stop"), + + TAKE_OFF_TO_POINT("takeoff_to_point"); + + String method; + + DroneControlMethodEnum(String method) { + this.method = method; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/GimbalResetModeEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/GimbalResetModeEnum.java new file mode 100644 index 0000000..2c7e9dd --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/GimbalResetModeEnum.java @@ -0,0 +1,26 @@ +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/3/13 + */ +public enum GimbalResetModeEnum { + + RECENTER, DOWN, RECENTER_PAN, PITCH_DOWN; + + @JsonValue + public int getVal() { + return ordinal(); + } + + @JsonCreator + public static GimbalResetModeEnum find(int value) { + return Arrays.stream(values()).filter(resetModeEnum -> resetModeEnum.ordinal() == value).findAny().get(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/MqttAclAccessEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/MqttAclAccessEnum.java new file mode 100644 index 0000000..771e4dc --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/MqttAclAccessEnum.java @@ -0,0 +1,24 @@ +package com.dji.sample.control.model.enums; + +import lombok.Getter; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/13 + */ +@Getter +public enum MqttAclAccessEnum { + + SUB(1), + + PUB(2), + + ALL(3); + + int value; + + MqttAclAccessEnum(int value) { + this.value = value; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/PayloadCommandsEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/PayloadCommandsEnum.java new file mode 100644 index 0000000..6629f8c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/PayloadCommandsEnum.java @@ -0,0 +1,58 @@ +package com.dji.sample.control.model.enums; + +import com.dji.sample.control.service.impl.*; +import com.dji.sdk.cloudapi.control.PayloadControlMethodEnum; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/2 + */ +public enum PayloadCommandsEnum { + + CAMERA_MODE_SWitCH(PayloadControlMethodEnum.CAMERA_MODE_SWITCH, CameraModeSwitchImpl.class), + + CAMERA_PHOTO_TAKE(PayloadControlMethodEnum.CAMERA_PHOTO_TAKE, CameraPhotoTakeImpl.class), + + CAMERA_RECORDING_START(PayloadControlMethodEnum.CAMERA_RECORDING_START, CameraRecordingStartImpl.class), + + CAMERA_RECORDING_STOP(PayloadControlMethodEnum.CAMERA_RECORDING_STOP, CameraRecordingStopImpl.class), + + CAMERA_AIM(PayloadControlMethodEnum.CAMERA_AIM, CameraAimImpl.class), + + CAMERA_FOCAL_LENGTH_SET(PayloadControlMethodEnum.CAMERA_FOCAL_LENGTH_SET, CameraFocalLengthSetImpl.class), + + GIMBAL_RESET(PayloadControlMethodEnum.GIMBAL_RESET, GimbalResetImpl.class); + + PayloadControlMethodEnum cmd; + + Class clazz; + + PayloadCommandsEnum(PayloadControlMethodEnum cmd, Class clazz) { + this.cmd = cmd; + this.clazz = clazz; + } + + @JsonValue + public String getMethod() { + return cmd.getPayloadMethod().getMethod(); + } + + public Class getClazz() { + return clazz; + } + + public PayloadControlMethodEnum getCmd() { + return cmd; + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static PayloadCommandsEnum find(String method) { + return Arrays.stream(values()).filter(methodEnum -> methodEnum.cmd.getPayloadMethod().getMethod().equals(method)).findAny() + .orElseThrow(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/RemoteDebugMethodEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/RemoteDebugMethodEnum.java new file mode 100644 index 0000000..b4b63f1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/enums/RemoteDebugMethodEnum.java @@ -0,0 +1,96 @@ +package com.dji.sample.control.model.enums; + +import com.dji.sample.control.model.dto.*; +import com.dji.sample.control.service.impl.RemoteDebugHandler; +import com.dji.sdk.cloudapi.debug.DebugMethodEnum; +import com.fasterxml.jackson.annotation.JsonCreator; +import lombok.Getter; + +import java.util.Arrays; +import java.util.Objects; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +@Getter +public enum RemoteDebugMethodEnum { + + DEBUG_MODE_OPEN(DebugMethodEnum.DEBUG_MODE_OPEN, false, RemoteDebugOpenState.class), + + DEBUG_MODE_CLOSE(DebugMethodEnum.DEBUG_MODE_CLOSE, false, null), + + SUPPLEMENT_LIGHT_OPEN(DebugMethodEnum.SUPPLEMENT_LIGHT_OPEN, false, null), + + SUPPLEMENT_LIGHT_CLOSE(DebugMethodEnum.SUPPLEMENT_LIGHT_CLOSE, false, null), + + RETURN_HOME("return_home", false, ReturnHomeState.class), + + RETURN_HOME_CANCEL("return_home_cancel", false, ReturnHomeCancelState.class), + + DEVICE_REBOOT(DebugMethodEnum.DEVICE_REBOOT, true, null), + + DRONE_OPEN(DebugMethodEnum.DRONE_OPEN, true, null), + + DRONE_CLOSE(DebugMethodEnum.DRONE_CLOSE, true, null), + + DRONE_FORMAT(DebugMethodEnum.DRONE_FORMAT, true, null), + + DEVICE_FORMAT(DebugMethodEnum.DEVICE_FORMAT, true, null), + + COVER_OPEN(DebugMethodEnum.COVER_OPEN, true, null), + + COVER_CLOSE(DebugMethodEnum.COVER_CLOSE, true, null), + + PUTTER_OPEN(DebugMethodEnum.PUTTER_OPEN, true, null), + + PUTTER_CLOSE(DebugMethodEnum.PUTTER_CLOSE, true, null), + + CHARGE_OPEN(DebugMethodEnum.CHARGE_OPEN, true, null), + + CHARGE_CLOSE(DebugMethodEnum.CHARGE_CLOSE, true, null), + + BATTERY_MAINTENANCE_SWITCH(DebugMethodEnum.BATTERY_MAINTENANCE_SWITCH, false, AlarmState.class), + + ALARM_STATE_SWITCH(DebugMethodEnum.ALARM_STATE_SWITCH, false, AlarmState.class), + + BATTERY_STORE_MODE_SWITCH(DebugMethodEnum.BATTERY_STORE_MODE_SWITCH, false, BatteryStoreMode.class), + + SDR_WORK_MODE_SWITCH(DebugMethodEnum.SDR_WORKMODE_SWITCH, false, LinkWorkMode.class), + + AIR_CONDITIONER_MODE_SWITCH(DebugMethodEnum.AIR_CONDITIONER_MODE_SWITCH, false, AirConditionerMode.class); + + private DebugMethodEnum debugMethodEnum; + + private String method; + + private boolean progress; + + private Class clazz; + + RemoteDebugMethodEnum(DebugMethodEnum debugMethodEnum, boolean progress, Class clazz) { + this.debugMethodEnum = debugMethodEnum; + this.progress = progress; + this.clazz = clazz; + this.method = debugMethodEnum.getMethod(); + } + + RemoteDebugMethodEnum(String method, boolean progress, Class clazz) { + this.debugMethodEnum = null; + this.progress = progress; + this.clazz = clazz; + this.method = method; + } + + @JsonCreator + public static RemoteDebugMethodEnum find(String method) { + return Arrays.stream(values()) + .filter(methodEnum -> methodEnum.method.equals(method) + || (Objects.nonNull(methodEnum.debugMethodEnum) + && methodEnum.debugMethodEnum.getMethod().equals(method))) + .findAny() + .orElseThrow(); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DeviceDrcInfoParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DeviceDrcInfoParam.java new file mode 100644 index 0000000..05930f0 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DeviceDrcInfoParam.java @@ -0,0 +1,19 @@ +package com.dji.sample.control.model.param; + +import lombok.Data; +import org.hibernate.validator.constraints.Range; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/2 + */ +@Data +public class DeviceDrcInfoParam { + + @Range(min = 1, max = 30) + private Integer osdFrequency = 10; + + @Range(min = 1, max = 30) + private Integer hsiFrequency = 1; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DrcConnectParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DrcConnectParam.java new file mode 100644 index 0000000..3aa7926 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DrcConnectParam.java @@ -0,0 +1,19 @@ +package com.dji.sample.control.model.param; + +import com.dji.sample.component.redis.RedisConst; +import lombok.Data; +import org.hibernate.validator.constraints.Range; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/11 + */ +@Data +public class DrcConnectParam { + + private String clientId; + + @Range(min = 1800, max = 86400) + private long expireSec = RedisConst.DRC_MODE_ALIVE_SECOND; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DrcModeParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DrcModeParam.java new file mode 100644 index 0000000..d483da1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DrcModeParam.java @@ -0,0 +1,37 @@ +package com.dji.sample.control.model.param; + +import com.dji.sample.component.redis.RedisConst; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Range; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/11 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DrcModeParam { + + @NotBlank + private String clientId; + + @NotBlank + private String dockSn; + + @Range(min = 1800, max = 86400) + @Builder.Default + private long expireSec = RedisConst.DRC_MODE_ALIVE_SECOND; + + @Valid + @Builder.Default + private DeviceDrcInfoParam deviceInfo = new DeviceDrcInfoParam(); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DronePayloadParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DronePayloadParam.java new file mode 100644 index 0000000..de9aa21 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/DronePayloadParam.java @@ -0,0 +1,54 @@ +package com.dji.sample.control.model.param; + +import com.dji.sdk.cloudapi.control.CameraTypeEnum; +import com.dji.sdk.cloudapi.control.GimbalResetModeEnum; +import com.dji.sdk.cloudapi.device.CameraModeEnum; +import lombok.Data; +import org.hibernate.validator.constraints.Range; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +@Data +public class DronePayloadParam { + + @Pattern(regexp = "\\d+-\\d+-\\d+") + @NotNull + private String payloadIndex; + + private CameraTypeEnum cameraType; + + @Range(min = 2, max = 200) + private Float zoomFactor; + + private CameraModeEnum cameraMode; + + /** + * true: Lock the gimbal, the gimbal and the drone rotate together. + * false: Only the gimbal rotates, but the drone does not. + */ + private Boolean locked; + + private Double pitchSpeed; + + /** + * Only valid when locked is false. + */ + private Double yawSpeed; + + /** + * upper left corner as center point + */ + @Range(min = 0, max = 1) + private Double x; + + @Range(min = 0, max = 1) + private Double y; + + private GimbalResetModeEnum resetMode; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/FlyToPointParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/FlyToPointParam.java new file mode 100644 index 0000000..4c96423 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/FlyToPointParam.java @@ -0,0 +1,36 @@ +package com.dji.sample.control.model.param; + +import com.dji.sdk.cloudapi.control.Point; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Range; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FlyToPointParam { + + private String flyToId; + + @Range(min = 1, max = 15) + @NotNull + private Integer maxSpeed; + + /** + * The M30 series only support one point. + */ + @Size(min = 1) + @NotNull + private List<@Valid Point> points; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/PayloadCommandsParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/PayloadCommandsParam.java new file mode 100644 index 0000000..f5c4a6e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/PayloadCommandsParam.java @@ -0,0 +1,27 @@ +package com.dji.sample.control.model.param; + +import com.dji.sample.control.model.enums.PayloadCommandsEnum; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/2 + */ +@Data +public class PayloadCommandsParam { + + private String sn; + + @NotNull + @Valid + private PayloadCommandsEnum cmd; + + @Valid + @NotNull + private DronePayloadParam data; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/RemoteDebugParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/RemoteDebugParam.java new file mode 100644 index 0000000..8678d3a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/RemoteDebugParam.java @@ -0,0 +1,18 @@ +package com.dji.sample.control.model.param; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +@Data +public class RemoteDebugParam { + + @NotNull + private Integer action; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/TakeoffToPointParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/TakeoffToPointParam.java new file mode 100644 index 0000000..d2e79fc --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/model/param/TakeoffToPointParam.java @@ -0,0 +1,64 @@ +package com.dji.sample.control.model.param; + +import com.dji.sdk.cloudapi.control.CommanderFlightModeEnum; +import com.dji.sdk.cloudapi.control.CommanderModeLostActionEnum; +import com.dji.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum; +import com.dji.sdk.cloudapi.device.RcLostActionEnum; +import com.dji.sdk.cloudapi.wayline.RthModeEnum; +import lombok.Data; +import org.hibernate.validator.constraints.Range; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/1 + */ +@Data +public class TakeoffToPointParam { + + private String flightId; + + @Range(min = -180, max = 180) + @NotNull + private Double targetLongitude; + + @Range(min = -90, max = 90) + @NotNull + private Double targetLatitude; + + @Range(min = 2, max = 10000) + @NotNull + private Double targetHeight; + + @Range(min = 2, max = 1500) + @NotNull + private Double securityTakeoffHeight; + + @Range(min = 2, max = 1500) + @NotNull + private Double rthAltitude; + + @NotNull + private RcLostActionEnum rcLostAction; + + @NotNull + private ExitWaylineWhenRcLostEnum exitWaylineWhenRcLost; + + @Range(min = 1, max = 15) + @NotNull + private Double maxSpeed; + + private RthModeEnum rthMode; + + private CommanderModeLostActionEnum commanderModeLostAction; + + private CommanderFlightModeEnum commanderFlightMode; + + @Min(2) + @Max(3000) + private Float commanderFlightHeight; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/IControlService.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/IControlService.java new file mode 100644 index 0000000..d0a34ce --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/IControlService.java @@ -0,0 +1,70 @@ +package com.dji.sample.control.service; + +import com.dji.sample.control.model.enums.DroneAuthorityEnum; +import com.dji.sample.control.model.enums.RemoteDebugMethodEnum; +import com.dji.sample.control.model.param.*; +import com.dji.sdk.common.HttpResultResponse; + +/** + * @author sean + * @version 1.2 + * @date 2022/7/29 + */ +public interface IControlService { + + /** + * Remotely debug the dock via commands. + * @param sn + * @param serviceIdentifier + * @param param + * @return + */ + HttpResultResponse controlDockDebug(String sn, RemoteDebugMethodEnum serviceIdentifier, RemoteDebugParam param); + + /** + * Make the drone fly to the target point. + * @param sn + * @param param + * @return + */ + HttpResultResponse flyToPoint(String sn, FlyToPointParam param); + + /** + * End the mission of flying the drone to the target point. + * @param sn + * @return + */ + HttpResultResponse flyToPointStop(String sn); + + /** + * Handle progress result notifications for fly to target point. + * @param receiver + * @param headers + * @return + */ +// CommonTopicReceiver handleFlyToPointProgress(CommonTopicReceiver receiver, MessageHeaders headers); + + /** + * Control the drone to take off. + * @param sn + * @param param + * @return + */ + HttpResultResponse takeoffToPoint(String sn, TakeoffToPointParam param); + + /** + * Seize the control authority of the drone or the payload control authority. + * @param sn + * @param authority + * @param param + * @return + */ + HttpResultResponse seizeAuthority(String sn, DroneAuthorityEnum authority, DronePayloadParam param); + + /** + * Control the payload of the drone. + * @param param + * @return + */ + HttpResultResponse payloadCommands(PayloadCommandsParam param) throws Exception; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/IDrcService.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/IDrcService.java new file mode 100644 index 0000000..55d0b75 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/IDrcService.java @@ -0,0 +1,60 @@ +package com.dji.sample.control.service; + +import com.dji.sample.control.model.dto.JwtAclDTO; +import com.dji.sample.control.model.param.DrcConnectParam; +import com.dji.sample.control.model.param.DrcModeParam; +import com.dji.sdk.cloudapi.control.DrcModeMqttBroker; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/11 + */ +public interface IDrcService { + + /** + * Save the drc mode of dock in redis. + * @param dockSn + * @param clientId + */ + void setDrcModeInRedis(String dockSn, String clientId); + + /** + * Query the client that is controlling the dock. + * @param dockSn + * @return clientId + */ + String getDrcModeInRedis(String dockSn); + + /** + * Delete the drc mode of dock in redis. + * @param dockSn + * @return + */ + Boolean delDrcModeInRedis(String dockSn); + + /** + * Provide mqtt options for the control terminal. + * @param workspaceId + * @param userId + * @param username + * @param param + * @return + */ + DrcModeMqttBroker userDrcAuth(String workspaceId, String userId, String username, DrcConnectParam param); + + /** + * Make the dock enter drc mode. And grant relevant permissions. + * @param workspaceId + * @param param + * @return + */ + JwtAclDTO deviceDrcEnter(String workspaceId, DrcModeParam param); + + /** + * Make the dock exit drc mode. + * @param workspaceId + * @param param + */ + void deviceDrcExit(String workspaceId, DrcModeParam param); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraAimImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraAimImpl.java new file mode 100644 index 0000000..4afb448 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraAimImpl.java @@ -0,0 +1,24 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.control.model.param.DronePayloadParam; + +import java.util.Objects; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/23 + */ +public class CameraAimImpl extends PayloadCommandsHandler { + + public CameraAimImpl(DronePayloadParam param) { + super(param); + } + + @Override + public boolean valid() { + return Objects.nonNull(param.getX()) && Objects.nonNull(param.getY()) + && Objects.nonNull(param.getLocked()) && Objects.nonNull(param.getCameraType()); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraFocalLengthSetImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraFocalLengthSetImpl.java new file mode 100644 index 0000000..e37f8a3 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraFocalLengthSetImpl.java @@ -0,0 +1,42 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.control.model.param.DronePayloadParam; +import com.dji.sdk.cloudapi.control.CameraTypeEnum; +import com.dji.sdk.cloudapi.device.CameraStateEnum; + +import java.util.Objects; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/23 + */ +public class CameraFocalLengthSetImpl extends PayloadCommandsHandler { + + public CameraFocalLengthSetImpl(DronePayloadParam param) { + super(param); + } + + @Override + public boolean valid() { + return Objects.nonNull(param.getCameraType()) && Objects.nonNull(param.getZoomFactor()) + && (CameraTypeEnum.ZOOM == param.getCameraType() + || CameraTypeEnum.IR == param.getCameraType()); + } + + @Override + public boolean canPublish(String deviceSn) { + super.canPublish(deviceSn); + if (CameraStateEnum.WORKING == osdCamera.getPhotoState()) { + return false; + } + switch (param.getCameraType()) { + case IR: + return Objects.nonNull(osdCamera.getIrZoomFactor()) + && param.getZoomFactor().intValue() != osdCamera.getIrZoomFactor(); + case ZOOM: + return param.getZoomFactor().intValue() != osdCamera.getZoomFactor(); + } + return false; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraModeSwitchImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraModeSwitchImpl.java new file mode 100644 index 0000000..9d2db66 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraModeSwitchImpl.java @@ -0,0 +1,31 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.control.model.param.DronePayloadParam; +import com.dji.sdk.cloudapi.device.CameraStateEnum; + +import java.util.Objects; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/23 + */ +public class CameraModeSwitchImpl extends PayloadCommandsHandler { + + public CameraModeSwitchImpl(DronePayloadParam param) { + super(param); + } + + @Override + public boolean valid() { + return Objects.nonNull(param.getCameraMode()); + } + + @Override + public boolean canPublish(String deviceSn) { + super.canPublish(deviceSn); + return param.getCameraMode() != osdCamera.getCameraMode() + && CameraStateEnum.IDLE == osdCamera.getPhotoState() + && CameraStateEnum.IDLE == osdCamera.getRecordingState(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraPhotoTakeImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraPhotoTakeImpl.java new file mode 100644 index 0000000..d9f6bcc --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraPhotoTakeImpl.java @@ -0,0 +1,22 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.control.model.param.DronePayloadParam; +import com.dji.sdk.cloudapi.device.CameraStateEnum; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/23 + */ +public class CameraPhotoTakeImpl extends PayloadCommandsHandler { + + public CameraPhotoTakeImpl(DronePayloadParam param) { + super(param); + } + + @Override + public boolean canPublish(String deviceSn) { + super.canPublish(deviceSn); + return CameraStateEnum.WORKING != osdCamera.getPhotoState() && osdCamera.getRemainPhotoNum() > 0; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraRecordingStartImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraRecordingStartImpl.java new file mode 100644 index 0000000..0a9960b --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraRecordingStartImpl.java @@ -0,0 +1,25 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.control.model.param.DronePayloadParam; +import com.dji.sdk.cloudapi.device.CameraModeEnum; +import com.dji.sdk.cloudapi.device.CameraStateEnum; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/23 + */ +public class CameraRecordingStartImpl extends PayloadCommandsHandler { + + public CameraRecordingStartImpl(DronePayloadParam param) { + super(param); + } + + @Override + public boolean canPublish(String deviceSn) { + super.canPublish(deviceSn); + return CameraModeEnum.VIDEO == osdCamera.getCameraMode() + && CameraStateEnum.IDLE == osdCamera.getRecordingState() + && osdCamera.getRemainRecordDuration() > 0; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraRecordingStopImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraRecordingStopImpl.java new file mode 100644 index 0000000..22e59af --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/CameraRecordingStopImpl.java @@ -0,0 +1,22 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.control.model.param.DronePayloadParam; +import com.dji.sdk.cloudapi.device.CameraStateEnum; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/23 + */ +public class CameraRecordingStopImpl extends PayloadCommandsHandler { + + public CameraRecordingStopImpl(DronePayloadParam param) { + super(param); + } + + @Override + public boolean canPublish(String deviceSn) { + super.canPublish(deviceSn); + return CameraStateEnum.WORKING == osdCamera.getRecordingState(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/ControlServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/ControlServiceImpl.java new file mode 100644 index 0000000..186b415 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/ControlServiceImpl.java @@ -0,0 +1,228 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.control.model.enums.DroneAuthorityEnum; +import com.dji.sample.control.model.enums.RemoteDebugMethodEnum; +import com.dji.sample.control.model.param.*; +import com.dji.sample.control.service.IControlService; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.service.IDevicePayloadService; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sdk.cloudapi.control.FlyToPointRequest; +import com.dji.sdk.cloudapi.control.PayloadAuthorityGrabRequest; +import com.dji.sdk.cloudapi.control.TakeoffToPointRequest; +import com.dji.sdk.cloudapi.control.api.AbstractControlService; +import com.dji.sdk.cloudapi.debug.DebugMethodEnum; +import com.dji.sdk.cloudapi.debug.api.AbstractDebugService; +import com.dji.sdk.cloudapi.device.DockModeCodeEnum; +import com.dji.sdk.cloudapi.device.DroneModeCodeEnum; +import com.dji.sdk.cloudapi.device.PayloadIndex; +import com.dji.sdk.cloudapi.wayline.api.AbstractWaylineService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +/** + * @author sean + * @version 1.2 + * @date 2022/7/29 + */ +@Service +@Slf4j +public class ControlServiceImpl implements IControlService { + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private ObjectMapper mapper; + + @Autowired + private IDevicePayloadService devicePayloadService; + + @Autowired + private AbstractControlService abstractControlService; + + @Autowired + private AbstractDebugService abstractDebugService; + + @Autowired + @Qualifier("SDKWaylineService") + private AbstractWaylineService abstractWaylineService; + + private RemoteDebugHandler checkDebugCondition(String sn, RemoteDebugParam param, RemoteDebugMethodEnum controlMethodEnum) { + RemoteDebugHandler handler = Objects.nonNull(controlMethodEnum.getClazz()) ? + mapper.convertValue(Objects.nonNull(param) ? param : new Object(), controlMethodEnum.getClazz()) + : new RemoteDebugHandler(); + if (!handler.canPublish(sn)) { + throw new RuntimeException("The current state of the dock does not support this function."); + } + return handler; + } + + @Override + public HttpResultResponse controlDockDebug(String sn, RemoteDebugMethodEnum controlMethodEnum, RemoteDebugParam param) { + DebugMethodEnum methodEnum = controlMethodEnum.getDebugMethodEnum(); + RemoteDebugHandler data = checkDebugCondition(sn, param, controlMethodEnum); + + boolean isExist = deviceRedisService.checkDeviceOnline(sn); + if (!isExist) { + return HttpResultResponse.error("dock处于脱机状态。"); + } + TopicServicesResponse response; + switch (controlMethodEnum) { + case RETURN_HOME: + response = abstractWaylineService.returnHome(SDKManager.getDeviceSDK(sn)); + break; + case RETURN_HOME_CANCEL: + response = abstractWaylineService.returnHomeCancel(SDKManager.getDeviceSDK(sn)); + break; + default: + response = abstractDebugService.remoteDebug(SDKManager.getDeviceSDK(sn), methodEnum, + Objects.nonNull(methodEnum.getClazz()) ? mapper.convertValue(data, methodEnum.getClazz()) : null); + } + ServicesReplyData serviceReply = (ServicesReplyData) response.getData(); + if (!serviceReply.getResult().isSuccess()) { + return HttpResultResponse.error(serviceReply.getResult()); + } + return HttpResultResponse.success(); + } + + private void checkFlyToCondition(String dockSn) { + // TODO 设备固件版本不兼容情况 + Optional dockOpt = deviceRedisService.getDeviceOnline(dockSn); + if (dockOpt.isEmpty()) { + throw new RuntimeException("dock处于脱机状态,请重新启动dock。"); + } + + DroneModeCodeEnum deviceMode = deviceService.getDeviceMode(dockOpt.get().getChildDeviceSn()); + if (DroneModeCodeEnum.MANUAL != deviceMode) { + throw new RuntimeException("无人机的当前状态不支持此功能,请稍后再试。"); + } + + HttpResultResponse result = seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null); + if (HttpResultResponse.CODE_SUCCESS != result.getCode()) { + throw new IllegalArgumentException(result.getMessage()); + } + } + + @Override + public HttpResultResponse flyToPoint(String sn, FlyToPointParam param) { + checkFlyToCondition(sn); + + param.setFlyToId(UUID.randomUUID().toString()); + TopicServicesResponse response = abstractControlService.flyToPoint( + SDKManager.getDeviceSDK(sn), mapper.convertValue(param, FlyToPointRequest.class)); + ServicesReplyData reply = response.getData(); + return reply.getResult().isSuccess() ? + HttpResultResponse.success() + : HttpResultResponse.error("飞往目标点失败。" + reply.getResult()); + } + + @Override + public HttpResultResponse flyToPointStop(String sn) { + TopicServicesResponse response = abstractControlService.flyToPointStop(SDKManager.getDeviceSDK(sn)); + ServicesReplyData reply = response.getData(); + + return reply.getResult().isSuccess() ? + HttpResultResponse.success() + : HttpResultResponse.error("飞向目标点的无人机没有停下来。" + reply.getResult()); + } + + private void checkTakeoffCondition(String dockSn) { + Optional dockOpt = deviceRedisService.getDeviceOnline(dockSn); + if (dockOpt.isEmpty() || DockModeCodeEnum.IDLE != deviceService.getDockMode(dockSn)) { + throw new RuntimeException("当前状态不支持起飞。"); + } + + HttpResultResponse result = seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null); + if (HttpResultResponse.CODE_SUCCESS != result.getCode()) { + throw new IllegalArgumentException(result.getMessage()); + } + + } + + @Override + public HttpResultResponse takeoffToPoint(String sn, TakeoffToPointParam param) { + checkTakeoffCondition(sn); + + param.setFlightId(UUID.randomUUID().toString()); + TopicServicesResponse response = abstractControlService.takeoffToPoint( + SDKManager.getDeviceSDK(sn), mapper.convertValue(param, TakeoffToPointRequest.class)); + ServicesReplyData reply = response.getData(); + return reply.getResult().isSuccess() ? + HttpResultResponse.success() + : HttpResultResponse.error("无人机未能起飞。" + reply.getResult()); + } + + @Override + public HttpResultResponse seizeAuthority(String sn, DroneAuthorityEnum authority, DronePayloadParam param) { + TopicServicesResponse response; + switch (authority) { + case FLIGHT: + if (deviceService.checkAuthorityFlight(sn)) { + return HttpResultResponse.success(); + } + + response = abstractControlService.flightAuthorityGrab(SDKManager.getDeviceSDK(sn)); + break; + case PAYLOAD: + if (checkPayloadAuthority(sn, param.getPayloadIndex())) { + return HttpResultResponse.success(); + } + response = abstractControlService.payloadAuthorityGrab(SDKManager.getDeviceSDK(sn), + new PayloadAuthorityGrabRequest().setPayloadIndex(new PayloadIndex(param.getPayloadIndex()))); + break; + default: + return HttpResultResponse.error(CloudSDKErrorEnum.INVALID_PARAMETER); + } + + ServicesReplyData serviceReply = response.getData(); + return serviceReply.getResult().isSuccess() ? + HttpResultResponse.success() + : HttpResultResponse.error(serviceReply.getResult()); + } + + private Boolean checkPayloadAuthority(String sn, String payloadIndex) { + Optional dockOpt = deviceRedisService.getDeviceOnline(sn); + if (dockOpt.isEmpty()) { + throw new RuntimeException("dock处于脱机状态,请重新启动dock。"); + } + return devicePayloadService.checkAuthorityPayload(dockOpt.get().getChildDeviceSn(), payloadIndex); + } + + @Override + public HttpResultResponse payloadCommands(PayloadCommandsParam param) throws Exception { + param.getCmd().getClazz() + .getDeclaredConstructor(DronePayloadParam.class) + .newInstance(param.getData()) + .checkCondition(param.getSn()); + + TopicServicesResponse response = abstractControlService.payloadControl( + SDKManager.getDeviceSDK(param.getSn()), param.getCmd().getCmd(), + mapper.convertValue(param.getData(), param.getCmd().getCmd().getClazz())); + + ServicesReplyData serviceReply = response.getData(); + return serviceReply.getResult().isSuccess() ? + HttpResultResponse.success() + : HttpResultResponse.error(serviceReply.getResult()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/DrcServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/DrcServiceImpl.java new file mode 100644 index 0000000..ef65aa8 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/DrcServiceImpl.java @@ -0,0 +1,215 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.component.mqtt.config.MqttPropertyConfiguration; +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.mqtt.model.MapKeyConst; +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.control.model.dto.JwtAclDTO; +import com.dji.sample.control.model.enums.DroneAuthorityEnum; +import com.dji.sample.control.model.enums.MqttAclAccessEnum; +import com.dji.sample.control.model.param.DrcConnectParam; +import com.dji.sample.control.model.param.DrcModeParam; +import com.dji.sample.control.service.IControlService; +import com.dji.sample.control.service.IDrcService; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum; +import com.dji.sample.wayline.model.enums.WaylineTaskStatusEnum; +import com.dji.sample.wayline.model.param.UpdateJobParam; +import com.dji.sample.wayline.service.IFlightTaskService; +import com.dji.sample.wayline.service.IWaylineJobService; +import com.dji.sample.wayline.service.IWaylineRedisService; +import com.dji.sdk.cloudapi.control.DrcModeEnterRequest; +import com.dji.sdk.cloudapi.control.DrcModeMqttBroker; +import com.dji.sdk.cloudapi.control.api.AbstractControlService; +import com.dji.sdk.cloudapi.device.DockModeCodeEnum; +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.wayline.FlighttaskProgress; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.TopicConst; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * @author sean + * @version 1.3 + * @date 2023/1/11 + */ +@Service +@Slf4j +public class DrcServiceImpl implements IDrcService { + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private IWaylineJobService waylineJobService; + + @Autowired + private IFlightTaskService flighttaskService; + + @Autowired + private IDeviceService deviceService; + + @Autowired + private ObjectMapper mapper; + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IControlService controlService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private IWaylineRedisService waylineRedisService; + + @Autowired + private AbstractControlService abstractControlService; + + @Override + public void setDrcModeInRedis(String dockSn, String clientId) { + RedisOpsUtils.setWithExpire(RedisConst.DRC_PREFIX + dockSn, clientId, RedisConst.DRC_MODE_ALIVE_SECOND); + } + + @Override + public String getDrcModeInRedis(String dockSn) { + return (String) RedisOpsUtils.get(RedisConst.DRC_PREFIX + dockSn); + } + + @Override + public Boolean delDrcModeInRedis(String dockSn) { + return RedisOpsUtils.del(RedisConst.DRC_PREFIX + dockSn); + } + + @Override + public DrcModeMqttBroker userDrcAuth(String workspaceId, String userId, String username, DrcConnectParam param) { + + // refresh token + String clientId = param.getClientId(); + // first time + if (!StringUtils.hasText(clientId) || !RedisOpsUtils.checkExist(RedisConst.MQTT_ACL_PREFIX + clientId)) { + clientId = userId + "-" + System.currentTimeMillis(); + RedisOpsUtils.hashSet(RedisConst.MQTT_ACL_PREFIX + clientId, "", MqttAclAccessEnum.ALL.getValue()); + } + + String key = RedisConst.MQTT_ACL_PREFIX + clientId; + + try { + RedisOpsUtils.expireKey(key, RedisConst.DRC_MODE_ALIVE_SECOND); + + return MqttPropertyConfiguration.getMqttBrokerWithDrc( + clientId, username, param.getExpireSec(), Collections.emptyMap()); + } catch (RuntimeException e) { + RedisOpsUtils.del(key); + throw e; + } + } + + private void checkDrcModeCondition(String workspaceId, String dockSn) { + Optional> runningOpt = waylineRedisService.getRunningWaylineJob(dockSn); + if (runningOpt.isPresent() && WaylineJobStatusEnum.IN_PROGRESS == waylineJobService.getWaylineState(dockSn)) { + flighttaskService.updateJobStatus(workspaceId, runningOpt.get().getBid(), + UpdateJobParam.builder().status(WaylineTaskStatusEnum.PAUSE).build()); + } + + DockModeCodeEnum dockMode = deviceService.getDockMode(dockSn); + Optional dockOpt = deviceRedisService.getDeviceOnline(dockSn); + if (dockOpt.isPresent() && (DockModeCodeEnum.IDLE == dockMode || DockModeCodeEnum.WORKING == dockMode)) { + Optional deviceOsd = deviceRedisService.getDeviceOsd(dockOpt.get().getChildDeviceSn(), OsdDockDrone.class); + if (deviceOsd.isEmpty() || deviceOsd.get().getElevation() <= 0) { + throw new RuntimeException("无人机不在空中,无法进入命令飞行模式。"); + } + } else { + throw new RuntimeException("码头的当前状态不支持进入命令飞行模式。"); + } + + HttpResultResponse result = controlService.seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null); + if (HttpResultResponse.CODE_SUCCESS != result.getCode()) { + throw new IllegalArgumentException(result.getMessage()); + } + + } + + @Override + public JwtAclDTO deviceDrcEnter(String workspaceId, DrcModeParam param) { + String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + param.getDockSn() + TopicConst.DRC; + String pubTopic = topic + TopicConst.DOWN; + String subTopic = topic + TopicConst.UP; + + // If the dock is in drc mode, refresh the permissions directly. + if (deviceService.checkDockDrcMode(param.getDockSn()) + && param.getClientId().equals(this.getDrcModeInRedis(param.getDockSn()))) { + refreshAcl(param.getDockSn(), param.getClientId(), topic, subTopic); + return JwtAclDTO.builder().sub(List.of(subTopic)).pub(List.of(pubTopic)).build(); + } + + checkDrcModeCondition(workspaceId, param.getDockSn()); + + TopicServicesResponse reply = abstractControlService.drcModeEnter( + SDKManager.getDeviceSDK(param.getDockSn()), + new DrcModeEnterRequest() + .setMqttBroker(MqttPropertyConfiguration.getMqttBrokerWithDrc(param.getDockSn() + "-" + System.currentTimeMillis(), param.getDockSn(), + RedisConst.DRC_MODE_ALIVE_SECOND.longValue(), + Map.of(MapKeyConst.ACL, objectMapper.convertValue(JwtAclDTO.builder() + .pub(List.of(subTopic)) + .sub(List.of(pubTopic)) + .build(), new TypeReference>() {})))) + .setHsiFrequency(1).setOsdFrequency(10)); + + if (!reply.getData().getResult().isSuccess()) { + throw new RuntimeException("SN: " + param.getDockSn() + "; Error:" + reply.getData().getResult() + + "; 无法进入指令飞行控制模式,请稍后再试!"); + } + + refreshAcl(param.getDockSn(), param.getClientId(), pubTopic, subTopic); + return JwtAclDTO.builder().sub(List.of(subTopic)).pub(List.of(pubTopic)).build(); + } + + private void refreshAcl(String dockSn, String clientId, String pubTopic, String subTopic) { + this.setDrcModeInRedis(dockSn, clientId); + + // assign acl,Match by clientId. https://www.emqx.io/docs/zh/v4.4/advanced/acl-redis.html + // scheme: HSET mqtt_acl:[clientid] [topic] [access] + String key = RedisConst.MQTT_ACL_PREFIX + clientId; + RedisOpsUtils.hashSet(key, pubTopic, MqttAclAccessEnum.PUB.getValue()); + RedisOpsUtils.hashSet(key, subTopic, MqttAclAccessEnum.SUB.getValue()); + RedisOpsUtils.expireKey(key, RedisConst.DRC_MODE_ALIVE_SECOND); + } + + @Override + public void deviceDrcExit(String workspaceId, DrcModeParam param) { + TopicServicesResponse reply = + abstractControlService.drcModeExit(SDKManager.getDeviceSDK(param.getDockSn())); + if (!reply.getData().getResult().isSuccess()) { + throw new RuntimeException("SN: " + param.getDockSn() + "; Error:" + + reply.getData().getResult() + "; 退出指令飞行控制模式失败,请稍后再试!"); + } + + String jobId = waylineRedisService.getPausedWaylineJobId(param.getDockSn()); + if (StringUtils.hasText(jobId)) { + flighttaskService.updateJobStatus(workspaceId, jobId, UpdateJobParam.builder().status(WaylineTaskStatusEnum.RESUME).build()); + } + + this.delDrcModeInRedis(param.getDockSn()); + RedisOpsUtils.del(RedisConst.MQTT_ACL_PREFIX + param.getClientId()); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/GimbalResetImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/GimbalResetImpl.java new file mode 100644 index 0000000..4e7a310 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/GimbalResetImpl.java @@ -0,0 +1,22 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.control.model.param.DronePayloadParam; + +import java.util.Objects; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/23 + */ +public class GimbalResetImpl extends PayloadCommandsHandler { + public GimbalResetImpl(DronePayloadParam param) { + super(param); + } + + @Override + public boolean valid() { + return Objects.nonNull(param.getResetMode()); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/PayloadCommandsHandler.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/PayloadCommandsHandler.java new file mode 100644 index 0000000..53097be --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/PayloadCommandsHandler.java @@ -0,0 +1,82 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.common.util.SpringBeanUtilsTest; +import com.dji.sample.control.model.param.DronePayloadParam; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.service.IDevicePayloadService; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.device.OsdCamera; +import com.dji.sdk.cloudapi.device.OsdDockDrone; + +import java.util.Optional; + +/** + * @author sean + * @version 1.4 + * @date 2023/4/23 + */ +public abstract class PayloadCommandsHandler { + + DronePayloadParam param; + + OsdCamera osdCamera; + + PayloadCommandsHandler(DronePayloadParam param) { + this.param = param; + } + + public boolean valid() { + return true; + } + + public boolean canPublish(String deviceSn) { + Optional deviceOpt = SpringBeanUtilsTest.getBean(IDeviceRedisService.class) + .getDeviceOsd(deviceSn, OsdDockDrone.class); + if (deviceOpt.isEmpty()) { + throw new RuntimeException("设备脱机。"); + } + osdCamera = deviceOpt.get().getCameras().stream() + .filter(osdCamera -> param.getPayloadIndex().equals(osdCamera.getPayloadIndex().toString())) + .findAny() + .orElseThrow(() -> new RuntimeException("没有收到有关相机的osd信息,请检查缓存数据。")); + return true; + } + + private String checkDockOnline(String dockSn) { + Optional deviceOpt = SpringBeanUtilsTest.getBean(IDeviceRedisService.class).getDeviceOnline(dockSn); + if (deviceOpt.isEmpty()) { + throw new RuntimeException("机场离线。"); + } + return deviceOpt.get().getChildDeviceSn(); + } + + private void checkDeviceOnline(String deviceSn) { + boolean isOnline = SpringBeanUtilsTest.getBean(IDeviceRedisService.class).checkDeviceOnline(deviceSn); + if (!isOnline) { + throw new RuntimeException("设备脱机。"); + } + } + + private void checkAuthority(String deviceSn) { + boolean hasAuthority = SpringBeanUtilsTest.getBean(IDevicePayloadService.class) + .checkAuthorityPayload(deviceSn, param.getPayloadIndex()); + if (!hasAuthority) { + throw new RuntimeException("设备没有有效负载控制权限。"); + } + } + + public final void checkCondition(String dockSn) { + if (!valid()) { + throw new RuntimeException("非法参数"); + } + + String deviceSn = checkDockOnline(dockSn); + checkDeviceOnline(deviceSn); + checkAuthority(deviceSn); + + if (!canPublish(deviceSn)) { + throw new RuntimeException("无人机的当前状态不支持此功能,请稍后再试。"); + } + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/RemoteDebugHandler.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/RemoteDebugHandler.java new file mode 100644 index 0000000..5da1688 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/RemoteDebugHandler.java @@ -0,0 +1,23 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.common.util.SpringBeanUtilsTest; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sdk.cloudapi.device.DockModeCodeEnum; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class RemoteDebugHandler { + + public boolean valid() { + return true; + } + + public boolean canPublish(String sn) { + IDeviceService deviceService = SpringBeanUtilsTest.getBean(IDeviceService.class); + DockModeCodeEnum dockMode = deviceService.getDockMode(sn); + return DockModeCodeEnum.REMOTE_DEBUGGING == dockMode; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/SDKControlService.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/SDKControlService.java new file mode 100644 index 0000000..7401675 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/SDKControlService.java @@ -0,0 +1,118 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.control.model.dto.ResultNotifyDTO; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.control.*; +import com.dji.sdk.cloudapi.control.api.AbstractControlService; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/4 + */ +@Service +@Slf4j +public class SDKControlService extends AbstractControlService { + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private ObjectMapper mapper; + + @Override + public TopicEventsResponse flyToPointProgress(TopicEventsRequest request, MessageHeaders headers) { + String dockSn = request.getGateway(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); + if (deviceOpt.isEmpty()) { + log.error("dock处于脱机状态。"); + return null; + } + + FlyToPointProgress eventsReceiver = request.getData(); + webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.FLY_TO_POINT_PROGRESS.getCode(), + ResultNotifyDTO.builder().sn(dockSn) + .message(eventsReceiver.getResult().toString()) + .result(eventsReceiver.getResult().getCode()) + .build()); + return new TopicEventsResponse().setData(MqttReply.success()); + } + + @Override + public TopicEventsResponse takeoffToPointProgress(TopicEventsRequest request, MessageHeaders headers) { + String dockSn = request.getGateway(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); + if (deviceOpt.isEmpty()) { + log.error("dock处于脱机状态。"); + return null; + } + + TakeoffToPointProgress eventsReceiver = request.getData(); + webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.TAKE_OFF_TO_POINT_PROGRESS.getCode(), + ResultNotifyDTO.builder().sn(dockSn) + .message(eventsReceiver.getResult().toString()) + .result(eventsReceiver.getResult().getCode()) + .build()); + + return new TopicEventsResponse().setData(MqttReply.success()); + } + + @Override + public TopicEventsResponse drcStatusNotify(TopicEventsRequest request, MessageHeaders headers) { + String dockSn = request.getGateway(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); + if (deviceOpt.isEmpty()) { + return null; + } + + DrcStatusNotify eventsReceiver = request.getData(); + if (DrcStatusErrorEnum.SUCCESS != eventsReceiver.getResult()) { + webSocketMessageService.sendBatch( + deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), BizCodeEnum.DRC_STATUS_NOTIFY.getCode(), + ResultNotifyDTO.builder().sn(dockSn) + .message(eventsReceiver.getResult().getMessage()) + .result(eventsReceiver.getResult().getCode()).build()); + } + return new TopicEventsResponse().setData(MqttReply.success()); + } + + @Override + public TopicEventsResponse joystickInvalidNotify(TopicEventsRequest request, MessageHeaders headers) { + String dockSn = request.getGateway(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(dockSn); + if (deviceOpt.isEmpty()) { + return null; + } + + JoystickInvalidNotify eventsReceiver = request.getData(); + webSocketMessageService.sendBatch( + deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), BizCodeEnum.JOYSTICK_INVALID_NOTIFY.getCode(), + ResultNotifyDTO.builder().sn(dockSn) + .message(eventsReceiver.getReason().getMessage()) + .result(eventsReceiver.getReason().getVal()).build()); + return new TopicEventsResponse().setData(MqttReply.success()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/SDKRemoteDebug.java b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/SDKRemoteDebug.java new file mode 100644 index 0000000..b858454 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/control/service/impl/SDKRemoteDebug.java @@ -0,0 +1,63 @@ +package com.dji.sample.control.service.impl; + +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.debug.RemoteDebugProgress; +import com.dji.sdk.cloudapi.debug.api.AbstractDebugService; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/4 + */ +@Service +@Slf4j +public class SDKRemoteDebug extends AbstractDebugService { + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Override + public TopicEventsResponse remoteDebugProgress(TopicEventsRequest> request, MessageHeaders headers) { + String sn = request.getGateway(); + + EventsReceiver eventsReceiver = new EventsReceiver() + .setOutput(request.getData().getOutput()).setResult(request.getData().getResult()); + eventsReceiver.setBid(request.getBid()); + eventsReceiver.setSn(sn); + + log.info("SN: {}, {} ===> 控制进度: {}", sn, request.getMethod(), eventsReceiver.getOutput().getProgress()); + + if (!eventsReceiver.getResult().isSuccess()) { + log.error("SN: {}, {} ===> 错误: {}", sn, request.getMethod(), eventsReceiver.getResult()); + } + + Optional deviceOpt = deviceRedisService.getDeviceOnline(sn); + + if (deviceOpt.isEmpty()) { + throw new RuntimeException("设备处于脱机状态。"); + } + + DeviceDTO device = deviceOpt.get(); + webSocketMessageService.sendBatch(device.getWorkspaceId(), UserTypeEnum.WEB.getVal(), + request.getMethod(), eventsReceiver); + + return new TopicEventsResponse().setData(MqttReply.success()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceController.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceController.java new file mode 100644 index 0000000..7a0a7ed --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceController.java @@ -0,0 +1,144 @@ +package com.dji.sample.manage.controller; + +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.dto.DeviceFirmwareUpgradeDTO; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; +import com.dji.sdk.exception.CloudSDKErrorEnum; +import com.dji.sdk.mqtt.property.PropertySetReplyResultEnum; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/15 + */ +@RestController +@Slf4j +@RequestMapping("${url.manage.prefix}${url.manage.version}/devices") +public class DeviceController { + + @Autowired + private IDeviceService deviceService; + + /** + * Get the topology list of all online devices in one workspace. + * @param workspaceId + * @return + */ + @GetMapping("/{workspace_id}/devices") + public HttpResultResponse> getDevices(@PathVariable("workspace_id") String workspaceId) { + List devicesList = deviceService.getDevicesTopoForWeb(workspaceId); + + return HttpResultResponse.success(devicesList); + } + + /** + * After binding the device to the workspace, the device data can only be seen on the web. + * @param device + * @param deviceSn + * @return + */ + @PostMapping("/{device_sn}/binding") + public HttpResultResponse bindDevice(@RequestBody DeviceDTO device, @PathVariable("device_sn") String deviceSn) { + device.setDeviceSn(deviceSn); + boolean isUpd = deviceService.bindDevice(device); + return isUpd ? HttpResultResponse.success() : HttpResultResponse.error(); + } + + /** + * Obtain device information according to device sn. + * @param workspaceId + * @param deviceSn + * @return + */ + @GetMapping("/{workspace_id}/devices/{device_sn}") + public HttpResultResponse getDevice(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn) { + Optional deviceOpt = deviceService.getDeviceBySn(deviceSn); + return deviceOpt.isEmpty() ? HttpResultResponse.error("device not found.") : HttpResultResponse.success(deviceOpt.get()); + } + + /** + * Get the binding devices list in one workspace. + * @param workspaceId + * @param page + * @param pageSize + * @return + */ + @GetMapping("/{workspace_id}/devices/bound") + public HttpResultResponse> getBoundDevicesWithDomain( + @PathVariable("workspace_id") String workspaceId, Integer domain, + @RequestParam(defaultValue = "1") Long page, + @RequestParam(value = "page_size", defaultValue = "50") Long pageSize) { + PaginationData devices = deviceService.getBoundDevicesWithDomain(workspaceId, page, pageSize, domain); + + return HttpResultResponse.success(devices); + } + + /** + * Removing the binding state of the device. + * @param deviceSn + * @return + */ + @DeleteMapping("/{device_sn}/unbinding") + public HttpResultResponse unbindingDevice(@PathVariable("device_sn") String deviceSn) { + deviceService.unbindDevice(deviceSn); + return HttpResultResponse.success(); + } + + /** + * Update device information. + * @param device + * @param workspaceId + * @param deviceSn + * @return + */ + @PutMapping("/{workspace_id}/devices/{device_sn}") + public HttpResultResponse updateDevice(@RequestBody DeviceDTO device, + @PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn) { + device.setDeviceSn(deviceSn); + boolean isUpd = deviceService.updateDevice(device); + return isUpd ? HttpResultResponse.success() : HttpResultResponse.error(); + } + + /** + * Delivers offline firmware upgrade tasks. + * @param workspaceId + * @param upgradeDTOS + * @return + */ + @PostMapping("/{workspace_id}/devices/ota") + public HttpResultResponse createOtaJob(@PathVariable("workspace_id") String workspaceId, + @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 HttpResultResponse devicePropertySet(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String dockSn, + @RequestBody JsonNode param) { + if (param.size() != 1) { + return HttpResultResponse.error(CloudSDKErrorEnum.INVALID_PARAMETER); + } + + int result = deviceService.devicePropertySet(workspaceId, dockSn, param); + return PropertySetReplyResultEnum.SUCCESS.getResult() == result ? + HttpResultResponse.success() : HttpResultResponse.error(result, String.valueOf(result)); + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceFirmwareController.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceFirmwareController.java new file mode 100644 index 0000000..6425bbb --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceFirmwareController.java @@ -0,0 +1,113 @@ +package com.dji.sample.manage.controller; + +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.manage.model.dto.DeviceFirmwareDTO; +import com.dji.sample.manage.model.dto.DeviceFirmwareNoteDTO; +import com.dji.sample.manage.model.dto.FirmwareFileProperties; +import com.dji.sample.manage.model.param.DeviceFirmwareQueryParam; +import com.dji.sample.manage.model.param.DeviceFirmwareUpdateParam; +import com.dji.sample.manage.model.param.DeviceFirmwareUploadParam; +import com.dji.sample.manage.service.IDeviceFirmwareService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/16 + */ +@RestController +@RequestMapping("${url.manage.prefix}${url.manage.version}/workspaces") +@Validated +public class DeviceFirmwareController { + + @Autowired + private IDeviceFirmwareService service; + + /** + * Get the latest firmware version information for this device model. + * @param deviceNames + * @return + */ + @GetMapping("/firmware-release-notes/latest") + public HttpResultResponse> getLatestFirmwareNote(@RequestParam("device_name") List deviceNames) { + + List releaseNotes = deviceNames.stream() + .map(deviceName -> service.getLatestFirmwareReleaseNote(deviceName)) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + + return HttpResultResponse.success(releaseNotes); + } + + /** + * Query firmware information based on parameters. + * @param workspaceId + * @param param + * @return + */ + @GetMapping("/{workspace_id}/firmwares") + public HttpResultResponse> getAllFirmwarePagination( + @PathVariable("workspace_id") String workspaceId, @Valid DeviceFirmwareQueryParam param) { + + PaginationData data = service.getAllFirmwarePagination(workspaceId, param); + return HttpResultResponse.success(data); + } + + /** + * Import firmware file for device upgrades. + * @param request + * @param workspaceId + * @param file + * @param param + * @return + */ + @PostMapping("/{workspace_id}/firmwares/file/upload") + public HttpResultResponse importFirmwareFile(HttpServletRequest request, @PathVariable("workspace_id") String workspaceId, + @NotNull(message = "No file received.") MultipartFile file, + @Valid DeviceFirmwareUploadParam param) { + + if (!file.getOriginalFilename().endsWith(FirmwareFileProperties.FIRMWARE_FILE_SUFFIX)) { + return HttpResultResponse.error("The file format is incorrect."); + } + + CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); + String creator = customClaim.getUsername(); + + service.importFirmwareFile(workspaceId, creator, param, file); + return HttpResultResponse.success(); + } + + /** + * Change the firmware availability status. + * @param workspaceId + * @param firmwareId + * @param param + * @return + */ + @PutMapping("/{workspace_id}/firmwares/{firmware_id}") + public HttpResultResponse changeFirmwareStatus(@PathVariable("workspace_id") String workspaceId, + @PathVariable("firmware_id") String firmwareId, + @Valid @RequestBody DeviceFirmwareUpdateParam param) { + + service.updateFirmwareInfo(DeviceFirmwareDTO.builder() + .firmwareId(firmwareId).firmwareStatus(param.getStatus()).build()); + return HttpResultResponse.success(); + } + + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceHmsController.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceHmsController.java new file mode 100644 index 0000000..7ded209 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceHmsController.java @@ -0,0 +1,69 @@ +package com.dji.sample.manage.controller; + +import com.dji.sample.manage.model.dto.DeviceHmsDTO; +import com.dji.sample.manage.model.param.DeviceHmsQueryParam; +import com.dji.sample.manage.service.IDeviceHmsService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ + +@RestController +@Slf4j +@RequestMapping("${url.manage.prefix}${url.manage.version}/devices") +public class DeviceHmsController { + + @Autowired + private IDeviceHmsService deviceHmsService; + + /** + * Page to query the hms information of the device. + * @param param + * @param workspaceId + * @return + */ + @GetMapping("/{workspace_id}/devices/hms") + public HttpResultResponse> getHmsInformation(DeviceHmsQueryParam param, + @PathVariable("workspace_id") String workspaceId) { + PaginationData devices = deviceHmsService.getDeviceHmsByParam(param); + + return HttpResultResponse.success(devices); + } + + /** + * Update unread hms messages to read status. + * @param deviceSn + * @return + */ + @PutMapping("/{workspace_id}/devices/hms/{device_sn}") + public HttpResultResponse updateReadHmsByDeviceSn(@PathVariable("device_sn") String deviceSn) { + deviceHmsService.updateUnreadHms(deviceSn); + return HttpResultResponse.success(); + } + + /** + * Get hms messages for a single device. + * @param deviceSn + * @return + */ + @GetMapping("/{workspace_id}/devices/hms/{device_sn}") + public HttpResultResponse> getUnreadHmsByDeviceSn(@PathVariable("device_sn") String deviceSn) { + PaginationData paginationData = deviceHmsService.getDeviceHmsByParam( + DeviceHmsQueryParam.builder() + .deviceSn(new HashSet<>(Set.of(deviceSn))) + .updateTime(0L) + .build()); + return HttpResultResponse.success(paginationData.getList()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceLogsController.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceLogsController.java new file mode 100644 index 0000000..3e08d53 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceLogsController.java @@ -0,0 +1,122 @@ +package com.dji.sample.manage.controller; + +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.manage.model.dto.DeviceLogsDTO; +import com.dji.sample.manage.model.param.DeviceLogsCreateParam; +import com.dji.sample.manage.model.param.DeviceLogsGetParam; +import com.dji.sample.manage.model.param.DeviceLogsQueryParam; +import com.dji.sample.manage.service.IDeviceLogsService; +import com.dji.sdk.cloudapi.log.FileUploadUpdateRequest; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URL; + +import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@RestController +@Slf4j +@RequestMapping("${url.manage.prefix}${url.manage.version}/workspaces") +public class DeviceLogsController { + + @Autowired + private IDeviceLogsService deviceLogsService; + + /** + * Obtain the device upload log list by paging according to the query parameters. + * @param workspaceId + * @param deviceSn + * @param param + * @return + */ + @GetMapping("/{workspace_id}/devices/{device_sn}/logs-uploaded") + public HttpResultResponse getUploadedLogs(DeviceLogsQueryParam param, @PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn) { + PaginationData data = deviceLogsService.getUploadedLogs(deviceSn, param); + return HttpResultResponse.success(data); + } + + /** + * Get a list of log files that can be uploaded in real time. + * @param workspaceId + * @param deviceSn + * @param param + * @return + */ + @GetMapping("/{workspace_id}/devices/{device_sn}/logs") + public HttpResultResponse getLogsBySn(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn, + DeviceLogsGetParam param) { + return deviceLogsService.getRealTimeLogs(deviceSn, param.getDomainList()); + } + + /** + * Initiate a log upload request to the gateway. + * @return + */ + @PostMapping("/{workspace_id}/devices/{device_sn}/logs") + public HttpResultResponse uploadLogs(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn, + HttpServletRequest request, @RequestBody DeviceLogsCreateParam param) { + + CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); + + return deviceLogsService.pushFileUpload(customClaim.getUsername(), deviceSn, param); + } + + /** + * Cancel logs file upload. + * @return + */ + @DeleteMapping("/{workspace_id}/devices/{device_sn}/logs") + public HttpResultResponse cancelUploadedLogs(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn, + @RequestBody FileUploadUpdateRequest param) { + + return deviceLogsService.pushUpdateFile(deviceSn, param); + } + + /** + * Delete upload history. + * @return + */ + @DeleteMapping("/{workspace_id}/devices/{device_sn}/logs/{logs_id}") + public HttpResultResponse deleteUploadedLogs(@PathVariable("workspace_id") String workspaceId, + @PathVariable("device_sn") String deviceSn, + @PathVariable("logs_id") String logsId) { + deviceLogsService.deleteLogs(deviceSn, logsId); + return HttpResultResponse.success(); + } + /** + * Query the download address of the file according to the wayline file id, + * and redirect to this address directly for download. + * @param workspaceId + * @param fileId + * @param logsId + * @param response + */ + @GetMapping("/{workspace_id}/logs/{logs_id}/url/{file_id}") + public HttpResultResponse getFileUrl(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "file_id") String fileId, + @PathVariable(name = "logs_id") String logsId, HttpServletResponse response) { + + try { + URL url = deviceLogsService.getLogsFileUrl(logsId, fileId); + return HttpResultResponse.success(url.toString()); + } catch (Exception e) { + log.error("Failed to get the logs file download address."); + e.printStackTrace(); + } + return HttpResultResponse.error("Failed to get the logs file download address."); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/LiveStreamController.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/LiveStreamController.java new file mode 100644 index 0000000..27f1a64 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/LiveStreamController.java @@ -0,0 +1,85 @@ +package com.dji.sample.manage.controller; + +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.manage.model.dto.CapacityDeviceDTO; +import com.dji.sample.manage.model.dto.LiveTypeDTO; +import com.dji.sample.manage.service.ILiveStreamService; +import com.dji.sdk.common.HttpResultResponse; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/19 + */ + +@RestController +@Slf4j +@RequestMapping("${url.manage.prefix}${url.manage.version}/live") +public class LiveStreamController { + + @Autowired + private ILiveStreamService liveStreamService; + + @Autowired + private ObjectMapper mapper; + + /** + * Get live capability data of all drones in the current user's workspace from the database. + * @param request + * @return live capability + */ + @GetMapping("/capacity") + public HttpResultResponse> getLiveCapacity(HttpServletRequest request) { + // Get information about the current user. + CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); + + List liveCapacity = liveStreamService.getLiveCapacity(customClaim.getWorkspaceId()); + + return HttpResultResponse.success(liveCapacity); + } + + /** + * Live streaming according to the parameters passed in from the web side. + * @param liveParam Live streaming parameters. + * @return + */ + @PostMapping("/streams/start") + public HttpResultResponse liveStart(@RequestBody LiveTypeDTO liveParam) { + return liveStreamService.liveStart(liveParam); + } + + /** + * Stop live streaming according to the parameters passed in from the web side. + * @param liveParam Live streaming parameters. + * @return + */ + @PostMapping("/streams/stop") + public HttpResultResponse liveStop(@RequestBody LiveTypeDTO liveParam) { + return liveStreamService.liveStop(liveParam.getVideoId()); + } + + /** + * Set the quality of the live streaming according to the parameters passed in from the web side. + * @param liveParam Live streaming parameters. + * @return + */ + @PostMapping("/streams/update") + public HttpResultResponse liveSetQuality(@RequestBody LiveTypeDTO liveParam) { + return liveStreamService.liveSetQuality(liveParam); + } + + @PostMapping("/streams/switch") + public HttpResultResponse liveLensChange(@RequestBody LiveTypeDTO liveParam) { + return liveStreamService.liveLensChange(liveParam); + } + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/LoginController.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/LoginController.java new file mode 100644 index 0000000..9572dbb --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/LoginController.java @@ -0,0 +1,48 @@ +package com.dji.sample.manage.controller; + +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.manage.model.dto.UserDTO; +import com.dji.sample.manage.model.dto.UserLoginDTO; +import com.dji.sample.manage.service.IUserService; +import com.dji.sdk.common.HttpResultResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Optional; + +import static com.dji.sample.component.AuthInterceptor.PARAM_TOKEN; + +@RestController +@RequestMapping("${url.manage.prefix}${url.manage.version}") +public class LoginController { + + @Autowired + private IUserService userService; + + @PostMapping("/login") + public HttpResultResponse login(@RequestBody UserLoginDTO loginDTO) { + + String username = loginDTO.getUsername(); + String password = loginDTO.getPassword(); + return userService.userLogin(username, password, loginDTO.getFlag()); + } + + @PostMapping("/token/refresh") + public HttpResultResponse refreshToken(HttpServletRequest request, HttpServletResponse response) { + String token = request.getHeader(PARAM_TOKEN); + Optional user = userService.refreshToken(token); + + if (user.isEmpty()) { + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + return HttpResultResponse.error(CommonErrorEnum.NO_TOKEN.getMessage()); + } + + return HttpResultResponse.success(user.get()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/TopologyController.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/TopologyController.java new file mode 100644 index 0000000..10908d2 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/TopologyController.java @@ -0,0 +1,37 @@ +package com.dji.sample.manage.controller; + +import com.dji.sample.manage.service.ITopologyService; +import com.dji.sdk.cloudapi.tsa.TopologyList; +import com.dji.sdk.cloudapi.tsa.TopologyResponse; +import com.dji.sdk.cloudapi.tsa.api.IHttpTsaService; +import com.dji.sdk.common.HttpResultResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@RestController +public class TopologyController implements IHttpTsaService { + + @Autowired + private ITopologyService topologyService; + + + /** + * Get the topology list of all devices in the current user workspace for pilot display. + * @param workspaceId + * @return + */ + @Override + public HttpResultResponse obtainDeviceTopologyList(String workspaceId, HttpServletRequest req, HttpServletResponse rsp) { + List topologyList = topologyService.getDeviceTopology(workspaceId); + return HttpResultResponse.success(new TopologyResponse().setList(topologyList)); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/UserController.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/UserController.java new file mode 100644 index 0000000..5536948 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/UserController.java @@ -0,0 +1,64 @@ +package com.dji.sample.manage.controller; + +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.manage.model.dto.UserListDTO; +import com.dji.sample.manage.service.IUserService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; + +import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; + + +@RestController +@RequestMapping("${url.manage.prefix}${url.manage.version}/users") +public class UserController { + + @Autowired + private IUserService userService; + + /** + * Query the information of the current user. + * @param request + * @return + */ + @GetMapping("/current") + public HttpResultResponse getCurrentUserInfo(HttpServletRequest request) { + CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); + return userService.getUserByUsername(customClaim.getUsername(), customClaim.getWorkspaceId()); + } + + /** + * Paging to query all users in a workspace. + * @param page current page + * @param pageSize + * @param workspaceId + * @return + */ + @GetMapping("/{workspace_id}/users") + public HttpResultResponse> getUsers(@RequestParam(defaultValue = "1") Long page, + @RequestParam(value = "page_size", defaultValue = "50") Long pageSize, + @PathVariable("workspace_id") String workspaceId) { + PaginationData paginationData = userService.getUsersByWorkspaceId(page, pageSize, workspaceId); + return HttpResultResponse.success(paginationData); + } + + /** + * Modify user information. Only mqtt account information is included, nothing else can be modified. + * @param user + * @param workspaceId + * @param userId + * @return + */ + @PutMapping("/{workspace_id}/users/{user_id}") + public HttpResultResponse updateUser(@RequestBody UserListDTO user, + @PathVariable("workspace_id") String workspaceId, + @PathVariable("user_id") String userId) { + + userService.updateUser(workspaceId, userId, user); + return HttpResultResponse.success(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/WorkspaceController.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/WorkspaceController.java new file mode 100644 index 0000000..80110ac --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/WorkspaceController.java @@ -0,0 +1,41 @@ +package com.dji.sample.manage.controller; + +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.manage.model.dto.WorkspaceDTO; +import com.dji.sample.manage.service.IWorkspaceService; +import com.dji.sdk.common.HttpResultResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import java.util.Optional; + +import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +@RestController +@RequestMapping("${url.manage.prefix}${url.manage.version}/workspaces") +public class WorkspaceController { + + @Autowired + private IWorkspaceService workspaceService; + + /** + * Gets information about the workspace that the current user is in. + * @param request + * @return + */ + @GetMapping("/current") + public HttpResultResponse getCurrentWorkspace(HttpServletRequest request) { + CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); + Optional workspaceOpt = workspaceService.getWorkspaceByWorkspaceId(customClaim.getWorkspaceId()); + + return workspaceOpt.isEmpty() ? HttpResultResponse.error() : HttpResultResponse.success(workspaceOpt.get()); + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceDictionaryMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceDictionaryMapper.java new file mode 100644 index 0000000..cce8f7e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceDictionaryMapper.java @@ -0,0 +1,13 @@ +package com.dji.sample.manage.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.manage.model.entity.DeviceDictionaryEntity; + +/** + * + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +public interface IDeviceDictionaryMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceFirmwareMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceFirmwareMapper.java new file mode 100644 index 0000000..bc4c4a2 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceFirmwareMapper.java @@ -0,0 +1,39 @@ +package com.dji.sample.manage.dao; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dji.sample.manage.model.entity.DeviceFirmwareEntity; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/16 + */ +public interface IDeviceFirmwareMapper extends BaseMapper { + String sql = "") + Page selectPage(Page page, @Param(Constants.WRAPPER)Wrapper wrapper, @Param("device_name") String deviceName); + + @Select(sql + " limit 1 ") + DeviceFirmwareEntity selectOne(@Param(Constants.WRAPPER)Wrapper wrapper, @Param("device_name") String deviceName); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceHmsMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceHmsMapper.java new file mode 100644 index 0000000..c7eb8bb --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceHmsMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.manage.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.manage.model.entity.DeviceHmsEntity; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/6 + */ +public interface IDeviceHmsMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceLogsMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceLogsMapper.java new file mode 100644 index 0000000..ae9290b --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceLogsMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.manage.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.manage.model.entity.DeviceLogsEntity; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public interface IDeviceLogsMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceMapper.java new file mode 100644 index 0000000..758d8e5 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDeviceMapper.java @@ -0,0 +1,14 @@ +package com.dji.sample.manage.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.manage.model.entity.DeviceEntity; + +/** + * + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +public interface IDeviceMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDevicePayloadMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDevicePayloadMapper.java new file mode 100644 index 0000000..f90231c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IDevicePayloadMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.manage.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.manage.model.entity.DevicePayloadEntity; + +/** + * @author sean.zhou + * @date 2021/11/19 + * @version 0.1 + */ +public interface IDevicePayloadMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IFirmwareModelMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IFirmwareModelMapper.java new file mode 100644 index 0000000..9cb8ee3 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IFirmwareModelMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.manage.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.manage.model.entity.FirmwareModelEntity; + +/** + * @author sean + * @version 1.3 + * @date 2022/12/21 + */ +public interface IFirmwareModelMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/ILogsFileIndexMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/ILogsFileIndexMapper.java new file mode 100644 index 0000000..e0b3f3b --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/ILogsFileIndexMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.manage.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.manage.model.entity.LogsFileIndexEntity; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/8 + */ +public interface ILogsFileIndexMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/ILogsFileMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/ILogsFileMapper.java new file mode 100644 index 0000000..4acfb6c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/ILogsFileMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.manage.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.manage.model.entity.LogsFileEntity; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public interface ILogsFileMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IUserMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IUserMapper.java new file mode 100644 index 0000000..a6179ae --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IUserMapper.java @@ -0,0 +1,8 @@ +package com.dji.sample.manage.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.manage.model.entity.UserEntity; + +public interface IUserMapper extends BaseMapper { + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IWorkspaceMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IWorkspaceMapper.java new file mode 100644 index 0000000..79bc240 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/dao/IWorkspaceMapper.java @@ -0,0 +1,8 @@ +package com.dji.sample.manage.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.manage.model.entity.WorkspaceEntity; + +public interface IWorkspaceMapper extends BaseMapper { + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/AppLicenseProperties.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/AppLicenseProperties.java new file mode 100644 index 0000000..cc15023 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/AppLicenseProperties.java @@ -0,0 +1,32 @@ +package com.dji.sample.manage.model.common; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @author sean + * @version 1.3.1 + * @date 2023/1/5 + */ +@Component +@ConfigurationProperties("cloud-api.app") +public class AppLicenseProperties { + + public static String id; + + public static String key; + + public static String license; + + public void setId(String id) { + AppLicenseProperties.id = id; + } + + public void setKey(String key) { + AppLicenseProperties.key = key; + } + + public void setLicense(String license) { + AppLicenseProperties.license = license; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/HmsJsonUtil.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/HmsJsonUtil.java new file mode 100644 index 0000000..12919d6 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/HmsJsonUtil.java @@ -0,0 +1,52 @@ +package com.dji.sample.manage.model.common; + +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.core.io.ClassPathResource; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.io.InputStream; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +@Slf4j +@Component +public class HmsJsonUtil { + + private static ObjectMapper mapper; + + @Autowired + public void setMapper(ObjectMapper mapper) { + HmsJsonUtil.mapper = mapper; + } + + private static JsonNode nodes; + + private HmsJsonUtil(){ + + } + + @PostConstruct + private void loadJsonFile() { + try (InputStream inputStream = new ClassPathResource("hms.json").getInputStream()){ + nodes = mapper.readTree(inputStream); + } catch (IOException e) { + log.error("hms.json加载失败。"); + e.printStackTrace(); + } + } + + public static HmsMessage get(String key) { + if (nodes.get(key) == null) { + return new HmsMessage(); + } + return mapper.convertValue(nodes.get(key), HmsMessage.class); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/HmsMessage.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/HmsMessage.java new file mode 100644 index 0000000..328b45e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/HmsMessage.java @@ -0,0 +1,16 @@ +package com.dji.sample.manage.model.common; + +import lombok.Data; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/7 + */ +@Data +public class HmsMessage { + + private String zh; + + private String en; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/NtpServerProperties.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/NtpServerProperties.java new file mode 100644 index 0000000..7e562f3 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/common/NtpServerProperties.java @@ -0,0 +1,20 @@ +package com.dji.sample.manage.model.common; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +@Component +@ConfigurationProperties("ntp.server") +public class NtpServerProperties { + + public static String host; + + public void setHost(String host) { + NtpServerProperties.host = host; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/CapacityCameraDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/CapacityCameraDTO.java new file mode 100644 index 0000000..d44fddd --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/CapacityCameraDTO.java @@ -0,0 +1,32 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/22 + * @version 0.1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CapacityCameraDTO { + + private String id; + + private String deviceSn; + + private String name; + + private String index; + + private String type; + + private List videosList; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/CapacityDeviceDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/CapacityDeviceDTO.java new file mode 100644 index 0000000..efa0bcc --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/CapacityDeviceDTO.java @@ -0,0 +1,26 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/22 + * @version 0.1 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CapacityDeviceDTO { + + private String sn; + + private String name; + + private List camerasList; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/CapacityVideoDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/CapacityVideoDTO.java new file mode 100644 index 0000000..531e7ec --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/CapacityVideoDTO.java @@ -0,0 +1,28 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/22 + * @version 0.1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CapacityVideoDTO { + + private String id; + + private String index; + + private String type; + + private List switchVideoTypes; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceAuthorityDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceAuthorityDTO.java new file mode 100644 index 0000000..c72680f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceAuthorityDTO.java @@ -0,0 +1,27 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sample.control.model.enums.DroneAuthorityEnum; +import com.dji.sdk.cloudapi.device.ControlSourceEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/2 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DeviceAuthorityDTO { + + private String sn; + + private DroneAuthorityEnum type; + + private ControlSourceEnum controlSource; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceDTO.java new file mode 100644 index 0000000..3d89a92 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceDTO.java @@ -0,0 +1,75 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sample.manage.model.enums.DeviceFirmwareStatusEnum; +import com.dji.sdk.cloudapi.device.ControlSourceEnum; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.device.DeviceSubTypeEnum; +import com.dji.sdk.cloudapi.device.DeviceTypeEnum; +import com.dji.sdk.cloudapi.tsa.DeviceIconUrl; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/19 + * @version 0.1 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class DeviceDTO { + + private String deviceSn; + + private String deviceName; + + private String workspaceId; + + private ControlSourceEnum controlSource; + + private String deviceDesc; + + private String childDeviceSn; + + private DeviceDomainEnum domain; + + private DeviceTypeEnum type; + + private DeviceSubTypeEnum subType; + + private List payloadsList; + + private DeviceIconUrl iconUrl; + + private Boolean status; + + private Boolean boundStatus; + + private LocalDateTime loginTime; + + private LocalDateTime boundTime; + + private String nickname; + + private String userId; + + private String firmwareVersion; + + private String workspaceName; + + private DeviceDTO children; + + private DeviceFirmwareStatusEnum firmwareStatus; + + private Integer firmwareProgress; + + private String parentSn; + + private String thingVersion; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceDictionaryDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceDictionaryDTO.java new file mode 100644 index 0000000..9c0170d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceDictionaryDTO.java @@ -0,0 +1,28 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +public class DeviceDictionaryDTO { + + private Integer domain; + + private Integer deviceType; + + private Integer subType; + + private String deviceName; + + private String deviceDesc; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceFirmwareDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceFirmwareDTO.java new file mode 100644 index 0000000..b59f289 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceFirmwareDTO.java @@ -0,0 +1,45 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/16 + */ +@Builder +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DeviceFirmwareDTO { + + private String firmwareId; + + private String fileName; + + private String productVersion; + + private String objectKey; + + private Long fileSize; + + private String fileMd5; + + private List deviceName; + + private String releaseNote; + + private LocalDate releasedTime; + + private Boolean firmwareStatus; + + private String workspaceId; + + private String username; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceFirmwareNoteDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceFirmwareNoteDTO.java new file mode 100644 index 0000000..8899518 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceFirmwareNoteDTO.java @@ -0,0 +1,28 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/16 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DeviceFirmwareNoteDTO { + + private String deviceName; + + private String productVersion; + + private String releaseNote; + + private LocalDate releasedTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceFirmwareUpgradeDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceFirmwareUpgradeDTO.java new file mode 100644 index 0000000..79e559b --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceFirmwareUpgradeDTO.java @@ -0,0 +1,20 @@ +package com.dji.sample.manage.model.dto; + +import lombok.Data; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/16 + */ +@Data +public class DeviceFirmwareUpgradeDTO { + + private String deviceName; + + private String sn; + + private String productVersion; + + private Integer firmwareUpgradeType; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceHmsDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceHmsDTO.java new file mode 100644 index 0000000..7dc1c1a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceHmsDTO.java @@ -0,0 +1,57 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/8 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class DeviceHmsDTO implements Cloneable { + + private String hmsId; + + private String tid; + + private String bid; + + private String sn; + + private Integer level; + + private Integer module; + + private String key; + + private String messageZh; + + private String messageEn; + + private LocalDateTime createTime; + + private LocalDateTime updateTime; + + @Override + public DeviceHmsDTO clone() { + try { + return (DeviceHmsDTO) super.clone(); + } catch (CloneNotSupportedException e) { + return DeviceHmsDTO.builder() + .sn(this.sn) + .bid(this.bid) + .tid(this.tid) + .createTime(this.createTime) + .updateTime(this.updateTime) + .build(); + } + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceLogsDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceLogsDTO.java new file mode 100644 index 0000000..0f5e210 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DeviceLogsDTO.java @@ -0,0 +1,41 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sdk.cloudapi.tsa.TopologyList; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DeviceLogsDTO { + + private String logsId; + + private LocalDateTime happenTime; + + private String userName; + + private String logsInformation; + + private LocalDateTime createTime; + + private Integer status; + + private TopologyList deviceTopo; + + private List logsProgress; + + private LogsFileUploadListDTO deviceLogs; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DevicePayloadDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DevicePayloadDTO.java new file mode 100644 index 0000000..abcfb45 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DevicePayloadDTO.java @@ -0,0 +1,32 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sdk.cloudapi.device.ControlSourceEnum; +import com.dji.sdk.cloudapi.device.PayloadIndex; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean.zhou + * @date 2021/11/19 + * @version 0.1 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DevicePayloadDTO { + + private String payloadSn; + + private String payloadName; + + private Integer index; + + private String payloadDesc; + + private ControlSourceEnum controlSource; + + private PayloadIndex payloadIndex; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DevicePayloadReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DevicePayloadReceiver.java new file mode 100644 index 0000000..85ecfd9 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/DevicePayloadReceiver.java @@ -0,0 +1,29 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sdk.cloudapi.device.ControlSourceEnum; +import com.dji.sdk.cloudapi.device.PayloadIndex; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DevicePayloadReceiver { + + private String deviceSn; + + private ControlSourceEnum controlSource; + + private PayloadIndex payloadIndex; + + private String sn; + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/FirmwareFileProperties.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/FirmwareFileProperties.java new file mode 100644 index 0000000..3e4e8f3 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/FirmwareFileProperties.java @@ -0,0 +1,28 @@ +package com.dji.sample.manage.model.dto; + +/** + * @author sean + * @version 1.3 + * @date 2022/12/1 + */ +public class FirmwareFileProperties { + + private FirmwareFileProperties() { + + } + + public static final String FIRMWARE_FILE_SUFFIX = ".zip"; + + public static final String FIRMWARE_SIG_FILE_SUFFIX = ".sig"; + + public static final String FIRMWARE_CONFIG_FILE_SUFFIX = ".cfg"; + + public static final String FIRMWARE_FILE_DELIMITER = "_"; + + public static final int FILENAME_VERSION_INDEX = 2; + + public static final int FILENAME_RELEASE_DATE_INDEX = 3; + + public static final String FILENAME_RELEASE_DATE_FORMAT = "yyyyMMdd"; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/FirmwareModelDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/FirmwareModelDTO.java new file mode 100644 index 0000000..d9f10f5 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/FirmwareModelDTO.java @@ -0,0 +1,24 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author sean + * @version 1.3 + * @date 2022/12/21 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FirmwareModelDTO { + + private String firmwareId; + + private List deviceNames; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveDTO.java new file mode 100644 index 0000000..29841c2 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveDTO.java @@ -0,0 +1,20 @@ +package com.dji.sample.manage.model.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class LiveDTO { + + private String url; + + private String username; + + private String password; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveStreamProperty.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveStreamProperty.java new file mode 100644 index 0000000..4f68500 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveStreamProperty.java @@ -0,0 +1,65 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sdk.cloudapi.livestream.*; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * @author sean + * @version 1.7 + * @date 2023/10/13 + */ + +@Data +@ConfigurationProperties("livestream.url") +@Configuration +public class LiveStreamProperty { + + private static LivestreamAgoraUrl agora; + + private static LivestreamRtmpUrl rtmp; + + private static LivestreamRtspUrl rtsp; + + private static LivestreamGb28181Url gb28181; + + private static LivestreamWhipUrl whip; + + public void setAgora(LivestreamAgoraUrl agora) { + LiveStreamProperty.agora = agora; + } + + public void setRtmp(LivestreamRtmpUrl rtmp) { + LiveStreamProperty.rtmp = rtmp; + } + + public void setRtsp(LivestreamRtspUrl rtsp) { + LiveStreamProperty.rtsp = rtsp; + } + + public void setGb28181(LivestreamGb28181Url gb28181) { + LiveStreamProperty.gb28181 = gb28181; + } + + public void setWhip(LivestreamWhipUrl webrtc) { + LiveStreamProperty.whip = webrtc; + } + + public static ILivestreamUrl get(UrlTypeEnum type) { + switch (type) { + case AGORA: + return agora; + case RTMP: + return rtmp; + case RTSP: + return rtsp; + case GB28181: + return gb28181; + case WHIP: + return whip; + } + throw new RuntimeException(CommonErrorEnum.ILLEGAL_ARGUMENT.getMessage()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveTypeDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveTypeDTO.java new file mode 100644 index 0000000..f0a41b2 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveTypeDTO.java @@ -0,0 +1,30 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sdk.cloudapi.device.VideoId; +import com.dji.sdk.cloudapi.livestream.LensChangeVideoTypeEnum; +import com.dji.sdk.cloudapi.livestream.UrlTypeEnum; +import com.dji.sdk.cloudapi.livestream.VideoQualityEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * Receive live parameters. + * @author sean.zhou + * @version 0.1 + * @date 2021/11/22 + */ +@Data +public class LiveTypeDTO { + + @JsonProperty("url_type") + private UrlTypeEnum urlType; + + @JsonProperty("video_id") + private VideoId videoId; + + @JsonProperty("video_quality") + private VideoQualityEnum videoQuality; + + private LensChangeVideoTypeEnum videoType; + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveUrlAgoraDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveUrlAgoraDTO.java new file mode 100644 index 0000000..1f9f781 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveUrlAgoraDTO.java @@ -0,0 +1,20 @@ +package com.dji.sample.manage.model.dto; + +import lombok.Data; + +/** + * @author sean.zhou + * @date 2021/11/23 + * @version 0.1 + */ +@Data +public class LiveUrlAgoraDTO { + + private String channel; + + private String sn; + + private String token; + + private Integer uid; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveUrlGB28181DTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveUrlGB28181DTO.java new file mode 100644 index 0000000..d57f06a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveUrlGB28181DTO.java @@ -0,0 +1,27 @@ +package com.dji.sample.manage.model.dto; + +import lombok.Data; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +@Data +public class LiveUrlGB28181DTO { + + private String serverIP; + + private Integer serverPort; + + private String serverID; + + private String agentID; + + private String agentPassword; + + private Integer localPort; + + private String channel; + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveUrlRTSPDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveUrlRTSPDTO.java new file mode 100644 index 0000000..8e57734 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LiveUrlRTSPDTO.java @@ -0,0 +1,18 @@ +package com.dji.sample.manage.model.dto; + +import lombok.Data; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +@Data +public class LiveUrlRTSPDTO { + + private String userName; + + private String password; + + private Integer port; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsFileDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsFileDTO.java new file mode 100644 index 0000000..be09491 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsFileDTO.java @@ -0,0 +1,35 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class LogsFileDTO { + + private String fileId; + + private String name; + + private Long size; + + private String logsId; + + private String deviceSn; + + private String fingerprint; + + private String objectKey; + + private Boolean status; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsFileUploadDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsFileUploadDTO.java new file mode 100644 index 0000000..1780b7f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsFileUploadDTO.java @@ -0,0 +1,36 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sdk.cloudapi.log.LogFileIndex; +import com.dji.sdk.cloudapi.log.LogModuleEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class LogsFileUploadDTO { + + private String deviceSn; + + private List list; + + @JsonProperty("module") + private LogModuleEnum deviceModelDomain; + + private String objectKey; + + private Integer result; + + private String fileId; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsFileUploadListDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsFileUploadListDTO.java new file mode 100644 index 0000000..be470f8 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsFileUploadListDTO.java @@ -0,0 +1,24 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class LogsFileUploadListDTO { + + private List files; + + private Integer result; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsOutputProgressDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsOutputProgressDTO.java new file mode 100644 index 0000000..e0b1ad8 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsOutputProgressDTO.java @@ -0,0 +1,27 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sdk.cloudapi.log.FileUploadStatusEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class LogsOutputProgressDTO { + + private String logsId; + + private FileUploadStatusEnum status; + + private List files; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsProgressDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsProgressDTO.java new file mode 100644 index 0000000..1e4e6bb --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsProgressDTO.java @@ -0,0 +1,31 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class LogsProgressDTO { + + private String deviceSn; + + private String deviceModelDomain; + + private Integer progress; + + private Integer result; + + private Float uploadRate; + + private String status; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsUploadCredentialsDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsUploadCredentialsDTO.java new file mode 100644 index 0000000..a58041e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/LogsUploadCredentialsDTO.java @@ -0,0 +1,52 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sdk.cloudapi.log.FileUploadStartParam; +import com.dji.sdk.cloudapi.storage.CredentialsToken; +import com.dji.sdk.cloudapi.storage.OssTypeEnum; +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/8 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class LogsUploadCredentialsDTO { + + private String bucket; + + private CredentialsToken credentials; + + private String endpoint; + + @JsonProperty("file_store_dir") + private String objectKeyPrefix; + + private OssTypeEnum provider; + + @Builder.Default + private String fileType = "text_log"; + + private FileUploadStartParam params; + + private String region; + + public LogsUploadCredentialsDTO(StsCredentialsResponse sts) { + this.bucket = sts.getBucket(); + long expire = sts.getCredentials().getExpire(); + sts.getCredentials().setExpire(System.currentTimeMillis() + (expire - 60) * 1000); + this.credentials = sts.getCredentials(); + this.endpoint = sts.getEndpoint(); + this.objectKeyPrefix = sts.getObjectKeyPrefix(); + this.provider = sts.getProvider(); + this.region = sts.getRegion(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/ProductConfigDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/ProductConfigDTO.java new file mode 100644 index 0000000..577ba54 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/ProductConfigDTO.java @@ -0,0 +1,24 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ProductConfigDTO { + + private String ntpServerHost; + + private String appId; + + private String appKey; + + private String appLicense; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/TelemetryDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/TelemetryDTO.java new file mode 100644 index 0000000..26fe624 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/TelemetryDTO.java @@ -0,0 +1,22 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class TelemetryDTO { + + private T host; + + private String sn; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/TopologyDeviceDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/TopologyDeviceDTO.java new file mode 100644 index 0000000..627615d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/TopologyDeviceDTO.java @@ -0,0 +1,148 @@ +package com.dji.sample.manage.model.dto; + +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.tsa.DeviceIconUrl; +import com.dji.sdk.cloudapi.tsa.DeviceTopology; +import com.dji.sdk.cloudapi.tsa.TopologyDeviceModel; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +public class TopologyDeviceDTO extends DeviceTopology { + + private String model; + + private Boolean boundStatus; + + private String gatewaySn; + + private DeviceDomainEnum domain; + + public TopologyDeviceDTO() { + } + + @Override + public String toString() { + return "TopologyDeviceDTO{" + + "model='" + model + '\'' + + ", boundStatus=" + boundStatus + + ", gatewaySn='" + gatewaySn + '\'' + + ", domain=" + domain + + '}'; + } + + @Override + public String getSn() { + return super.getSn(); + } + + @Override + public TopologyDeviceDTO setSn(String sn) { + super.setSn(sn); + return this; + } + + @Override + public String getDeviceCallsign() { + return super.getDeviceCallsign(); + } + + @Override + public TopologyDeviceDTO setDeviceCallsign(String deviceCallsign) { + super.setDeviceCallsign(deviceCallsign); + return this; + } + + @Override + public TopologyDeviceModel getDeviceModel() { + return super.getDeviceModel(); + } + + @Override + public TopologyDeviceDTO setDeviceModel(TopologyDeviceModel deviceModel) { + super.setDeviceModel(deviceModel); + return this; + } + + @Override + public Boolean getOnlineStatus() { + return super.getOnlineStatus(); + } + + @Override + public TopologyDeviceDTO setOnlineStatus(Boolean onlineStatus) { + super.setOnlineStatus(onlineStatus); + return this; + } + + @Override + public String getUserId() { + return super.getUserId(); + } + + @Override + public TopologyDeviceDTO setUserId(String userId) { + super.setUserId(userId); + return this; + } + + @Override + public String getUserCallsign() { + return super.getUserCallsign(); + } + + @Override + public TopologyDeviceDTO setUserCallsign(String userCallsign) { + super.setUserCallsign(userCallsign); + return this; + } + + @Override + public DeviceIconUrl getIconUrls() { + return super.getIconUrls(); + } + + @Override + public TopologyDeviceDTO setIconUrls(DeviceIconUrl iconUrls) { + super.setIconUrls(iconUrls); + return this; + } + + public String getModel() { + return model; + } + + public TopologyDeviceDTO setModel(String model) { + this.model = model; + return this; + } + + public Boolean getBoundStatus() { + return boundStatus; + } + + public TopologyDeviceDTO setBoundStatus(Boolean boundStatus) { + this.boundStatus = boundStatus; + return this; + } + + public String getGatewaySn() { + return gatewaySn; + } + + public TopologyDeviceDTO setGatewaySn(String gatewaySn) { + this.gatewaySn = gatewaySn; + return this; + } + + public DeviceDomainEnum getDomain() { + return domain; + } + + public TopologyDeviceDTO setDomain(DeviceDomainEnum domain) { + this.domain = domain; + return this; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/UserDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/UserDTO.java new file mode 100644 index 0000000..1e67c72 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/UserDTO.java @@ -0,0 +1,37 @@ +package com.dji.sample.manage.model.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class UserDTO { + + @JsonProperty("user_id") + private String userId; + + private String username; + + @JsonProperty("workspace_id") + private String workspaceId; + + @JsonProperty("user_type") + private Integer userType; + + @JsonProperty("mqtt_username") + private String mqttUsername; + + @JsonProperty("mqtt_password") + private String mqttPassword; + + @JsonProperty("access_token") + private String accessToken; + + @JsonProperty("mqtt_addr") + private String mqttAddr; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/UserListDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/UserListDTO.java new file mode 100644 index 0000000..7bfb3a6 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/UserListDTO.java @@ -0,0 +1,34 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/18 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class UserListDTO { + + private String userId; + + private String username; + + private String workspaceName; + + private String userType; + + private String mqttUsername; + + private String mqttPassword; + + private LocalDateTime createTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/UserLoginDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/UserLoginDTO.java new file mode 100644 index 0000000..1865ac9 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/UserLoginDTO.java @@ -0,0 +1,21 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserLoginDTO { + + @NonNull + private String username; + + @NonNull + private String password; + + @NonNull + private Integer flag; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/WorkspaceDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/WorkspaceDTO.java new file mode 100644 index 0000000..de9083b --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/dto/WorkspaceDTO.java @@ -0,0 +1,30 @@ +package com.dji.sample.manage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean.zhou + * @date 2021/11/22 + * @version 0.1 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class WorkspaceDTO { + + private Integer id; + + private String workspaceId; + + private String workspaceName; + + private String workspaceDesc; + + private String platformName; + + private String bindCode; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceDictionaryEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceDictionaryEntity.java new file mode 100644 index 0000000..c01ec6f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceDictionaryEntity.java @@ -0,0 +1,45 @@ +package com.dji.sample.manage.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * + * @author sean.zhou + * @date 2021/11/15 + * @version 0.1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@TableName("manage_device_dictionary") +public class DeviceDictionaryEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField(value = "domain") + private Integer domain; + + @TableField(value = "device_type") + private Integer deviceType; + + @TableField(value = "sub_type") + private Integer subType; + + @TableField(value = "device_name") + private String deviceName; + + @TableField(value = "device_desc") + private String deviceDesc; + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceEntity.java new file mode 100644 index 0000000..ae26ed1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceEntity.java @@ -0,0 +1,91 @@ +package com.dji.sample.manage.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * The entity class of the device + * + * @author sean.zhou + * @version 0.1 + * @date 2021/11/10 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName(value = "manage_device") +public class DeviceEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField(value = "device_sn") + private String deviceSn; + + @TableField(value = "device_name") + private String deviceName; + + @TableField(value = "workspace_id") + private String workspaceId; + + @TableField(value = "device_type") + private Integer deviceType; + + @TableField(value = "sub_type") + private Integer subType; + + @TableField(value = "domain") + private Integer domain; + + @TableField(value = "version") + private String version; + + @TableField(value = "device_index") + private String deviceIndex; + + @TableField(value = "child_sn") + private String childSn; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; + + @TableField(value = "device_desc") + private String deviceDesc; + + @TableField(value = "url_normal") + private String urlNormal; + + @TableField(value = "url_select") + private String urlSelect; + + @TableField(value = "user_id") + private String userId; + + @TableField(value = "nickname") + private String nickname; + + @TableField(value = "firmware_version") + private String firmwareVersion; + + @TableField(value = "compatible_status") + private Boolean compatibleStatus; + + @TableField(value = "bound_status") + private Boolean boundStatus; + + @TableField(value = "bound_time") + private Long boundTime; + + @TableField(value = "login_time") + private Long loginTime; + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceFirmwareEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceFirmwareEntity.java new file mode 100644 index 0000000..ced8e39 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceFirmwareEntity.java @@ -0,0 +1,70 @@ +package com.dji.sample.manage.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/16 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@TableName("manage_device_firmware") +public class DeviceFirmwareEntity implements Serializable { + + private static final long serialVersionUID = -12L; + + @TableId(type = IdType.AUTO) + private Long id; + + @TableField("firmware_id") + private String firmwareId; + + @TableField("file_name") + private String fileName; + + @TableField("firmware_version") + private String firmwareVersion; + + @TableField("object_key") + private String objectKey; + + @TableField("file_size") + private Long fileSize; + + @TableField("file_md5") + private String fileMd5; + + @TableField(exist = false) + private String deviceName; + + @TableField("release_note") + private String releaseNote; + + @TableField("release_date") + private Long releaseDate; + + @TableField("status") + private Boolean status; + + @TableField("workspace_id") + private String workspaceId; + + @TableField("user_name") + private String username; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceHmsEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceHmsEntity.java new file mode 100644 index 0000000..27c2040 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceHmsEntity.java @@ -0,0 +1,78 @@ +package com.dji.sample.manage.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/6 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName(value = "manage_device_hms") +public class DeviceHmsEntity implements Serializable, Cloneable { + + private static final long serialVersionUID = -12L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @TableField("hms_id") + private String hmsId; + + @TableField("tid") + private String tid; + + @TableField("bid") + private String bid; + + @TableField("sn") + private String sn; + + @TableField("level") + private Integer level; + + @TableField("module") + private Integer module; + + @TableField("hms_key") + private String hmsKey; + + @TableField("message_zh") + private String messageZh; + + @TableField("message_en") + private String messageEn; + + @TableField("create_time") + private Long createTime; + + @TableField("update_time") + private Long updateTime; + + @Override + public DeviceHmsEntity clone() { + try { + return (DeviceHmsEntity) super.clone(); + } catch (CloneNotSupportedException e) { + return DeviceHmsEntity.builder() + .bid(this.getBid()) + .tid(this.getTid()) + .createTime(this.getCreateTime()) + .updateTime(this.getUpdateTime()) + .sn(this.getSn()) + .build(); + } + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceLogsEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceLogsEntity.java new file mode 100644 index 0000000..6510004 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DeviceLogsEntity.java @@ -0,0 +1,52 @@ +package com.dji.sample.manage.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@TableName("manage_device_logs") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class DeviceLogsEntity implements Serializable { + + private static final long serialVersionUID = -12L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @TableField("logs_id") + private String logsId; + + @TableField("username") + private String username; + + @TableField("logs_info") + private String logsInfo; + + @TableField("device_sn") + private String deviceSn; + + @TableField("happen_time") + private Long happenTime; + + @TableField("status") + private Integer status; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DevicePayloadEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DevicePayloadEntity.java new file mode 100644 index 0000000..c50db1e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/DevicePayloadEntity.java @@ -0,0 +1,59 @@ +package com.dji.sample.manage.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean.zhou + * @date 2021/11/19 + * @version 0.1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@TableName(value = "manage_device_payload") +public class DevicePayloadEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField(value = "payload_sn") + private String payloadSn; + + @TableField(value = "payload_name") + private String payloadName; + + @TableField(value = "payload_type") + private Integer payloadType; + + @TableField(value = "sub_type") + private Integer subType; + + @TableField(value = "firmware_version") + private String firmwareVersion; + + @TableField(value = "payload_index") + private Integer payloadIndex; + + @TableField(value = "device_sn") + private String deviceSn; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; + + @TableField(value = "payload_desc") + private String payloadDesc; + + @TableField(value = "control_source") + private String controlSource; + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/FirmwareModelEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/FirmwareModelEntity.java new file mode 100644 index 0000000..5c8707d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/FirmwareModelEntity.java @@ -0,0 +1,37 @@ +package com.dji.sample.manage.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 1.3 + * @date 2022/12/21 + */ +@Data +@TableName("manage_firmware_model") +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class FirmwareModelEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Long id; + + @TableField("firmware_id") + private String firmwareId; + + @TableField("device_name") + private String deviceName; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/LogsFileEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/LogsFileEntity.java new file mode 100644 index 0000000..636689a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/LogsFileEntity.java @@ -0,0 +1,58 @@ +package com.dji.sample.manage.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@TableName("logs_file") +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class LogsFileEntity implements Serializable { + + private static final long serialVersionUID = -12L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @TableField("file_id") + private String fileId; + + @TableField("name") + private String name; + + @TableField("size") + private Long size; + + @TableField("logs_id") + private String logsId; + + @TableField("device_sn") + private String deviceSn; + + @TableField("fingerprint") + private String fingerprint; + + @TableField("object_key") + private String objectKey; + + @TableField("status") + private Boolean status; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/LogsFileIndexEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/LogsFileIndexEntity.java new file mode 100644 index 0000000..d4999e8 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/LogsFileIndexEntity.java @@ -0,0 +1,54 @@ +package com.dji.sample.manage.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/8 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@TableName("logs_file_index") +public class LogsFileIndexEntity implements Serializable { + + private static final long serialVersionUID = -12L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @TableField("boot_index") + private Integer bootIndex; + + @TableField("file_id") + private String fileId; + + @TableField("start_time") + private Long startTime; + + @TableField("end_time") + private Long endTime; + + @TableField("size") + private Long size; + + @TableField("device_sn") + private String deviceSn; + + @TableField("domain") + private Integer domain; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/UserEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/UserEntity.java new file mode 100644 index 0000000..6c095b9 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/UserEntity.java @@ -0,0 +1,41 @@ +package com.dji.sample.manage.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; + +import java.io.Serializable; + +@TableName(value = "manage_user") +@Data +public class UserEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField(value = "user_id") + private String userId; + + @TableField(value = "username") + private String username; + + @TableField(value = "password") + private String password; + + @TableField(value = "workspace_id") + private String workspaceId; + + @TableField(value = "user_type") + private Integer userType; + + @TableField(value = "mqtt_username") + private String mqttUsername; + + @TableField(value = "mqtt_password") + private String mqttPassword; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/WorkspaceEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/WorkspaceEntity.java new file mode 100644 index 0000000..90a5348 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/WorkspaceEntity.java @@ -0,0 +1,35 @@ +package com.dji.sample.manage.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; + +import java.io.Serializable; + +@TableName(value = "manage_workspace") +@Data +public class WorkspaceEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField(value = "workspace_id") + private String workspaceId; + + @TableField(value = "workspace_name") + private String workspaceName; + + @TableField(value = "workspace_desc") + private String workspaceDesc; + + @TableField(value = "platform_name") + private String platformName; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; + + @TableField(value = "bind_code") + private String bindCode; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/CustomizeConfigScopeEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/CustomizeConfigScopeEnum.java new file mode 100644 index 0000000..4634264 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/CustomizeConfigScopeEnum.java @@ -0,0 +1,33 @@ +package com.dji.sample.manage.model.enums; + +import com.dji.sample.manage.service.IRequestsConfigService; +import com.dji.sample.manage.service.impl.ConfigProductServiceImpl; +import com.dji.sdk.cloudapi.config.ConfigScopeEnum; +import lombok.Getter; + +import java.util.Arrays; +import java.util.Optional; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +@Getter +public enum CustomizeConfigScopeEnum { + + PRODUCT(ConfigScopeEnum.PRODUCT, ConfigProductServiceImpl.class); + + ConfigScopeEnum scope; + + Class clazz; + + CustomizeConfigScopeEnum(ConfigScopeEnum scope, Class clazz) { + this.scope = scope; + this.clazz = clazz; + } + + public static Optional find(String scope) { + return Arrays.stream(CustomizeConfigScopeEnum.values()).filter(scopeEnum -> scopeEnum.scope.getScope().equals(scope)).findAny(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/DeviceFirmwareStatusEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/DeviceFirmwareStatusEnum.java new file mode 100644 index 0000000..01beda2 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/DeviceFirmwareStatusEnum.java @@ -0,0 +1,69 @@ +package com.dji.sample.manage.model.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.Getter; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/15 + */ +public enum DeviceFirmwareStatusEnum { + + /** + * no need to upgrade + */ + NOT_UPGRADE(1), + + /** + * to upgraded + */ + NORMAL_UPGRADE(2), + + /** + * A consistency upgrade is required. + */ + CONSISTENT_UPGRADE(3), + + /** + * during upgrade + */ + UPGRADING(4), + + UNKNOWN(-1); + + int val; + + @JsonValue + public int getVal() { + return val; + } + + DeviceFirmwareStatusEnum(int val) { + this.val = val; + } + + @JsonCreator + public static DeviceFirmwareStatusEnum find(int val) { + return Arrays.stream(DeviceFirmwareStatusEnum.values()) + .filter(firmwareStatus -> firmwareStatus.val == val) + .findFirst().orElse(UNKNOWN); + } + + @Getter + public enum CompatibleStatusEnum { + INCONSISTENT(1), + + CONSISTENT(0); + + int val; + + CompatibleStatusEnum(int val) { + this.val = val; + } + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/DeviceLogsStatusEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/DeviceLogsStatusEnum.java new file mode 100644 index 0000000..0fcbdd8 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/DeviceLogsStatusEnum.java @@ -0,0 +1,42 @@ +package com.dji.sample.manage.model.enums; + +import com.dji.sdk.cloudapi.log.FileUploadStatusEnum; +import lombok.Getter; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/8 + */ +@Getter +public enum DeviceLogsStatusEnum { + + UPLOADING(1, FileUploadStatusEnum.FILE_PULL, FileUploadStatusEnum.FILE_ZIP, + FileUploadStatusEnum.FILE_UPLOADING, FileUploadStatusEnum.IN_PROGRESS, FileUploadStatusEnum.PAUSED), + + DONE(2, FileUploadStatusEnum.OK), + + CANCELED(3, FileUploadStatusEnum.CANCELED), + + FAILED(4, FileUploadStatusEnum.FAILED, FileUploadStatusEnum.REJECTED, FileUploadStatusEnum.TIMEOUT), + + UNKNOWN(-1); + + int val; + + HashSet status; + + DeviceLogsStatusEnum(int val, FileUploadStatusEnum... status) { + this.status = new HashSet<>(); + Collections.addAll(this.status, status); + this.val = val; + } + + public static DeviceLogsStatusEnum find(FileUploadStatusEnum status) { + return Arrays.stream(DeviceLogsStatusEnum.values()).filter(element -> element.status.contains(status)).findAny().orElse(UNKNOWN); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/ExitWaylineWhenRcLostActionEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/ExitWaylineWhenRcLostActionEnum.java new file mode 100644 index 0000000..aff6504 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/ExitWaylineWhenRcLostActionEnum.java @@ -0,0 +1,28 @@ +package com.dji.sample.manage.model.enums; + +import com.dji.sdk.exception.CloudSDKException; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/15 + */ +public enum ExitWaylineWhenRcLostActionEnum { + + CONTINUE_WAYLINE, EXECUTE_RC_LOST_ACTION; + + @JsonValue + public int getVal() { + return ordinal(); + } + + @JsonCreator + public static ExitWaylineWhenRcLostActionEnum find(int val) { + return Arrays.stream(values()).filter(lostActionEnum -> lostActionEnum.ordinal() == val).findAny() + .orElseThrow(() -> new CloudSDKException(ExitWaylineWhenRcLostActionEnum.class, val)); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/FirmwareMethodEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/FirmwareMethodEnum.java new file mode 100644 index 0000000..b185546 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/FirmwareMethodEnum.java @@ -0,0 +1,21 @@ +package com.dji.sample.manage.model.enums; + +import lombok.Getter; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +@Getter +public enum FirmwareMethodEnum { + + OTA_CREATE("ota_create"); + + private String method; + + FirmwareMethodEnum(String method) { + this.method = method; + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LiveStreamMethodEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LiveStreamMethodEnum.java new file mode 100644 index 0000000..b49cdc1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LiveStreamMethodEnum.java @@ -0,0 +1,29 @@ +package com.dji.sample.manage.model.enums; + +import lombok.Getter; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +@Getter +public enum LiveStreamMethodEnum { + + LIVE_START_PUSH("live_start_push"), + + LIVE_STOP_PUSH("live_stop_push"), + + LIVE_SET_QUALITY("live_set_quality"), + + LIVE_LENS_CHANGE("live_lens_change"), + + UNKNOWN("unknown"); + + private String method; + + LiveStreamMethodEnum(String method) { + this.method = method; + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LiveUrlTypeEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LiveUrlTypeEnum.java new file mode 100644 index 0000000..163b520 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LiveUrlTypeEnum.java @@ -0,0 +1,41 @@ +package com.dji.sample.manage.model.enums; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/22 + */ +public enum LiveUrlTypeEnum { + + AGORA(0), + + RTMP(1), + + RTSP(2), + + GB28181(3), + + UNKNOWN(-1); + + private int val; + + LiveUrlTypeEnum(int val) { + this.val = val; + } + + public static LiveUrlTypeEnum find(Integer val) { + if (AGORA.val == val) { + return AGORA; + } + if (RTMP.val == val) { + return RTMP; + } + if (RTSP.val == val) { + return RTSP; + } + if (GB28181.val == val) { + return GB28181; + } + return UNKNOWN; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LiveVideoQualityEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LiveVideoQualityEnum.java new file mode 100644 index 0000000..3ad42d3 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LiveVideoQualityEnum.java @@ -0,0 +1,51 @@ +package com.dji.sample.manage.model.enums; + +/** + * @author sean + * @version 0.1 + * @date 2021/11/26 + */ +public enum LiveVideoQualityEnum { + + AUTO (0), + + SMOOTH(1), + + STANDARD_DEFINITION(2), + + HIGH_DEFINITION(3), + + ULTRA_HD(4), + + UNKNOWN(-1); + + private int val; + + LiveVideoQualityEnum(int val) { + this.val = val; + } + + public static LiveVideoQualityEnum find(int val) { + if (AUTO.val == val) { + return AUTO; + } + + if (SMOOTH.val == val) { + return SMOOTH; + } + + if (STANDARD_DEFINITION.val == val) { + return STANDARD_DEFINITION; + } + + if (HIGH_DEFINITION.val == val) { + return HIGH_DEFINITION; + } + + if (ULTRA_HD.val == val) { + return ULTRA_HD; + } + + return UNKNOWN; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LogsFileUpdateMethodEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LogsFileUpdateMethodEnum.java new file mode 100644 index 0000000..2e4e718 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/LogsFileUpdateMethodEnum.java @@ -0,0 +1,28 @@ +package com.dji.sample.manage.model.enums; + +import lombok.Getter; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +@Getter +public enum LogsFileUpdateMethodEnum { + + CANCEL("cancel"), + + UNKNOWN("unknown"); + + String method; + + LogsFileUpdateMethodEnum(String method) { + this.method = method; + } + + public static LogsFileUpdateMethodEnum find(String method) { + return Arrays.stream(LogsFileUpdateMethodEnum.values()).filter(e -> e.method.equals(method)).findAny().orElse(UNKNOWN); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/PayloadModelEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/PayloadModelEnum.java new file mode 100644 index 0000000..5633b03 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/PayloadModelEnum.java @@ -0,0 +1,61 @@ +package com.dji.sample.manage.model.enums; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/29 + */ +public enum PayloadModelEnum { + + Z30("Z30", "20-0"), + + XT2("XT2", "26-0"), + + XTS("XTS", "41-0"), + + H20("H20", "42-0"), + + H20T("H20T", "43-0"), + + P1("P1", "50-65535"), + + M30("M30", "52-0"), + + M30T("M30T", "53-0"), + + H20N("H20N", "61-0"), + + DOCK("DOCK", "165-0"), + + L1("L1", "90742-0"); + + private String model; + + private String index; + + PayloadModelEnum(String model, String index) { + this.model = model; + this.index = index; + } + + public String getModel() { + return model; + } + + public String getIndex() { + return index; + } + + public static List getAllModel() { + return Arrays.stream(PayloadModelEnum.values()).map(PayloadModelEnum::getModel).collect(Collectors.toList()); + } + + public static List getAllIndex() { + return Arrays.stream(PayloadModelEnum.values()).map(PayloadModelEnum::getIndex).collect(Collectors.toList()); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/PropertySetFieldEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/PropertySetFieldEnum.java new file mode 100644 index 0000000..a80f0f9 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/PropertySetFieldEnum.java @@ -0,0 +1,68 @@ +package com.dji.sample.manage.model.enums; + +import com.dji.sample.manage.model.receiver.*; +import com.dji.sdk.cloudapi.property.PropertySetEnum; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public enum PropertySetFieldEnum { + + NIGHT_LIGHTS_STATE(PropertySetEnum.NIGHT_LIGHTS_STATE, NightLightsStateReceiver.class), + + HEIGHT_LIMIT(PropertySetEnum.HEIGHT_LIMIT, HeightLimitReceiver.class), + + DISTANCE_LIMIT_STATUS(PropertySetEnum.DISTANCE_LIMIT_STATUS, DistanceLimitStatusReceiver.class), + + OBSTACLE_AVOIDANCE(PropertySetEnum.OBSTACLE_AVOIDANCE, ObstacleAvoidanceReceiver.class), + + RTH_ALTITUDE(PropertySetEnum.RTH_ALTITUDE, RthAltitudeReceiver.class), + + OUT_OF_CONTROL_ACTION(PropertySetEnum.OUT_OF_CONTROL_ACTION, OutOfControlActionReceiver.class), + +// EXIT_WAYLINE_WHEN_RC_LOST(PropertySetEnum.EXIT_WAYLINE_WHEN_RC_LOST, .class), +// +// THERMAL_CURRENT_PALETTE_STYLE(PropertySetEnum.THERMAL_CURRENT_PALETTE_STYLE, .class), +// +// THERMAL_GAIN_MODE(PropertySetEnum.THERMAL_GAIN_MODE, .class), +// +// THERMAL_ISOTHERM_STATE(PropertySetEnum.THERMAL_ISOTHERM_STATE, .class), +// +// THERMAL_ISOTHERM_UPPER_LIMIT(PropertySetEnum.THERMAL_ISOTHERM_UPPER_LIMIT, .class), +// +// THERMAL_ISOTHERM_LOWER_LIMIT(PropertySetEnum.THERMAL_ISOTHERM_LOWER_LIMIT, .class), + + ; + + private final PropertySetEnum property; + + private final Class clazz; + + PropertySetFieldEnum(PropertySetEnum property, Class clazz) { + this.property = property; + this.clazz = clazz; + } + + public PropertySetEnum getProperty() { + return property; + } + + @JsonValue + public String getPropertyName() { + return property.getProperty(); + } + + public Class getClazz() { + return clazz; + } + + public static PropertySetFieldEnum find(String property) { + return Arrays.stream(values()).filter(propertyEnum -> propertyEnum.property.getProperty().equals(property)).findAny() + .orElseThrow(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/StateSwitchEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/StateSwitchEnum.java new file mode 100644 index 0000000..b7989cf --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/StateSwitchEnum.java @@ -0,0 +1,18 @@ +package com.dji.sample.manage.model.enums; + +import java.util.Arrays; +import java.util.Optional; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/28 + */ +public enum StateSwitchEnum { + + DISABLE, ENABLE; + + public static Optional find(int value) { + return Arrays.stream(StateSwitchEnum.values()).filter(state -> state.ordinal() == value).findAny(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/UserTypeEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/UserTypeEnum.java new file mode 100644 index 0000000..a90e526 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/enums/UserTypeEnum.java @@ -0,0 +1,42 @@ +package com.dji.sample.manage.model.enums; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/2 + */ +public enum UserTypeEnum { + + WEB(1, "Web"), + + PILOT(2, "Pilot"), + + UNKNOWN(-1, "Unknown"); + + private int val; + + private String desc; + + UserTypeEnum(int val, String desc) { + this.val = val; + this.desc = desc; + } + + public int getVal() { + return this.val; + } + + public String getDesc() { + return this.desc; + } + + public static UserTypeEnum find(int val) { + if (val == WEB.val) { + return WEB; + } + if (val == PILOT.val) { + return PILOT; + } + return UNKNOWN; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceFirmwareQueryParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceFirmwareQueryParam.java new file mode 100644 index 0000000..ffcc8fb --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceFirmwareQueryParam.java @@ -0,0 +1,36 @@ +package com.dji.sample.manage.model.param; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/12/1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DeviceFirmwareQueryParam { + + @JsonProperty("device_name") + private String deviceName; + + @JsonProperty("product_version") + private String productVersion; + + private Boolean status; + + @NotNull + private Long page; + + @NotNull + @JsonProperty("page_size") + private Long pageSize; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceFirmwareUpdateParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceFirmwareUpdateParam.java new file mode 100644 index 0000000..45c357d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceFirmwareUpdateParam.java @@ -0,0 +1,17 @@ +package com.dji.sample.manage.model.param; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.3 + * @date 2022/12/6 + */ +@Data +public class DeviceFirmwareUpdateParam { + + @NotNull + private Boolean status; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceFirmwareUploadParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceFirmwareUploadParam.java new file mode 100644 index 0000000..deeb67f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceFirmwareUploadParam.java @@ -0,0 +1,27 @@ +package com.dji.sample.manage.model.param; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author sean + * @version 1.3 + * @date 2022/12/1 + */ +@Data +public class DeviceFirmwareUploadParam { + + @NotNull + @JsonProperty("release_note") + private String releaseNote; + + @NotNull + private Boolean status; + + @NotNull + @JsonProperty("device_name") + private List deviceName; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceHmsQueryParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceHmsQueryParam.java new file mode 100644 index 0000000..35eaca8 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceHmsQueryParam.java @@ -0,0 +1,44 @@ +package com.dji.sample.manage.model.param; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Set; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/8 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DeviceHmsQueryParam { + + @JsonProperty("device_sn") + private Set deviceSn; + + @JsonProperty("begin_time") + private Long beginTime; + + @JsonProperty("end_time") + private Long endTime; + + private String language; + + private String message; + + private Long page; + + @JsonProperty("page_size") + private Long pageSize; + + private Integer level; + + @JsonProperty("update_time") + private Long updateTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceLogsCreateParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceLogsCreateParam.java new file mode 100644 index 0000000..7870d79 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceLogsCreateParam.java @@ -0,0 +1,21 @@ +package com.dji.sample.manage.model.param; + +import com.dji.sdk.cloudapi.log.FileUploadStartFile; +import lombok.Data; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/8 + */ +@Data +public class DeviceLogsCreateParam { + + private String logsInformation; + + private Long happenTime; + + private List files; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceLogsGetParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceLogsGetParam.java new file mode 100644 index 0000000..54325a9 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceLogsGetParam.java @@ -0,0 +1,19 @@ +package com.dji.sample.manage.model.param; + +import com.dji.sdk.cloudapi.log.LogModuleEnum; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@Data +public class DeviceLogsGetParam { + + @JsonProperty("domain_list") + List domainList; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceLogsQueryParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceLogsQueryParam.java new file mode 100644 index 0000000..5674bb8 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceLogsQueryParam.java @@ -0,0 +1,29 @@ +package com.dji.sample.manage.model.param; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@Data +public class DeviceLogsQueryParam { + + private Long page; + + @JsonProperty("page_size") + private Long pageSize; + + private Integer status; + + @JsonProperty("begin_time") + private Long beginTime; + + @JsonProperty("end_time") + private Long endTime; + + @JsonProperty("logs_information") + private String logsInformation; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceQueryParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceQueryParam.java new file mode 100644 index 0000000..b9fc67e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/DeviceQueryParam.java @@ -0,0 +1,36 @@ +package com.dji.sample.manage.model.param; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * The object of the device query field. + * + * @author sean.zhou + * @date 2021/11/16 + * @version 0.1 + */ +@Data +@Builder +public class DeviceQueryParam { + + private String deviceSn; + + private String workspaceId; + + private Integer deviceType; + + private Integer subType; + + private List domains; + + private String childSn; + + private Boolean boundStatus; + + private boolean orderBy; + + private boolean isAsc; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/LogsFileUpdateParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/LogsFileUpdateParam.java new file mode 100644 index 0000000..fe7f183 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/param/LogsFileUpdateParam.java @@ -0,0 +1,21 @@ +package com.dji.sample.manage.model.param; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +@Data +public class LogsFileUpdateParam { + + private String status; + + @JsonProperty("module_list") + private List deviceModelDomainList; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/BasicDeviceProperty.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/BasicDeviceProperty.java new file mode 100644 index 0000000..c02b546 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/BasicDeviceProperty.java @@ -0,0 +1,19 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sdk.cloudapi.device.OsdDockDrone; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public abstract class BasicDeviceProperty { + + public boolean valid() { + return false; + } + + public boolean canPublish(OsdDockDrone osd) { + return valid(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/CapacityCameraReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/CapacityCameraReceiver.java new file mode 100644 index 0000000..9747533 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/CapacityCameraReceiver.java @@ -0,0 +1,24 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sdk.cloudapi.device.PayloadIndex; +import lombok.Data; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +@Data +public class CapacityCameraReceiver { + + private Integer availableVideoNumber; + + private Integer coexistVideoNumberMax; + + private PayloadIndex cameraIndex; + + private List videoList; + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/CapacityDeviceReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/CapacityDeviceReceiver.java new file mode 100644 index 0000000..63edf06 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/CapacityDeviceReceiver.java @@ -0,0 +1,23 @@ +package com.dji.sample.manage.model.receiver; + +import lombok.Data; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +@Data +public class CapacityDeviceReceiver { + + private String sn; + + private Integer availableVideoNumber; + + private Integer coexistVideoNumberMax; + + private List cameraList; + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/CapacityVideoReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/CapacityVideoReceiver.java new file mode 100644 index 0000000..1939641 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/CapacityVideoReceiver.java @@ -0,0 +1,21 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sdk.cloudapi.livestream.VideoTypeEnum; +import lombok.Data; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +@Data +public class CapacityVideoReceiver { + + private String videoIndex; + + private VideoTypeEnum videoType; + + private List switchableVideoTypes; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/DeviceBasicReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/DeviceBasicReceiver.java new file mode 100644 index 0000000..423624c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/DeviceBasicReceiver.java @@ -0,0 +1,31 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sample.manage.model.dto.DevicePayloadReceiver; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/18 + * @version 0.1 + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class DeviceBasicReceiver { + + private String deviceSn; + + private String controlSource; + + private Float homeLatitude; + + private Float homeLongitude; + + private Integer lowBatteryWarningThreshold; + + private Integer seriousLowBatteryWarningThreshold; + + private List payloads; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/DeviceMaintainStatusReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/DeviceMaintainStatusReceiver.java new file mode 100644 index 0000000..05e3ed4 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/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/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/DistanceLimitStatusReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/DistanceLimitStatusReceiver.java new file mode 100644 index 0000000..42c9004 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/DistanceLimitStatusReceiver.java @@ -0,0 +1,51 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sdk.cloudapi.device.DockDistanceLimitStatus; +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.device.SwitchActionEnum; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.Objects; + +/** + * The state of the drone's limited distance + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DistanceLimitStatusReceiver extends BasicDeviceProperty { + + private SwitchActionEnum state; + + private Integer distanceLimit; + + private static final int DISTANCE_MAX = 8000; + + private static final int DISTANCE_MIN = 15; + + @Override + public boolean valid() { + if (Objects.isNull(state) && Objects.isNull(distanceLimit)) { + return false; + } + if (Objects.nonNull(distanceLimit)) { + return distanceLimit >= DISTANCE_MIN && distanceLimit <= DISTANCE_MAX; + } + return true; + } + + @Override + public boolean canPublish(OsdDockDrone osd) { + DockDistanceLimitStatus distanceLimitStatus = osd.getDistanceLimitStatus(); + return (Objects.nonNull(distanceLimitStatus.getState()) && distanceLimitStatus.getState() != this.state) + || (Objects.nonNull(distanceLimitStatus.getDistanceLimit()) + && distanceLimitStatus.getDistanceLimit().intValue() != this.distanceLimit); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/DockSdrReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/DockSdrReceiver.java new file mode 100644 index 0000000..4067717 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/DockSdrReceiver.java @@ -0,0 +1,18 @@ +package com.dji.sample.manage.model.receiver; + +import lombok.Data; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/17 + */ +@Data +public class DockSdrReceiver { + + private Integer downQuality; + + private Double frequencyBand; + + private Integer upQuality; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/FirmwareVersionReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/FirmwareVersionReceiver.java new file mode 100644 index 0000000..94ed706 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/FirmwareVersionReceiver.java @@ -0,0 +1,29 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.0 + * @date 2022/4/28 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class FirmwareVersionReceiver { + + private String firmwareVersion; + + private Integer compatibleStatus; + + private Integer firmwareUpgradeStatus; + + private String sn; + + private DeviceDomainEnum domain; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/HeightLimitReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/HeightLimitReceiver.java new file mode 100644 index 0000000..a8b8e4f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/HeightLimitReceiver.java @@ -0,0 +1,37 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.Objects; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/28 + */ +@EqualsAndHashCode(callSuper = true) +@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 heightLimit; + + @Override + public boolean valid() { + return Objects.nonNull(this.heightLimit) && this.heightLimit >= HEIGHT_LIMIT_MIN && this.heightLimit <= HEIGHT_LIMIT_MAX; + } + + @Override + public boolean canPublish(OsdDockDrone osd) { + return heightLimit.intValue() != osd.getHeightLimit(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/LiveCapacityReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/LiveCapacityReceiver.java new file mode 100644 index 0000000..af471b7 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/LiveCapacityReceiver.java @@ -0,0 +1,20 @@ +package com.dji.sample.manage.model.receiver; + +import lombok.Data; + +import java.util.List; + +/** + * @author sean + * @version 1.0 + * @date 2022/5/24 + */ +@Data +public class LiveCapacityReceiver { + + private Integer availableVideoNumber; + + private Integer coexistVideoNumberMax; + + private List deviceList; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/MaintainStatusReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/MaintainStatusReceiver.java new file mode 100644 index 0000000..7896f31 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/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/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/NightLightsStateReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/NightLightsStateReceiver.java new file mode 100644 index 0000000..c966b26 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/NightLightsStateReceiver.java @@ -0,0 +1,32 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.device.SwitchActionEnum; +import com.fasterxml.jackson.annotation.JsonCreator; + +import java.util.Objects; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/25 + */ +public class NightLightsStateReceiver extends BasicDeviceProperty { + + private SwitchActionEnum nightLightsState; + + @JsonCreator + public NightLightsStateReceiver(Integer nightLightsState) { + this.nightLightsState = SwitchActionEnum.find(nightLightsState); + } + + @Override + public boolean valid() { + return Objects.nonNull(nightLightsState); + } + + @Override + public boolean canPublish(OsdDockDrone osd) { + return nightLightsState != osd.getNightLightsState(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/ObstacleAvoidanceReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/ObstacleAvoidanceReceiver.java new file mode 100644 index 0000000..cc10413 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/ObstacleAvoidanceReceiver.java @@ -0,0 +1,37 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sdk.cloudapi.device.ObstacleAvoidance; +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.device.SwitchActionEnum; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Objects; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ObstacleAvoidanceReceiver extends BasicDeviceProperty { + + private SwitchActionEnum horizon; + + private SwitchActionEnum upside; + + private SwitchActionEnum downside; + + public boolean valid() { + return Objects.nonNull(this.horizon) || Objects.nonNull(this.upside) || Objects.nonNull(this.downside); + } + + @Override + public boolean canPublish(OsdDockDrone osd) { + ObstacleAvoidance obstacleAvoidance = osd.getObstacleAvoidance(); + return (Objects.nonNull(obstacleAvoidance.getHorizon()) && horizon != obstacleAvoidance.getHorizon()) + || (Objects.nonNull(obstacleAvoidance.getUpside()) && upside != obstacleAvoidance.getUpside()) + || (Objects.nonNull(obstacleAvoidance.getDownside()) && downside != obstacleAvoidance.getDownside()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/OutOfControlActionReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/OutOfControlActionReceiver.java new file mode 100644 index 0000000..7b00d69 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/OutOfControlActionReceiver.java @@ -0,0 +1,32 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.device.RcLostActionEnum; +import com.fasterxml.jackson.annotation.JsonCreator; + +import java.util.Objects; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +public class OutOfControlActionReceiver extends BasicDeviceProperty { + + private RcLostActionEnum rcLostAction; + + @JsonCreator + public OutOfControlActionReceiver(Integer rcLostAction) { + this.rcLostAction = RcLostActionEnum.find(rcLostAction); + } + + @Override + public boolean valid() { + return Objects.nonNull(rcLostAction); + } + + @Override + public boolean canPublish(OsdDockDrone osd) { + return rcLostAction != osd.getRcLostAction(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/OutputLogsProgressReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/OutputLogsProgressReceiver.java new file mode 100644 index 0000000..9f5a0a6 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/OutputLogsProgressReceiver.java @@ -0,0 +1,17 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sdk.cloudapi.log.FileUploadProgressExt; +import lombok.Data; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/9 + */ +@Data +public class OutputLogsProgressReceiver { + + private FileUploadProgressExt ext; + + private String status; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/RthAltitudeReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/RthAltitudeReceiver.java new file mode 100644 index 0000000..0d3bd54 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/RthAltitudeReceiver.java @@ -0,0 +1,37 @@ +package com.dji.sample.manage.model.receiver; + +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.Objects; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/3 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RthAltitudeReceiver extends BasicDeviceProperty { + + private Integer rthAltitude; + + private static final int RTH_ALTITUDE_MAX = 500; + + private static final int RTH_ALTITUDE_MIN = 20; + + @Override + public boolean valid() { + return Objects.nonNull(rthAltitude) && rthAltitude >= RTH_ALTITUDE_MIN && rthAltitude <= RTH_ALTITUDE_MAX; + } + + @Override + public boolean canPublish(OsdDockDrone osd) { + return rthAltitude != osd.getRthAltitude().intValue(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/StatusGatewayReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/StatusGatewayReceiver.java new file mode 100644 index 0000000..0cee5ed --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/StatusGatewayReceiver.java @@ -0,0 +1,43 @@ +package com.dji.sample.manage.model.receiver; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * + * @author sean.zhou + * @version 0.1 + * @date 2021/11/12 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class StatusGatewayReceiver { + + private String sn; + + private Integer domain; + + private Integer type; + + @JsonProperty(value = "sub_type") + private Integer subType; + + @JsonProperty(value = "device_secret") + private String deviceSecret; + + private String nonce; + + private Integer version; + + @JsonProperty(value = "sub_devices") + private List subDevices; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/StatusSubDeviceReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/StatusSubDeviceReceiver.java new file mode 100644 index 0000000..428f16c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/StatusSubDeviceReceiver.java @@ -0,0 +1,34 @@ +package com.dji.sample.manage.model.receiver; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * + * @author sean.zhou + * @version 0.1 + * @date 2021/11/12 + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class StatusSubDeviceReceiver { + + private String sn; + + private Integer domain; + + private Integer type; + + @JsonProperty(value = "sub_type") + private Integer subType; + + private String index; + + @JsonProperty(value = "device_secret") + private String deviceSecret; + + private String nonce; + + private Integer version; +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/WirelessLinkStateReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/WirelessLinkStateReceiver.java new file mode 100644 index 0000000..797d351 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/receiver/WirelessLinkStateReceiver.java @@ -0,0 +1,19 @@ +package com.dji.sample.manage.model.receiver; + +import lombok.Data; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/23 + */ +@Data +public class WirelessLinkStateReceiver { + + private Integer downloadQuality; + + private Double frequencyBand; + + private Integer upwardQuality; + +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ICameraVideoService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ICameraVideoService.java new file mode 100644 index 0000000..df2f1ec --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ICameraVideoService.java @@ -0,0 +1,19 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.CapacityVideoDTO; +import com.dji.sample.manage.model.receiver.CapacityVideoReceiver; + +/** + * @author sean.zhou + * @date 2021/11/19 + * @version 0.1 + */ +public interface ICameraVideoService { + + /** + * Convert the received lens capability object into lens data transfer object. + * @param receiver + * @return data transfer object + */ + CapacityVideoDTO receiver2Dto(CapacityVideoReceiver receiver); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ICapacityCameraService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ICapacityCameraService.java new file mode 100644 index 0000000..df4d3ee --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ICapacityCameraService.java @@ -0,0 +1,42 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.CapacityCameraDTO; +import com.dji.sample.manage.model.receiver.CapacityCameraReceiver; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/19 + * @version 0.1 + */ +public interface ICapacityCameraService { + + /** + * Query all camera data that can be live streamed from this device based on the device sn. + * @param deviceSn + * @return + */ + List getCapacityCameraByDeviceSn(String deviceSn); + + /** + * Delete all live capability data for this device based on the device sn. + * @param deviceSn + * @return + */ + Boolean deleteCapacityCameraByDeviceSn(String deviceSn); + + /** + * Save the live capability data of the device. + * @param capacityCameraReceivers + * @param deviceSn + */ + void saveCapacityCameraReceiverList(List capacityCameraReceivers, String deviceSn); + + /** + * Convert the received camera capability object into camera data transfer object. + * @param receiver + * @return + */ + CapacityCameraDTO receiver2Dto(CapacityCameraReceiver receiver); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceDictionaryService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceDictionaryService.java new file mode 100644 index 0000000..97b901b --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceDictionaryService.java @@ -0,0 +1,24 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.DeviceDictionaryDTO; + +import java.util.Optional; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/15 + */ +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 domain, Integer deviceType, Integer subType); + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceFirmwareService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceFirmwareService.java new file mode 100644 index 0000000..aab0992 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceFirmwareService.java @@ -0,0 +1,87 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.DeviceFirmwareDTO; +import com.dji.sample.manage.model.dto.DeviceFirmwareNoteDTO; +import com.dji.sample.manage.model.dto.DeviceFirmwareUpgradeDTO; +import com.dji.sample.manage.model.param.DeviceFirmwareQueryParam; +import com.dji.sample.manage.model.param.DeviceFirmwareUploadParam; +import com.dji.sdk.cloudapi.firmware.OtaCreateDevice; +import com.dji.sdk.common.PaginationData; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/16 + */ +public interface IDeviceFirmwareService { + + /** + * Query specific firmware information based on the device model and firmware version. + * + * @param workspaceId + * @param deviceName + * @param version + * @return + */ + Optional getFirmware(String workspaceId, String deviceName, String version); + + /** + * Get the latest firmware release note for this device model. + * @param deviceName + * @return + */ + Optional getLatestFirmwareReleaseNote(String deviceName); + + /** + * Get the firmware information that the device needs to update. + * + * @param workspaceId + * @param upgradeDTOS + * @return + */ + List getDeviceOtaFirmware(String workspaceId, List upgradeDTOS); + + /** + * Query firmware version information by page. + * + * @param workspaceId + * @param param + * @return + */ + PaginationData getAllFirmwarePagination(String workspaceId, DeviceFirmwareQueryParam param); + + /** + * Checks for file existence based on md5. + * + * @param workspaceId + * @param fileMd5 + * @return + */ + Boolean checkFileExist(String workspaceId, String fileMd5); + + /** + * Import firmware file for device upgrades. + * @param workspaceId + * @param creator + * @param param + * @param file + */ + void importFirmwareFile(String workspaceId, String creator, DeviceFirmwareUploadParam param, MultipartFile file); + + /** + * Save the file information of the firmware. + * @param firmware + * @param deviceNames + */ + void saveFirmwareInfo(DeviceFirmwareDTO firmware, List deviceNames); + + /** + * Update the file information of the firmware. + * @param firmware + */ + void updateFirmwareInfo(DeviceFirmwareDTO firmware); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceHmsService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceHmsService.java new file mode 100644 index 0000000..afbd681 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceHmsService.java @@ -0,0 +1,26 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.DeviceHmsDTO; +import com.dji.sample.manage.model.param.DeviceHmsQueryParam; +import com.dji.sdk.common.PaginationData; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/6 + */ +public interface IDeviceHmsService { + + /** + * Query hms data by paging according to query parameters. + * @param param + * @return + */ + PaginationData getDeviceHmsByParam(DeviceHmsQueryParam param); + + /** + * Read message handling. + * @param deviceSn + */ + void updateUnreadHms(String deviceSn); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceLogsService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceLogsService.java new file mode 100644 index 0000000..b4f6800 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceLogsService.java @@ -0,0 +1,86 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.DeviceLogsDTO; +import com.dji.sample.manage.model.param.DeviceLogsCreateParam; +import com.dji.sample.manage.model.param.DeviceLogsQueryParam; +import com.dji.sdk.cloudapi.log.FileUploadUpdateRequest; +import com.dji.sdk.cloudapi.log.LogModuleEnum; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; + +import java.net.URL; +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public interface IDeviceLogsService { + + /** + * Obtain the device upload log list by paging according to the query parameters. + * @param deviceSn + * @param param + * @return + */ + PaginationData getUploadedLogs(String deviceSn, DeviceLogsQueryParam param); + + /** + * Get a list of log files that can be uploaded in real time. + * @param deviceSn + * @param domainList + * @return + */ + HttpResultResponse getRealTimeLogs(String deviceSn, List domainList); + + /** + * Add device logs. + * + * @param bid + * @param username + * @param deviceSn + * @param param + * @return logs id + */ + String insertDeviceLogs(String bid, String username, String deviceSn, DeviceLogsCreateParam param); + + /** + * Initiate a log upload request to the gateway. + * @param username + * @param deviceSn + * @param param + * @return + */ + HttpResultResponse pushFileUpload(String username, String deviceSn, DeviceLogsCreateParam param); + + /** + * Push a request to modify the status of the logs file. + * @param deviceSn + * @param param + * @return + */ + HttpResultResponse pushUpdateFile(String deviceSn, FileUploadUpdateRequest param); + + /** + * Delete log records. + * @param deviceSn + * @param logsId + */ + void deleteLogs(String deviceSn, String logsId); + + /** + * Update status, which is updated when the logs upload succeeds or fails. + * @param logsId + * @param value + */ + void updateLogsStatus(String logsId, Integer value); + + /** + * Get the file address. + * @param logsId + * @param fileId + * @return + */ + URL getLogsFileUrl(String logsId, String fileId); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDevicePayloadService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDevicePayloadService.java new file mode 100644 index 0000000..d6abfec --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDevicePayloadService.java @@ -0,0 +1,73 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.dto.DevicePayloadDTO; +import com.dji.sample.manage.model.dto.DevicePayloadReceiver; +import com.dji.sdk.cloudapi.device.PayloadFirmwareVersion; + +import java.util.Collection; +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/19 + * @version 0.1 + */ +public interface IDevicePayloadService { + + /** + * Query if the payload has been saved based on the sn of the payload. + * @param payloadSn + * @return + */ + Integer checkPayloadExist(String payloadSn); + + /** + * Save all payload data. + * @param payloadReceiverList + * @return + */ + Boolean savePayloadDTOs(DeviceDTO drone, List payloadReceiverList); + + /** + * Save a payload data. + * @param payloadReceiver + * @return + */ + Integer saveOnePayloadDTO(DevicePayloadReceiver payloadReceiver); + + /** + * Query all payload data on this device based on the device sn. + * @param deviceSn + * @return + */ + List getDevicePayloadEntitiesByDeviceSn(String deviceSn); + + /** + * Delete all payload data on these devices based on the collection of device sns. + * @param deviceSns + */ + void deletePayloadsByDeviceSn(List deviceSns); + + /** + * Update the firmware version information of the payload. + * @param receiver + */ + Boolean updateFirmwareVersion(String droneSn, PayloadFirmwareVersion receiver); + + /** + * Delete payload data based on payload sn. + * @param payloadSns + */ + void deletePayloadsByPayloadsSn(Collection payloadSns); + + /** + * Check if the device has payload control. + * @param deviceSn + * @param payloadIndex + * @return + */ + Boolean checkAuthorityPayload(String deviceSn, String payloadIndex); + + void updatePayloadControl(DeviceDTO drone, List payloads); +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceRedisService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceRedisService.java new file mode 100644 index 0000000..cd1afc2 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceRedisService.java @@ -0,0 +1,112 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sdk.cloudapi.firmware.OtaProgress; + +import java.util.Optional; +import java.util.Set; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/21 + */ +public interface IDeviceRedisService { + + /** + * Determine if the device is online. + * @param sn + * @return + */ + Boolean checkDeviceOnline(String sn); + + /** + * Query the basic information of the device in redis. + * @param sn + * @return + */ + Optional getDeviceOnline(String sn); + + /** + * Save the basic information of the device in redis. + * @param device + */ + void setDeviceOnline(DeviceDTO device); + + /** + * Delete the basic device information saved in redis. + * @param sn + * @return + */ + Boolean delDeviceOnline(String sn); + + /** + * Save the device's osd real-time data. + * @param sn + * @param data + * @return + */ + void setDeviceOsd(String sn, Object data); + + /** + * Get the device's osd real-time data. + * @param sn + * @param clazz + * @param + * @return + */ + Optional getDeviceOsd(String sn, Class clazz); + /** + * Delete the device's osd real-time data. + * @param sn + * @return + */ + Boolean delDeviceOsd(String sn); + + /** + * Save the firmware update progress of the device in redis. + * @param sn + * @param events + */ + void setFirmwareUpgrading(String sn, EventsReceiver events); + + /** + * Query the firmware update progress of the device in redis. + * @param sn + * @return + */ + Optional> getFirmwareUpgradingProgress(String sn); + + /** + * Delete the firmware update progress of the device in redis. + * @param sn + * @return + */ + Boolean delFirmwareUpgrading(String sn); + + /** + * Save the hms key of the device in redis. + * @param sn + * @param keys + */ + void addEndHmsKeys(String sn, String... keys); + + /** + * Query all hms keys of the device in redis. + * @param sn + * @return + */ + Set getAllHmsKeys(String sn); + + /** + * Delete all hms keys of the device in redis. + * @param sn + * @return + */ + Boolean delHmsKeysBySn(String sn); + + void gatewayOffline(String gatewaySn); + + void subDeviceOffline(String deviceSn); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceService.java new file mode 100644 index 0000000..df0efa2 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceService.java @@ -0,0 +1,200 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.dto.DeviceFirmwareUpgradeDTO; +import com.dji.sample.manage.model.dto.TopologyDeviceDTO; +import com.dji.sample.manage.model.param.DeviceQueryParam; +import com.dji.sdk.cloudapi.device.ControlSourceEnum; +import com.dji.sdk.cloudapi.device.DeviceOsdHost; +import com.dji.sdk.cloudapi.device.DockModeCodeEnum; +import com.dji.sdk.cloudapi.device.DroneModeCodeEnum; +import com.dji.sdk.config.version.GatewayManager; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; +import com.fasterxml.jackson.databind.JsonNode; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean.zhou + * @date 2021/11/10 + * @version 0.1 + */ +public interface IDeviceService { + + /** + * The aircraft goes offline. + * @param deviceSn aircraft's SN + */ + void subDeviceOffline(String deviceSn); + + /** + * The gateway goes offline. + * @param gatewaySn gateway's SN + */ + void gatewayOffline(String gatewaySn); + + /** + * Subscribe to the topic of the gateway when the gateway device goes online, and unsubscribe from the topic of the sub-device. + * @param gateway + */ + void gatewayOnlineSubscribeTopic(GatewayManager gateway); + + /** + * Subscribe to the gateway's and sub-device's topics when the drone comes online. + * @param gateway + */ + void subDeviceOnlineSubscribeTopic(GatewayManager gateway); + + /** + * When the gateway device goes offline, unsubscribe from the topics of the gateway and sub-device. + * @param gateway + */ + void offlineUnsubscribeTopic(GatewayManager gateway); + + /** + * Obtain device data according to different query conditions. + * @param param query parameters + * @return + */ + List getDevicesByParams(DeviceQueryParam param); + + /** + * The business interface on the web side. Get all information about all devices in this workspace. + * @param workspaceId + * @return + */ + List getDevicesTopoForWeb(String workspaceId); + + /** + * Set the remote controller and payloads information of the drone. + * @param device + */ + void spliceDeviceTopo(DeviceDTO device); + + /** + * Query the information of the device according to the sn of the device. + * @param sn device sn + * @return + */ + Optional getDeviceTopoForPilot(String sn); + + /** + * Convert individual device information into topology objects. + * @param device + * @return + */ + TopologyDeviceDTO deviceConvertToTopologyDTO(DeviceDTO device); + + /** + * When the server receives the request of any device online, offline and topology update in the same workspace, + * it also broadcasts a push of device online, offline and topology update to PILOT via websocket, + * and PILOT will get the device topology list again after receiving the push. + * @param workspaceId + * @param deviceSn + */ + void pushDeviceOfflineTopo(String workspaceId, String deviceSn); + + /** + * When the server receives the request of any device online, offline and topology update in the same workspace, + * it also broadcasts a push of device online, offline and topology update to PILOT via websocket, + * and PILOT will get the device topology list again after receiving the push. + * @param workspaceId + * @param gatewaySn + * @param deviceSn + */ + void pushDeviceOnlineTopo(String workspaceId, String gatewaySn, String deviceSn); + + /** + * Update the device information. + * @param deviceDTO + * @return + */ + Boolean updateDevice(DeviceDTO deviceDTO); + + /** + * Bind devices to organizations and people. + * @param device + */ + Boolean bindDevice(DeviceDTO device); + + /** + * Get the binding devices list in one workspace. + * @param workspaceId + * @param page + * @param pageSize + * @param domain + * @return + */ + PaginationData getBoundDevicesWithDomain(String workspaceId, Long page, Long pageSize, Integer domain); + + /** + * Unbind device base on device's sn. + * @param deviceSn + */ + void unbindDevice(String deviceSn); + + /** + * Get device information based on device's sn. + * @param sn device's sn + * @return device + */ + Optional getDeviceBySn(String sn); + + /** + * Create job for device firmware updates. + * @param workspaceId + * @param upgradeDTOS + * @return + */ + HttpResultResponse createDeviceOtaJob(String workspaceId, List upgradeDTOS); + + /** + * Set the property parameters of the drone. + * @param workspaceId + * @param dockSn + * @param param + * @return + */ + int devicePropertySet(String workspaceId, String dockSn, JsonNode param); + + /** + * Check the working status of the dock. + * @param dockSn + * @return + */ + DockModeCodeEnum getDockMode(String dockSn); + + /** + * Query the working status of the aircraft. + * @param deviceSn + * @return + */ + DroneModeCodeEnum getDeviceMode(String deviceSn); + + /** + * Check if the dock is in drc mode. + * @param dockSn + * @return + */ + Boolean checkDockDrcMode(String dockSn); + + /** + * Check if the device has flight control. + * @param gatewaySn + * @return + */ + Boolean checkAuthorityFlight(String gatewaySn); + + Integer saveDevice(DeviceDTO device); + + Boolean saveOrUpdateDevice(DeviceDTO device); + + void pushOsdDataToPilot(String workspaceId, String sn, DeviceOsdHost data); + + void pushOsdDataToWeb(String workspaceId, BizCodeEnum codeEnum, String sn, Object data); + + void updateFlightControl(DeviceDTO gateway, ControlSourceEnum controlSource); +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IFirmwareModelService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IFirmwareModelService.java new file mode 100644 index 0000000..4aaaa81 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IFirmwareModelService.java @@ -0,0 +1,18 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.FirmwareModelDTO; + +/** + * @author sean + * @version 1.3 + * @date 2022/12/21 + */ +public interface IFirmwareModelService { + + /** + * Save the relationship between firmware files and device models. + * @param firmwareModel + */ + void saveFirmwareDeviceName(FirmwareModelDTO firmwareModel); + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ILiveStreamService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ILiveStreamService.java new file mode 100644 index 0000000..e18eaac --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ILiveStreamService.java @@ -0,0 +1,51 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.CapacityDeviceDTO; +import com.dji.sample.manage.model.dto.LiveTypeDTO; +import com.dji.sdk.cloudapi.device.VideoId; +import com.dji.sdk.common.HttpResultResponse; + +import java.util.List; + +/** + * @author sean.zhou + * @date 2021/11/19 + * @version 0.1 + */ +public interface ILiveStreamService { + + /** + * Get all the drone data that can be broadcast live in this workspace. + * @param workspaceId + * @return + */ + List getLiveCapacity(String workspaceId); + + /** + * Initiate a live streaming by publishing mqtt message. + * @param liveParam Parameters needed for on-demand. + * @return + */ + HttpResultResponse liveStart(LiveTypeDTO liveParam); + + /** + * Stop the live streaming by publishing mqtt message. + * @param videoId + * @return + */ + HttpResultResponse liveStop(VideoId videoId); + + /** + * Readjust the clarity of the live streaming by publishing mqtt messages. + * @param liveParam + * @return + */ + HttpResultResponse liveSetQuality(LiveTypeDTO liveParam); + + /** + * Switches the lens of the device during the live streaming. + * @param liveParam + * @return + */ + HttpResultResponse liveLensChange(LiveTypeDTO liveParam); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ILogsFileIndexService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ILogsFileIndexService.java new file mode 100644 index 0000000..9d7da29 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ILogsFileIndexService.java @@ -0,0 +1,46 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.LogsFileDTO; +import com.dji.sample.manage.model.dto.LogsFileUploadDTO; +import com.dji.sdk.cloudapi.log.LogFileIndex; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/8 + */ +public interface ILogsFileIndexService { + + /** + * Insert the index of the device logs. + * @param file + * @param deviceSn + * @param domain + * @param fileId + * @return + */ + Boolean insertFileIndex(LogFileIndex file, String deviceSn, Integer domain, String fileId); + + /** + * Query logs file upload information based on the file id. + * @param fileId + * @return + */ + Optional getFileIndexByFileId(String fileId); + + /** + * Batch query logs file upload information. + * @param fileIds + * @return + */ + List getFileIndexByFileIds(List fileIds); + + /** + * Delete log index data based on file id. + * @param fileIds + */ + void deleteFileIndexByFileIds(List fileIds); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ILogsFileService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ILogsFileService.java new file mode 100644 index 0000000..0384ac1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ILogsFileService.java @@ -0,0 +1,67 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.LogsFileDTO; +import com.dji.sample.manage.model.dto.LogsFileUploadDTO; +import com.dji.sdk.cloudapi.log.FileUploadProgressFile; +import com.dji.sdk.cloudapi.log.FileUploadStartFile; + +import java.net.URL; +import java.util.List; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +public interface ILogsFileService { + + /** + * Query the uploaded log file information based on the log id. + * @param logsId + * @return + */ + List getLogsFileInfoByLogsId(String logsId); + + /** + * Query the uploaded log file structure information based on the log id. + * @param logsId + * @return + */ + List getLogsFileByLogsId(String logsId); + + /** + * Added logs file. + * @param file + * @param logsId + * @return + */ + Boolean insertFile(FileUploadStartFile file, String logsId); + + /** + * Delete logs files. + * @param logsId + */ + void deleteFileByLogsId(String logsId); + + /** + * Update file information. + * @param logsId + * @param fileReceiver + */ + void updateFile(String logsId, FileUploadProgressFile fileReceiver); + + /** + * Update file upload status. + * @param logsId + * @param isUploaded + */ + void updateFileUploadStatus(String logsId, Boolean isUploaded); + + /** + * Get the file address. + * @param logsId + * @param fileId + * @return + */ + URL getLogsFileUrl(String logsId, String fileId); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IRequestsConfigService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IRequestsConfigService.java new file mode 100644 index 0000000..9f0222b --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IRequestsConfigService.java @@ -0,0 +1,15 @@ +package com.dji.sample.manage.service; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +public interface IRequestsConfigService { + + /** + * Get the parameters required by config method. + * @return + */ + Object getConfig(); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ITopologyService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ITopologyService.java new file mode 100644 index 0000000..012d9c6 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ITopologyService.java @@ -0,0 +1,28 @@ +package com.dji.sample.manage.service; + +import com.dji.sdk.cloudapi.tsa.TopologyList; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +public interface ITopologyService { + + /** + * Get the topology list of all devices in the workspace for pilot display. + * @param workspaceId + * @return + */ + List getDeviceTopology(String workspaceId); + + /** + * Query the topology according to the gateway sn. + * @param gatewaySn + * @return + */ + Optional getDeviceTopologyByGatewaySn(String gatewaySn); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IUserService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IUserService.java new file mode 100644 index 0000000..7100565 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IUserService.java @@ -0,0 +1,44 @@ +package com.dji.sample.manage.service; + +import com.dji.sample.manage.model.dto.UserDTO; +import com.dji.sample.manage.model.dto.UserListDTO; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; + +import java.util.Optional; + +public interface IUserService { + + /** + * Query user's details based on username. + * @param username + * @param workspaceId + * @return + */ + HttpResultResponse getUserByUsername(String username, String workspaceId); + + /** + * Verify the username and password to log in. + * @param username + * @param password + * @param flag + * @return + */ + HttpResultResponse userLogin(String username, String password, Integer flag); + + /** + * Create a user object containing a new token. + * @param token + * @return + */ + Optional refreshToken(String token); + + /** + * Query information about all users in a workspace. + * @param workspaceId uuid + * @return + */ + PaginationData getUsersByWorkspaceId(long page, long pageSize, String workspaceId); + + Boolean updateUser(String workspaceId, String userId, UserListDTO user); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IWorkspaceService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IWorkspaceService.java new file mode 100644 index 0000000..eb3bcf5 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IWorkspaceService.java @@ -0,0 +1,24 @@ +package com.dji.sample.manage.service; + + +import com.dji.sample.manage.model.dto.WorkspaceDTO; + +import java.util.Optional; + +public interface IWorkspaceService { + + /** + * Query the information of a workspace based on its workspace id. + * @param workspaceId + * @return + */ + Optional getWorkspaceByWorkspaceId(String workspaceId); + + /** + * Query the workspace of a workspace based on bind code. + * @param bindCode + * @return + */ + Optional getWorkspaceNameByBindCode(String bindCode); + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/CameraVideoServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/CameraVideoServiceImpl.java new file mode 100644 index 0000000..23a061a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/CameraVideoServiceImpl.java @@ -0,0 +1,35 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.manage.model.dto.CapacityVideoDTO; +import com.dji.sample.manage.model.receiver.CapacityVideoReceiver; +import com.dji.sample.manage.service.ICameraVideoService; +import com.dji.sdk.cloudapi.livestream.VideoTypeEnum; +import org.springframework.stereotype.Service; + +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/19 + */ +@Service +public class CameraVideoServiceImpl implements ICameraVideoService { + + @Override + public CapacityVideoDTO receiver2Dto(CapacityVideoReceiver receiver) { + if (null == receiver) { + return null; + } + CapacityVideoDTO.CapacityVideoDTOBuilder builder = CapacityVideoDTO.builder() + .id(UUID.randomUUID().toString()) + .index(receiver.getVideoIndex()) + .type(receiver.getVideoType().getType()); + if (null != receiver.getSwitchableVideoTypes()) { + builder.switchVideoTypes(receiver.getSwitchableVideoTypes().stream() + .map(VideoTypeEnum::getType).collect(Collectors.toList())); + } + return builder.build(); + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/CapacityCameraServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/CapacityCameraServiceImpl.java new file mode 100644 index 0000000..3a4d087 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/CapacityCameraServiceImpl.java @@ -0,0 +1,75 @@ +package com.dji.sample.manage.service.impl; + +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.receiver.CapacityCameraReceiver; +import com.dji.sample.manage.service.ICameraVideoService; +import com.dji.sample.manage.service.ICapacityCameraService; +import com.dji.sample.manage.service.IDeviceDictionaryService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.device.PayloadIndex; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author sean.zhou + * @date 2021/11/19 + * @version 0.1 + */ +@Service +public class CapacityCameraServiceImpl implements ICapacityCameraService { + + @Autowired + private ICameraVideoService cameraVideoService; + + @Autowired + private IDeviceDictionaryService dictionaryService; + + @Override + public List getCapacityCameraByDeviceSn(String deviceSn) { + return (List) RedisOpsUtils.hashGet(RedisConst.LIVE_CAPACITY, deviceSn); + } + + @Override + public Boolean deleteCapacityCameraByDeviceSn(String deviceSn) { + return RedisOpsUtils.hashDel(RedisConst.LIVE_CAPACITY, new String[]{deviceSn}); + } + + @Override + public void saveCapacityCameraReceiverList(List capacityCameraReceivers, String deviceSn) { + List capacity = capacityCameraReceivers.stream() + .map(this::receiver2Dto).collect(Collectors.toList()); + RedisOpsUtils.hashSet(RedisConst.LIVE_CAPACITY, deviceSn, capacity); + } + + public CapacityCameraDTO receiver2Dto(CapacityCameraReceiver receiver) { + CapacityCameraDTO.CapacityCameraDTOBuilder builder = CapacityCameraDTO.builder(); + if (receiver == null) { + return builder.build(); + } + PayloadIndex cameraIndex = receiver.getCameraIndex(); + // The cameraIndex consists of type and subType and the index of the payload hanging on the drone. + // type-subType-index + Optional dictionaryOpt = dictionaryService.getOneDictionaryInfoByTypeSubType( + DeviceDomainEnum.PAYLOAD.getDomain(), cameraIndex.getType().getType(), cameraIndex.getSubType().getSubType()); + dictionaryOpt.ifPresent(dictionary -> builder.name(dictionary.getDeviceName())); + + return builder + .id(UUID.randomUUID().toString()) + .videosList(receiver.getVideoList() + .stream() + .map(cameraVideoService::receiver2Dto) + .filter(Objects::nonNull) + .collect(Collectors.toList())) + .index(receiver.getCameraIndex().toString()) + .build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/ConfigProductServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/ConfigProductServiceImpl.java new file mode 100644 index 0000000..2b2f59f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/ConfigProductServiceImpl.java @@ -0,0 +1,21 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.manage.model.common.AppLicenseProperties; +import com.dji.sample.manage.model.common.NtpServerProperties; +import com.dji.sample.manage.model.dto.ProductConfigDTO; +import com.dji.sample.manage.service.IRequestsConfigService; +import org.springframework.stereotype.Service; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +@Service +public class ConfigProductServiceImpl implements IRequestsConfigService { + + @Override + public Object getConfig() { + return new ProductConfigDTO(NtpServerProperties.host, AppLicenseProperties.id, AppLicenseProperties.key, AppLicenseProperties.license); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceDictionaryServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceDictionaryServiceImpl.java new file mode 100644 index 0000000..a4574b7 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceDictionaryServiceImpl.java @@ -0,0 +1,59 @@ +package com.dji.sample.manage.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.dji.sample.manage.dao.IDeviceDictionaryMapper; +import com.dji.sample.manage.model.dto.DeviceDictionaryDTO; +import com.dji.sample.manage.model.entity.DeviceDictionaryEntity; +import com.dji.sample.manage.service.IDeviceDictionaryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +/** + * + * @author sean.zhou + * @version 0.1 + * @date 2021/11/15 + */ +@Service +@Transactional +public class DeviceDictionaryServiceImpl implements IDeviceDictionaryService { + + @Autowired + private IDeviceDictionaryMapper mapper; + + @Override + 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) + .last(" limit 1 ")))); + } + + /** + * Convert database entity objects into dictionary data transfer object. + * @param entity + * @return + */ + private DeviceDictionaryDTO entityConvertToDTO(DeviceDictionaryEntity entity) { + DeviceDictionaryDTO.DeviceDictionaryDTOBuilder builder = DeviceDictionaryDTO.builder(); + + if (entity != null) { + builder.deviceName(entity.getDeviceName()) + .deviceDesc(entity.getDeviceDesc()) + .deviceType(entity.getDeviceType()) + .domain(entity.getDomain()) + .subType(entity.getSubType()); + } + return builder.build(); + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceFirmwareServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceFirmwareServiceImpl.java new file mode 100644 index 0000000..03c95f5 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceFirmwareServiceImpl.java @@ -0,0 +1,354 @@ +package com.dji.sample.manage.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.oss.service.impl.OssServiceContext; +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.dao.IDeviceFirmwareMapper; +import com.dji.sample.manage.model.dto.*; +import com.dji.sample.manage.model.entity.DeviceFirmwareEntity; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.model.param.DeviceFirmwareQueryParam; +import com.dji.sample.manage.model.param.DeviceFirmwareUploadParam; +import com.dji.sample.manage.service.IDeviceFirmwareService; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.manage.service.IFirmwareModelService; +import com.dji.sdk.cloudapi.firmware.FirmwareUpgradeTypeEnum; +import com.dji.sdk.cloudapi.firmware.OtaCreateDevice; +import com.dji.sdk.cloudapi.firmware.OtaProgress; +import com.dji.sdk.cloudapi.firmware.OtaProgressStatusEnum; +import com.dji.sdk.cloudapi.firmware.api.AbstractFirmwareService; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; +import org.springframework.util.DigestUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * @author sean + * @version 1.2 + * @date 2022/8/16 + */ +@Service +@Slf4j +public class DeviceFirmwareServiceImpl extends AbstractFirmwareService implements IDeviceFirmwareService { + + @Autowired + private IDeviceFirmwareMapper mapper; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private OssServiceContext ossServiceContext; + + @Autowired + private IFirmwareModelService firmwareModelService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Override + public Optional getFirmware(String workspaceId, String deviceName, String version) { + return Optional.ofNullable(entity2Dto(mapper.selectOne( + new LambdaQueryWrapper() + .eq(DeviceFirmwareEntity::getWorkspaceId, workspaceId) + .eq(DeviceFirmwareEntity::getFirmwareVersion, version) + .eq(DeviceFirmwareEntity::getStatus, true), + deviceName))); + } + + @Override + public Optional getLatestFirmwareReleaseNote(String deviceName) { + return Optional.ofNullable(entity2NoteDto(mapper.selectOne( + Wrappers.lambdaQuery(DeviceFirmwareEntity.class) + .eq(DeviceFirmwareEntity::getStatus, true) + .orderByDesc(DeviceFirmwareEntity::getReleaseDate, DeviceFirmwareEntity::getFirmwareVersion), + deviceName))); + } + + @Override + public List getDeviceOtaFirmware(String workspaceId, List upgradeDTOS) { + List deviceOtaList = new ArrayList<>(); + upgradeDTOS.forEach(upgradeDevice -> { + boolean exist = deviceRedisService.checkDeviceOnline(upgradeDevice.getSn()); + if (!exist) { + throw new IllegalArgumentException("设备处于脱机状态。"); + } + Optional firmwareOpt = this.getFirmware( + workspaceId, upgradeDevice.getDeviceName(), upgradeDevice.getProductVersion()); + if (firmwareOpt.isEmpty()) { + throw new IllegalArgumentException("此固件版本不存在或不可用。"); + } + OtaCreateDevice ota = dto2OtaCreateDto(firmwareOpt.get()); + ota.setSn(upgradeDevice.getSn()); + ota.setFirmwareUpgradeType(FirmwareUpgradeTypeEnum.find(upgradeDevice.getFirmwareUpgradeType())); + deviceOtaList.add(ota); + }); + return deviceOtaList; + } + + @Override + public TopicEventsResponse otaProgress(TopicEventsRequest> request, MessageHeaders headers) { + String sn = request.getGateway(); + + EventsReceiver eventsReceiver = new EventsReceiver() + .setBid(request.getBid()) + .setOutput(request.getData().getOutput()) + .setResult(request.getData().getResult()); + + + log.info("SN: {}, {} ===> 升级进度: {}", + sn, request.getMethod(), eventsReceiver.getOutput().getProgress()); + + if (!eventsReceiver.getResult().isSuccess()) { + log.error("SN: {}, {} ===> 错误: {}", sn, request.getMethod(), eventsReceiver.getResult()); + } + + Optional deviceOpt = deviceRedisService.getDeviceOnline(sn); + if (deviceOpt.isEmpty()) { + return null; + } + + OtaProgressStatusEnum statusEnum = eventsReceiver.getOutput().getStatus(); + DeviceDTO device = deviceOpt.get(); + handleProgress(device.getWorkspaceId(), sn, eventsReceiver, statusEnum.isEnd()); + handleProgress(device.getWorkspaceId(), device.getChildDeviceSn(), eventsReceiver, statusEnum.isEnd()); + + return new TopicEventsResponse().setData(MqttReply.success()); + } + + private void handleProgress(String workspaceId, String sn, EventsReceiver events, boolean isEnd) { + boolean upgrade = deviceRedisService.getFirmwareUpgradingProgress(sn).isPresent(); + if (!upgrade) { + return; + } + if (isEnd) { + // Delete the cache after the update is complete. + deviceRedisService.delFirmwareUpgrading(sn); + } else { + // Update the update progress of the dock in redis. + deviceRedisService.setFirmwareUpgrading(sn, events); + } + events.setSn(sn); + webSocketMessageService.sendBatch(workspaceId, UserTypeEnum.WEB.getVal(), BizCodeEnum.OTA_PROGRESS.getCode(), events); + } + + @Override + public Boolean checkFileExist(String workspaceId, String fileMd5) { + return RedisOpsUtils.checkExist(RedisConst.FILE_UPLOADING_PREFIX + workspaceId + fileMd5) || + mapper.selectCount(new LambdaQueryWrapper() + .eq(DeviceFirmwareEntity::getWorkspaceId, workspaceId) + .eq(DeviceFirmwareEntity::getFileMd5, fileMd5)) + > 0; + } + + @Override + public PaginationData getAllFirmwarePagination(String workspaceId, DeviceFirmwareQueryParam param) { + Page page = mapper.selectPage(new Page<>(param.getPage(), param.getPageSize()), + new LambdaQueryWrapper() + .eq(DeviceFirmwareEntity::getWorkspaceId, workspaceId) + .eq(Objects.nonNull(param.getStatus()), DeviceFirmwareEntity::getStatus, param.getStatus()) + .like(StringUtils.hasText(param.getProductVersion()), DeviceFirmwareEntity::getFirmwareVersion, param.getProductVersion()) + .orderByDesc(DeviceFirmwareEntity::getReleaseDate), param.getDeviceName()); + + List data = page.getRecords().stream().map(this::entity2Dto).collect(Collectors.toList()); + return new PaginationData(data, new Pagination(page.getCurrent(), page.getSize(), page.getTotal())); + } + + + @Override + public void importFirmwareFile(String workspaceId, String creator, DeviceFirmwareUploadParam param, MultipartFile file) { + String key = RedisConst.FILE_UPLOADING_PREFIX + workspaceId; + String existKey = key + file.getOriginalFilename(); + if (RedisOpsUtils.getExpire(existKey) > 0) { + throw new RuntimeException("请稍后再试。"); + } + RedisOpsUtils.setWithExpire(existKey, true, RedisConst.DEVICE_ALIVE_SECOND); + try (InputStream is = file.getInputStream()) { + long size = is.available(); + String md5 = DigestUtils.md5DigestAsHex(is); + key += md5; + boolean exist = checkFileExist(workspaceId, md5); + if (exist) { + throw new RuntimeException("该文件已存在。"); + } + RedisOpsUtils.set(key, System.currentTimeMillis()); + Optional firmwareOpt = verifyFirmwareFile(file); + if (firmwareOpt.isEmpty()) { + throw new RuntimeException("文件格式不正确。"); + } + + String firmwareId = UUID.randomUUID().toString(); + String objectKey = OssConfiguration.objectDirPrefix + File.separator + firmwareId + FirmwareFileProperties.FIRMWARE_FILE_SUFFIX; + + ossServiceContext.putObject(OssConfiguration.bucket, objectKey, file.getInputStream()); + log.info("上传成功。 {}", file.getOriginalFilename()); + DeviceFirmwareDTO firmware = DeviceFirmwareDTO.builder() + .releaseNote(param.getReleaseNote()) + .firmwareStatus(param.getStatus()) + .fileMd5(md5) + .objectKey(objectKey) + .fileName(file.getOriginalFilename()) + .workspaceId(workspaceId) + .username(creator) + .fileSize(size) + .productVersion(firmwareOpt.get().getProductVersion()) + .releasedTime(firmwareOpt.get().getReleasedTime()) + .firmwareId(firmwareId) + .build(); + + saveFirmwareInfo(firmware, param.getDeviceName()); + } catch (IOException e) { + e.printStackTrace(); + } finally { + RedisOpsUtils.del(key); + } + } + + + @Override + public void saveFirmwareInfo(DeviceFirmwareDTO firmware, List deviceNames) { + DeviceFirmwareEntity entity = dto2Entity(firmware); + mapper.insert(entity); + firmwareModelService.saveFirmwareDeviceName( + FirmwareModelDTO.builder().firmwareId(entity.getFirmwareId()).deviceNames(deviceNames).build()); + } + + @Override + public void updateFirmwareInfo(DeviceFirmwareDTO firmware) { + mapper.update(dto2Entity(firmware), + new LambdaUpdateWrapper() + .eq(DeviceFirmwareEntity::getFirmwareId, firmware.getFirmwareId())); + } + + /** + * Parse firmware file information. + * @param file + * @return + */ + private Optional verifyFirmwareFile(MultipartFile file) { + try (ZipInputStream unzipFile = new ZipInputStream(file.getInputStream(), StandardCharsets.UTF_8)) { + ZipEntry nextEntry = unzipFile.getNextEntry(); + while (Objects.nonNull(nextEntry)) { + String configName = nextEntry.getName(); + if (!configName.contains(File.separator) && configName.endsWith(FirmwareFileProperties.FIRMWARE_CONFIG_FILE_SUFFIX + FirmwareFileProperties.FIRMWARE_SIG_FILE_SUFFIX)) { + String[] filenameArr = configName.split(FirmwareFileProperties.FIRMWARE_FILE_DELIMITER); + String date = filenameArr[FirmwareFileProperties.FILENAME_RELEASE_DATE_INDEX]; + int index = date.indexOf("."); + if (index != -1) { + date = date.substring(0, index); + } + return Optional.of(DeviceFirmwareDTO.builder() + .releasedTime(LocalDate.parse( + date, + DateTimeFormatter.ofPattern(FirmwareFileProperties.FILENAME_RELEASE_DATE_FORMAT))) + // delete the string v. + .productVersion(filenameArr[FirmwareFileProperties.FILENAME_VERSION_INDEX].substring(1)) + .build()); + } + nextEntry = unzipFile.getNextEntry(); + } + + } catch (IOException e) { + e.printStackTrace(); + } + return Optional.empty(); + } + + private DeviceFirmwareEntity dto2Entity(DeviceFirmwareDTO dto) { + if (dto == null) { + return null; + } + return DeviceFirmwareEntity.builder() + .fileName(dto.getFileName()) + .fileMd5(dto.getFileMd5()) + .fileSize(dto.getFileSize()) + .firmwareId(dto.getFirmwareId()) + .firmwareVersion(dto.getProductVersion()) + .objectKey(dto.getObjectKey()) + .releaseDate(Objects.nonNull(dto.getReleasedTime()) ? + dto.getReleasedTime().atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli() : null) + .releaseNote(dto.getReleaseNote()) + .status(dto.getFirmwareStatus()) + .workspaceId(dto.getWorkspaceId()) + .username(dto.getUsername()) + .build(); + } + + private DeviceFirmwareNoteDTO entity2NoteDto (DeviceFirmwareEntity entity) { + if (entity == null) { + return null; + } + return DeviceFirmwareNoteDTO.builder() + .deviceName(entity.getDeviceName()) + .productVersion(entity.getFirmwareVersion()) + .releasedTime(LocalDate.ofInstant(Instant.ofEpochMilli(entity.getReleaseDate()), ZoneId.systemDefault())) + .releaseNote(entity.getReleaseNote()) + .build(); + } + + private DeviceFirmwareDTO entity2Dto (DeviceFirmwareEntity entity) { + if (entity == null) { + return null; + } + return DeviceFirmwareDTO.builder() + .deviceName(Arrays.asList(entity.getDeviceName().split(","))) + .fileMd5(entity.getFileMd5()) + .fileSize(entity.getFileSize()) + .objectKey(entity.getObjectKey()) + .firmwareId(entity.getFirmwareId()) + .fileName(entity.getFileName()) + .productVersion(entity.getFirmwareVersion()) + .releasedTime(LocalDate.ofInstant(Instant.ofEpochMilli(entity.getReleaseDate()), ZoneId.systemDefault())) + .releaseNote(entity.getReleaseNote()) + .firmwareStatus(entity.getStatus()) + .workspaceId(entity.getWorkspaceId()) + .username(entity.getUsername()) + .build(); + } + + private OtaCreateDevice dto2OtaCreateDto(DeviceFirmwareDTO dto) { + if (dto == null) { + return null; + } + return new OtaCreateDevice() + .setFileSize(dto.getFileSize()) + .setFileUrl(ossServiceContext.getObjectUrl(OssConfiguration.bucket, dto.getObjectKey()).toString()) + .setFileName(dto.getFileName()) + .setMd5(dto.getFileMd5()) + .setProductVersion(dto.getProductVersion()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceHmsServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceHmsServiceImpl.java new file mode 100644 index 0000000..3f3f169 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceHmsServiceImpl.java @@ -0,0 +1,293 @@ +package com.dji.sample.manage.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.dao.IDeviceHmsMapper; +import com.dji.sample.manage.model.common.HmsJsonUtil; +import com.dji.sample.manage.model.common.HmsMessage; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.dto.DeviceHmsDTO; +import com.dji.sample.manage.model.dto.TelemetryDTO; +import com.dji.sample.manage.model.entity.DeviceHmsEntity; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.model.param.DeviceHmsQueryParam; +import com.dji.sample.manage.service.IDeviceHmsService; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.hms.*; +import com.dji.sdk.cloudapi.hms.api.AbstractHmsService; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.1 + * @date 2022/7/6 + */ +@Service +@Transactional +@Slf4j +public class DeviceHmsServiceImpl extends AbstractHmsService implements IDeviceHmsService { + + @Autowired + private IDeviceHmsMapper mapper; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private IWebSocketMessageService sendMessageService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + private static final Pattern PATTERN_KEY = Pattern.compile( + "(" + + Arrays.stream(HmsFormatKeyEnum.values()) + .map(HmsFormatKeyEnum::getKey) + .collect(Collectors.joining("|")) + + ")"); + + @Override + public void hms(TopicEventsRequest response, MessageHeaders headers) { + String sn = response.getFrom(); + DeviceHmsEntity entity = DeviceHmsEntity.builder() + .bid(response.getBid()) + .tid(response.getTid()) + .createTime(response.getTimestamp()) + .updateTime(0L) + .sn(sn) + .build(); + // Query all unread hms messages of the device in redis. + Set hmsMap = deviceRedisService.getAllHmsKeys(sn); + + List unReadList = new ArrayList<>(); + response.getData().getList() + .forEach(hmsReceiver -> { + final DeviceHmsEntity hms = entity.clone(); + this.fillEntity(hms, hmsReceiver); + // The same unread hms are no longer incremented. + if (hmsMap.contains(hms.getHmsKey())) { + return; + } + this.fillMessage(hms, hmsReceiver.getArgs()); + unReadList.add(entity2Dto(hms)); + mapper.insert(hms); + }); + + if (unReadList.isEmpty()) { + return; + } + deviceRedisService.addEndHmsKeys(sn, unReadList.stream().map(DeviceHmsDTO::getKey).toArray(String[]::new)); + // push to the web + Optional deviceOpt = deviceRedisService.getDeviceOnline(sn); + if (deviceOpt.isEmpty()) { + return; + } + sendMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.DEVICE_HMS.getCode(), TelemetryDTO.>builder().sn(sn).host(unReadList).build()); + } + + @Override + public PaginationData getDeviceHmsByParam(DeviceHmsQueryParam param) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .and(wrapper -> param.getDeviceSn().forEach(sn -> wrapper.eq(DeviceHmsEntity::getSn, sn).or())) + .between(param.getBeginTime() != null && param.getEndTime() != null, + DeviceHmsEntity::getCreateTime, param.getBeginTime(), param.getEndTime()) + .eq(param.getUpdateTime() != null, DeviceHmsEntity::getUpdateTime, param.getUpdateTime()) + .eq(param.getLevel() != null, DeviceHmsEntity::getLevel, param.getLevel()) + .like(StringUtils.hasText(param.getMessage()) && + HmsMessageLanguageEnum.ZH.getLanguage().equals(param.getLanguage()), + DeviceHmsEntity::getMessageZh, param.getMessage()) + .like(StringUtils.hasText(param.getMessage()) && + HmsMessageLanguageEnum.EN.getLanguage().equals(param.getLanguage()), + DeviceHmsEntity::getMessageEn, param.getMessage()) + .orderByDesc(DeviceHmsEntity::getCreateTime); + if (param.getPage() == null || param.getPageSize() == null) { + param.setPage(1L); + param.setPageSize(Long.valueOf(mapper.selectCount(queryWrapper))); + } + + Page pagination = mapper.selectPage(new Page<>(param.getPage(), param.getPageSize()), queryWrapper); + + List deviceHmsList = pagination.getRecords().stream().map(this::entity2Dto).collect(Collectors.toList()); + + return new PaginationData(deviceHmsList, new Pagination(pagination.getCurrent(), pagination.getSize(), pagination.getTotal())); + } + + @Override + public void updateUnreadHms(String deviceSn) { + mapper.update(DeviceHmsEntity.builder().updateTime(System.currentTimeMillis()).build(), + new LambdaUpdateWrapper() + .eq(DeviceHmsEntity::getSn, deviceSn) + .eq(DeviceHmsEntity::getUpdateTime, 0L)); + // Delete unread messages cached in redis. + deviceRedisService.delHmsKeysBySn(deviceSn); + } + + private DeviceHmsDTO entity2Dto(DeviceHmsEntity entity) { + if (entity == null) { + return null; + } + return DeviceHmsDTO.builder() + .bid(entity.getBid()) + .tid(entity.getTid()) + .createTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getCreateTime()), ZoneId.systemDefault())) + .updateTime(entity.getUpdateTime().intValue() == 0 ? + null : LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getUpdateTime()), ZoneId.systemDefault())) + .sn(entity.getSn()) + .hmsId(entity.getHmsId()) + .key(entity.getHmsKey()) + .level(entity.getLevel()) + .module(entity.getModule()) + .messageEn(entity.getMessageEn()) + .messageZh(entity.getMessageZh()) + .build(); + } + + /** + * Populate the received data into the entity. Please refer to the documentation for splicing rules. + * @param dto + * @param receiver + */ + private void fillEntity(@NotNull DeviceHmsEntity dto, @NotNull DeviceHms receiver) { + dto.setLevel(receiver.getLevel().getLevel()); + dto.setModule(receiver.getModule().getModule()); + dto.setHmsId(UUID.randomUUID().toString()); + DeviceDomainEnum domain = receiver.getDeviceType().getDomain(); + if (DeviceDomainEnum.DOCK == domain) { + dto.setHmsKey(HmsFaqIdEnum.DOCK_TIP.getText() + receiver.getCode()); + return; + } + StringBuilder key = new StringBuilder(HmsFaqIdEnum.FPV_TIP.getText()).append(receiver.getCode()); + + if (receiver.getInTheSky()) { + key.append(HmsInTheSkyEnum.IN_THE_SKY.getText()); + } + dto.setHmsKey(key.toString()); + } + + /** + * Replace wildcards in messages according to the relevant rules. + * Please refer to the documentation for splicing rules. + * @param dto + * @param args + */ + private void fillMessage(DeviceHmsEntity dto, DeviceHmsArgs args) { + HmsMessage hmsMessage = HmsJsonUtil.get(dto.getHmsKey()); + String zh = StringUtils.hasText(hmsMessage.getZh()) ? hmsMessage.getZh() : String.format("未知错误(%s)", dto.getHmsKey()); + String en = StringUtils.hasText(hmsMessage.getEn()) ? hmsMessage.getEn() : String.format("Unknown(%s)", dto.getHmsKey());// + + dto.setMessageZh(format(Locale.CHINESE.getLanguage(), zh, args)); + dto.setMessageEn(format(Locale.ENGLISH.getLanguage(), en, args)); + } + + /** + * Set the matching parameters for key. + * @param l language: zh or en + * @param hmsArgs + * @return + */ + private Map fillKeyArgs(String l, DeviceHmsArgs hmsArgs) { + Map args = new HashMap<>(); + args.put(HmsFormatKeyEnum.ALARM_ID.getKey(), Objects.nonNull(hmsArgs.getAlarmId()) ? Long.toHexString(hmsArgs.getAlarmId()) : null); + args.put(HmsFormatKeyEnum.COMPONENT_INDEX.getKey(), + Objects.nonNull(hmsArgs.getComponentIndex()) ? String.valueOf(hmsArgs.getComponentIndex() + 1) : null); + if (Objects.nonNull(hmsArgs.getSensorIndex())) { + args.put(HmsFormatKeyEnum.INDEX.getKey(), String.valueOf(hmsArgs.getSensorIndex() + 1)); + + HmsBatteryIndexEnum hmsBatteryIndexEnum = Optional.ofNullable(hmsArgs.getSensorIndex()) + .filter(arg -> arg <= 1).map(HmsBatteryIndexEnum::find).orElse(null); + HmsDockCoverIndexEnum hmsDockCoverIndexEnum = Optional.ofNullable(hmsArgs.getSensorIndex()) + .filter(arg -> arg <= 1).map(HmsDockCoverIndexEnum::find).orElse(null); + HmsChargingRodIndexEnum hmsChargingRodIndexEnum = Optional.ofNullable(hmsArgs.getSensorIndex()) + .filter(arg -> arg <= 3).map(HmsChargingRodIndexEnum::find).orElse(null); + + switch (l) { + case "zh": + args.put(HmsFormatKeyEnum.BATTERY_INDEX.getKey(), Optional.ofNullable(hmsBatteryIndexEnum) + .map(HmsBatteryIndexEnum::getZh).orElse(null)); + args.put(HmsFormatKeyEnum.DOCK_COVER_INDEX.getKey(), Optional.ofNullable(hmsDockCoverIndexEnum) + .map(HmsDockCoverIndexEnum::getZh).orElse(null)); + args.put(HmsFormatKeyEnum.CHARGING_ROD_INDEX.getKey(), Optional.ofNullable(hmsChargingRodIndexEnum) + .map(HmsChargingRodIndexEnum::getZh).orElse(null)); + break; + case "en": + args.put(HmsFormatKeyEnum.BATTERY_INDEX.getKey(), Optional.ofNullable(hmsBatteryIndexEnum) + .map(HmsBatteryIndexEnum::getEn).orElse(null)); + args.put(HmsFormatKeyEnum.DOCK_COVER_INDEX.getKey(), Optional.ofNullable(hmsDockCoverIndexEnum) + .map(HmsDockCoverIndexEnum::getEn).orElse(null)); + args.put(HmsFormatKeyEnum.CHARGING_ROD_INDEX.getKey(), Optional.ofNullable(hmsChargingRodIndexEnum) + .map(HmsChargingRodIndexEnum::getEn).orElse(null)); + break; + default: + break; + } + + } + return args; + } + + /** + * Returns a formatted string using the specified locale, format string, and arguments. + * @param l language: zh or en + * @param format + * @param hmsArgs + * @return + */ + private String format(String l, String format, DeviceHmsArgs hmsArgs) { + Map args = fillKeyArgs(l, hmsArgs); + List list = parse(format); + StringBuilder sb = new StringBuilder(); + for (String word : list) { + if (!StringUtils.hasText(word)) { + continue; + } + sb.append(args.getOrDefault(word, word)); + } + return sb.toString(); + } + + /** + * Finds format specifiers in the format string. + * @param s + * @return + */ + private List parse(String s) { + List list = new ArrayList<>(); + Matcher matcher = PATTERN_KEY.matcher(s); + for (int i = 0; i < s.length(); ) { + if (matcher.find(i)) { + if (matcher.start() != i) { + list.add(s.substring(i, matcher.start())); + } + list.add(matcher.group()); + i = matcher.end(); + } else { + list.add(s.substring(i)); + break; + } + } + return list; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceLogsServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceLogsServiceImpl.java new file mode 100644 index 0000000..071c9ca --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceLogsServiceImpl.java @@ -0,0 +1,314 @@ +package com.dji.sample.manage.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.dao.IDeviceLogsMapper; +import com.dji.sample.manage.model.dto.*; +import com.dji.sample.manage.model.entity.DeviceLogsEntity; +import com.dji.sample.manage.model.enums.DeviceLogsStatusEnum; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.model.param.DeviceLogsCreateParam; +import com.dji.sample.manage.model.param.DeviceLogsQueryParam; +import com.dji.sample.manage.service.IDeviceLogsService; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.manage.service.ILogsFileService; +import com.dji.sample.manage.service.ITopologyService; +import com.dji.sample.storage.service.IStorageService; +import com.dji.sdk.cloudapi.log.*; +import com.dji.sdk.cloudapi.log.api.AbstractLogService; +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.net.URL; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@Service +@Transactional +@Slf4j +public class DeviceLogsServiceImpl extends AbstractLogService implements IDeviceLogsService { + + private static final String LOGS_FILE_SUFFIX = ".tar"; + + @Autowired + private IDeviceLogsMapper mapper; + + @Autowired + private ITopologyService topologyService; + + @Autowired + private ILogsFileService logsFileService; + + @Autowired + private IStorageService storageService; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private AbstractLogService abstractLogService; + + @Override + public PaginationData getUploadedLogs(String deviceSn, DeviceLogsQueryParam param) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(DeviceLogsEntity::getDeviceSn, deviceSn) + .between(Objects.nonNull(param.getBeginTime()) && Objects.nonNull(param.getEndTime()), + DeviceLogsEntity::getCreateTime, param.getBeginTime(), param.getEndTime()) + .eq(Objects.nonNull(param.getStatus()), DeviceLogsEntity::getStatus, param.getStatus()) + .like(StringUtils.hasText(param.getLogsInformation()), + DeviceLogsEntity::getLogsInfo, param.getLogsInformation()) + .orderByDesc(DeviceLogsEntity::getCreateTime); + + Page pagination = mapper.selectPage(new Page<>(param.getPage(), param.getPageSize()), queryWrapper); + + List deviceLogsList = pagination.getRecords().stream().map(this::entity2Dto).collect(Collectors.toList()); + + return new PaginationData(deviceLogsList, new Pagination(pagination.getCurrent(), pagination.getSize(), pagination.getTotal())); + } + + @Override + public HttpResultResponse getRealTimeLogs(String deviceSn, List domainList) { + boolean exist = deviceRedisService.checkDeviceOnline(deviceSn); + if (!exist) { + return HttpResultResponse.error("设备处于脱机状态。"); + } + + TopicServicesResponse> response = abstractLogService + .fileuploadList(SDKManager.getDeviceSDK(deviceSn), new FileUploadListRequest().setModuleList(domainList)); + for (FileUploadListFile file : response.getData().getOutput().getFiles()) { + if (file.getDeviceSn().isBlank()) { + file.setDeviceSn(deviceSn); + } + } + return HttpResultResponse.success(response.getData().getOutput()); + } + + @Override + public String insertDeviceLogs(String bid, String username, String deviceSn, DeviceLogsCreateParam param) { + DeviceLogsEntity entity = DeviceLogsEntity.builder() + .deviceSn(deviceSn) + .username(username) + .happenTime(param.getHappenTime()) + .logsInfo(Objects.requireNonNullElse(param.getLogsInformation(), "")) + .logsId(bid) + .status(DeviceLogsStatusEnum.UPLOADING.getVal()) + .build(); + boolean insert = mapper.insert(entity) > 0; + if (!insert) { + return ""; + } + for (FileUploadStartFile file : param.getFiles()) { + insert = logsFileService.insertFile(file, entity.getLogsId()); + if (!insert) { + return ""; + } + } + + return bid; + } + + + @Override + public HttpResultResponse pushFileUpload(String username, String deviceSn, DeviceLogsCreateParam param) { + StsCredentialsResponse stsCredentials = storageService.getSTSCredentials(); + stsCredentials.getCredentials().setExpire(System.currentTimeMillis() + (stsCredentials.getCredentials().getExpire() - 60) * 1000); + LogsUploadCredentialsDTO credentialsDTO = new LogsUploadCredentialsDTO(stsCredentials); + // Set the storage name of the file. + List files = param.getFiles(); + files.forEach(file -> file.setObjectKey(credentialsDTO.getObjectKeyPrefix() + "/" + UUID.randomUUID().toString() + LOGS_FILE_SUFFIX)); + + credentialsDTO.setParams(new FileUploadStartParam().setFiles(files)); + + TopicServicesResponse response = abstractLogService.fileuploadStart( + SDKManager.getDeviceSDK(deviceSn), new FileUploadStartRequest() + .setCredentials(stsCredentials.getCredentials()) + .setBucket(stsCredentials.getBucket()) + .setEndpoint(stsCredentials.getEndpoint()) + .setFileStoreDir(stsCredentials.getObjectKeyPrefix()) + .setProvider(stsCredentials.getProvider()) + .setRegion(stsCredentials.getRegion()) + .setParams(new FileUploadStartParam().setFiles(files))); + + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); + } + + String id = this.insertDeviceLogs(response.getBid(), username, deviceSn, param); + + // Save the status of the log upload. + RedisOpsUtils.hashSet(RedisConst.LOGS_FILE_PREFIX + deviceSn, id, LogsOutputProgressDTO.builder().logsId(id).build()); + return HttpResultResponse.success(); + + } + + @Override + public HttpResultResponse pushUpdateFile(String deviceSn, FileUploadUpdateRequest param) { + TopicServicesResponse response = abstractLogService.fileuploadUpdate(SDKManager.getDeviceSDK(deviceSn), param); + + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); + } + return HttpResultResponse.success(); + } + + @Override + public void deleteLogs(String deviceSn, String logsId) { + mapper.delete(new LambdaUpdateWrapper() + .eq(DeviceLogsEntity::getLogsId, logsId).eq(DeviceLogsEntity::getDeviceSn, deviceSn)); + logsFileService.deleteFileByLogsId(logsId); + } + + @Override + public TopicEventsResponse fileuploadProgress(TopicEventsRequest> request, MessageHeaders headers) { + EventsReceiver webSocketData = new EventsReceiver<>(); + webSocketData.setBid(request.getBid()); + webSocketData.setSn(request.getGateway()); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + if (deviceOpt.isEmpty()) { + return null; + } + + DeviceDTO device = deviceOpt.get(); + String key = RedisConst.LOGS_FILE_PREFIX + request.getGateway(); + + try { + FileUploadProgress output = request.getData().getOutput(); + log.info("记录上传进度: {}", output.toString()); + + LogsOutputProgressDTO progress; + boolean exist = RedisOpsUtils.checkExist(key); + if (!exist && !output.getStatus().isEnd()) { + progress = LogsOutputProgressDTO.builder().logsId(request.getBid()).build(); + RedisOpsUtils.hashSet(key, request.getBid(), progress); + } else if (exist) { + progress = (LogsOutputProgressDTO) RedisOpsUtils.hashGet(key, request.getBid()); + } else { + progress = LogsOutputProgressDTO.builder().build(); + } + progress.setStatus(output.getStatus()); + + // If the logs file is empty, delete the cache of this task. + List fileReceivers = output.getExt().getFiles(); + if (CollectionUtils.isEmpty(fileReceivers)) { + RedisOpsUtils.del(key); + } + + // refresh cache. + List fileProgressList = new ArrayList<>(); + fileReceivers.forEach(file -> { + LogFileProgress logsProgress = file.getProgress(); + if (!StringUtils.hasText(file.getDeviceSn())) { + if (LogModuleEnum.DOCK == file.getModule()) { + file.setDeviceSn(request.getGateway()); + } else if (LogModuleEnum.DRONE == file.getModule()) { + file.setDeviceSn(device.getChildDeviceSn()); + } + } + + fileProgressList.add(LogsProgressDTO.builder() + .deviceSn(file.getDeviceSn()) + .deviceModelDomain(file.getModule().getDomain()) + .result(logsProgress.getResult()) + .status(logsProgress.getStatus().getStatus()) + .uploadRate(logsProgress.getUploadRate()) + .progress(((logsProgress.getCurrentStep() - 1) * 100 + logsProgress.getProgress()) / logsProgress.getTotalStep()) + .build()); + }); + progress.setFiles(fileProgressList); + webSocketData.setOutput(progress); + RedisOpsUtils.hashSet(RedisConst.LOGS_FILE_PREFIX + request.getGateway(), request.getBid(), progress); + // Delete the cache at the end of the task. + if (output.getStatus().isEnd()) { + RedisOpsUtils.del(key); + updateLogsStatus(request.getBid(), DeviceLogsStatusEnum.find(output.getStatus()).getVal()); + + fileReceivers.forEach(file -> logsFileService.updateFile(request.getBid(), file)); + } + } catch (NullPointerException e) { + this.updateLogsStatus(request.getBid(), DeviceLogsStatusEnum.FAILED.getVal()); + RedisOpsUtils.del(key); + } + + webSocketMessageService.sendBatch(device.getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.FILE_UPLOAD_PROGRESS.getCode(), webSocketData); + + return new TopicEventsResponse().setData(MqttReply.success()); + } + + @Override + public void updateLogsStatus(String logsId, Integer value) { + + mapper.update(DeviceLogsEntity.builder().status(value).build(), + new LambdaUpdateWrapper().eq(DeviceLogsEntity::getLogsId, logsId)); + if (DeviceLogsStatusEnum.DONE.getVal() == value) { + logsFileService.updateFileUploadStatus(logsId, true); + } + } + + @Override + public URL getLogsFileUrl(String logsId, String fileId) { + return logsFileService.getLogsFileUrl(logsId, fileId); + } + + private DeviceLogsDTO entity2Dto(DeviceLogsEntity entity) { + if (Objects.isNull(entity)) { + return null; + } + String key = RedisConst.LOGS_FILE_PREFIX + entity.getDeviceSn(); + LogsOutputProgressDTO progress = null; + if (RedisOpsUtils.hashCheck(key, entity.getLogsId())) { + progress = (LogsOutputProgressDTO) RedisOpsUtils.hashGet(key, entity.getLogsId()); + } + + return DeviceLogsDTO.builder() + .logsId(entity.getLogsId()) + .createTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getCreateTime()), ZoneId.systemDefault())) + .happenTime(Objects.isNull(entity.getHappenTime()) ? + null : LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getHappenTime()), ZoneId.systemDefault())) + .status(entity.getStatus()) + .logsInformation(entity.getLogsInfo()) + .userName(entity.getUsername()) + .deviceLogs(LogsFileUploadListDTO.builder().files(logsFileService.getLogsFileByLogsId(entity.getLogsId())).build()) + .logsProgress(Objects.requireNonNullElse(progress, new LogsOutputProgressDTO()).getFiles()) + .deviceTopo(topologyService.getDeviceTopologyByGatewaySn(entity.getDeviceSn()).orElse(null)) + .build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DevicePayloadServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DevicePayloadServiceImpl.java new file mode 100644 index 0000000..d86e042 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DevicePayloadServiceImpl.java @@ -0,0 +1,254 @@ +package com.dji.sample.manage.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.control.model.enums.DroneAuthorityEnum; +import com.dji.sample.manage.dao.IDevicePayloadMapper; +import com.dji.sample.manage.model.dto.*; +import com.dji.sample.manage.model.entity.DevicePayloadEntity; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.service.ICapacityCameraService; +import com.dji.sample.manage.service.IDeviceDictionaryService; +import com.dji.sample.manage.service.IDevicePayloadService; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.device.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/19 + */ +@Slf4j +@Service +@Transactional +public class DevicePayloadServiceImpl implements IDevicePayloadService { + + @Autowired + private IDevicePayloadMapper mapper; + + @Autowired + private IDeviceDictionaryService dictionaryService; + + @Autowired + private ICapacityCameraService capacityCameraService; + + @Autowired + private IWebSocketMessageService sendMessageService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Override + public Integer checkPayloadExist(String payloadSn) { + DevicePayloadEntity devicePayload = mapper.selectOne( + new LambdaQueryWrapper() + .eq(DevicePayloadEntity::getPayloadSn, payloadSn)); + return devicePayload != null ? devicePayload.getId() : -1; + } + + private Integer saveOnePayloadEntity(DevicePayloadEntity entity) { + int id = this.checkPayloadExist(entity.getPayloadSn()); + // If it already exists, update the data directly. + if (id > 0) { + entity.setId(id); + // For the payload of the drone itself, there is no firmware version. + entity.setFirmwareVersion(null); + return mapper.updateById(entity) > 0 ? entity.getId() : 0; + } + return mapper.insert(entity) > 0 ? entity.getId() : 0; + } + + @Override + public Boolean savePayloadDTOs(DeviceDTO device, List payloadReceiverList) { + Map controlMap = CollectionUtils.isEmpty(device.getPayloadsList()) ? + Collections.emptyMap() : device.getPayloadsList().stream() + .collect(Collectors.toMap(DevicePayloadDTO::getPayloadSn, DevicePayloadDTO::getControlSource)); + + for (DevicePayloadReceiver payloadReceiver : payloadReceiverList) { + payloadReceiver.setDeviceSn(device.getDeviceSn()); + int payloadId = this.saveOnePayloadDTO(payloadReceiver); + if (payloadId <= 0) { + log.error("有效负载数据保存失败。"); + return false; + } + if (controlMap.get(payloadReceiver.getSn()) != payloadReceiver.getControlSource()) { + sendMessageService.sendBatch(device.getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.CONTROL_SOURCE_CHANGE.getCode(), + DeviceAuthorityDTO.builder() + .controlSource(payloadReceiver.getControlSource()) + .sn(payloadReceiver.getSn()) + .type(DroneAuthorityEnum.PAYLOAD) + .build()); + } + } + + List payloads = this.getDevicePayloadEntitiesByDeviceSn(device.getDeviceSn()); + device.setPayloadsList(payloads); + deviceRedisService.setDeviceOnline(device); + return true; + } + + @Override + public Integer saveOnePayloadDTO(DevicePayloadReceiver payloadReceiver) { + return this.saveOnePayloadEntity(receiverConvertToEntity(payloadReceiver)); + } + + @Override + public List getDevicePayloadEntitiesByDeviceSn(String deviceSn) { + return mapper.selectList( + new LambdaQueryWrapper() + .eq(DevicePayloadEntity::getDeviceSn, deviceSn)) + .stream() + .map(this::payloadEntityConvertToDTO) + .collect(Collectors.toList()); + } + + @Override + public void deletePayloadsByDeviceSn(List deviceSns) { + deviceSns.forEach(deviceSn -> { + mapper.delete( + new LambdaQueryWrapper() + .eq(DevicePayloadEntity::getDeviceSn, deviceSn)); + capacityCameraService.deleteCapacityCameraByDeviceSn(deviceSn); + }); + } + + @Override + public Boolean updateFirmwareVersion(String droneSn, PayloadFirmwareVersion receiver) { + return mapper.update(DevicePayloadEntity.builder() + .firmwareVersion(receiver.getFirmwareVersion()).build(), + new LambdaUpdateWrapper() + .eq(DevicePayloadEntity::getDeviceSn, droneSn) + .eq(DevicePayloadEntity::getPayloadSn, droneSn + "-" + receiver.getPosition().getPosition()) + ) > 0; + } + + /** + * Handle payload data for devices. + * @param drone + * @param payloads + */ + public void updatePayloadControl(DeviceDTO drone, List payloads) { + boolean match = payloads.stream().peek(p -> p.setSn(Objects.requireNonNullElse(p.getSn(), + p.getDeviceSn() + "-" + p.getPayloadIndex().getPosition().getPosition()))) + .anyMatch(p -> ControlSourceEnum.UNKNOWN == p.getControlSource()); + if (match) { + return; + } + + if (payloads.isEmpty()) { + drone.setPayloadsList(null); + this.deletePayloadsByDeviceSn(List.of(drone.getDeviceSn())); + deviceRedisService.setDeviceOnline(drone); + return; + } + + // Filter unsaved payload information. + Set payloadSns = this.getDevicePayloadEntitiesByDeviceSn(drone.getDeviceSn()) + .stream().map(DevicePayloadDTO::getPayloadSn).collect(Collectors.toSet()); + + Set newPayloadSns = payloads.stream().map(DevicePayloadReceiver::getSn).collect(Collectors.toSet()); + payloadSns.removeAll(newPayloadSns); + this.deletePayloadsByPayloadsSn(payloadSns); + + // Save the new payload information. + boolean isSave = this.savePayloadDTOs(drone, payloads); + log.debug("保存有效载荷的结果是 {}.", isSave); + } + + @Override + public void deletePayloadsByPayloadsSn(Collection payloadSns) { + if (CollectionUtils.isEmpty(payloadSns)) { + return; + } + mapper.delete(new LambdaUpdateWrapper() + .or(wrapper -> payloadSns.forEach(sn -> wrapper.eq(DevicePayloadEntity::getPayloadSn, sn)))); + } + + @Override + public Boolean checkAuthorityPayload(String deviceSn, String payloadIndex) { + return deviceRedisService.getDeviceOnline(deviceSn).flatMap(device -> + Optional.of(DeviceDomainEnum.DRONE == device.getDomain() + && !CollectionUtils.isEmpty(device.getPayloadsList()) + && ControlSourceEnum.A == + device.getPayloadsList().stream() + .filter(payload -> payloadIndex.equals(payload.getPayloadIndex().toString())) + .map(DevicePayloadDTO::getControlSource).findAny() + .orElse(ControlSourceEnum.B))) + .orElse(true); + } + + /** + * Convert database entity objects into payload data transfer object. + * @param entity + * @return + */ + private DevicePayloadDTO payloadEntityConvertToDTO(DevicePayloadEntity entity) { + DevicePayloadDTO.DevicePayloadDTOBuilder builder = DevicePayloadDTO.builder(); + if (entity != null) { + builder.payloadSn(entity.getPayloadSn()) + .payloadName(entity.getPayloadName()) + .payloadDesc(entity.getPayloadDesc()) + .index(entity.getPayloadIndex()) + .payloadIndex(new PayloadIndex() + .setType(DeviceTypeEnum.find(entity.getPayloadType())) + .setSubType(DeviceSubTypeEnum.find(entity.getSubType())) + .setPosition(PayloadPositionEnum.find(entity.getPayloadIndex()))) + .controlSource(ControlSourceEnum.find(entity.getControlSource())); + } + return builder.build(); + } + + /** + * Convert the received payload object into a database entity object. + * @param dto payload + * @return + */ + private DevicePayloadEntity receiverConvertToEntity(DevicePayloadReceiver dto) { + if (dto == null) { + return new DevicePayloadEntity(); + } + DevicePayloadEntity.DevicePayloadEntityBuilder builder = DevicePayloadEntity.builder(); + + // The cameraIndex consists of type and subType and the index of the payload hanging on the drone. + // type-subType-index + Optional dictionaryOpt = dictionaryService.getOneDictionaryInfoByTypeSubType( + DeviceDomainEnum.PAYLOAD.getDomain(), dto.getPayloadIndex().getType().getType(), + dto.getPayloadIndex().getSubType().getSubType()); + dictionaryOpt.ifPresent(dictionary -> + builder.payloadName(dictionary.getDeviceName()) + .payloadDesc(dictionary.getDeviceDesc())); + + builder.payloadType(dto.getPayloadIndex().getType().getType()) + .subType(dto.getPayloadIndex().getSubType().getSubType()) + .payloadIndex(dto.getPayloadIndex().getPosition().getPosition()) + .controlSource(dto.getControlSource().getControlSource()); + + return builder + .payloadSn(dto.getSn()) + .deviceSn(dto.getDeviceSn()) + .build(); + } + + private DevicePayloadDTO receiver2Dto(DevicePayloadReceiver receiver) { + DevicePayloadDTO.DevicePayloadDTOBuilder builder = DevicePayloadDTO.builder(); + if (receiver == null) { + return builder.build(); + } + return builder.payloadSn(receiver.getSn()) + .payloadIndex(receiver.getPayloadIndex()) + .controlSource(receiver.getControlSource()) + .build(); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceRedisServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceRedisServiceImpl.java new file mode 100644 index 0000000..4d01f56 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceRedisServiceImpl.java @@ -0,0 +1,109 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.service.ICapacityCameraService; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sdk.cloudapi.firmware.OtaProgress; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/21 + */ +@Service +public class DeviceRedisServiceImpl implements IDeviceRedisService { + + @Autowired + private ICapacityCameraService capacityCameraService; + + @Override + public Boolean checkDeviceOnline(String sn) { + String key = RedisConst.DEVICE_ONLINE_PREFIX + sn; + return RedisOpsUtils.checkExist(key) && RedisOpsUtils.getExpire(key) > 0; + } + + @Override + public Optional getDeviceOnline(String sn) { + return Optional.ofNullable((DeviceDTO) RedisOpsUtils.get(RedisConst.DEVICE_ONLINE_PREFIX + sn)); + } + + @Override + public void setDeviceOnline(DeviceDTO device) { + RedisOpsUtils.setWithExpire(RedisConst.DEVICE_ONLINE_PREFIX + device.getDeviceSn(), device, RedisConst.DEVICE_ALIVE_SECOND); + } + + @Override + public Boolean delDeviceOnline(String sn) { + return RedisOpsUtils.del(RedisConst.DEVICE_ONLINE_PREFIX + sn); + } + + @Override + public void setDeviceOsd(String sn, Object data) { + RedisOpsUtils.setWithExpire(RedisConst.OSD_PREFIX + sn, data, RedisConst.DEVICE_ALIVE_SECOND); + } + + @Override + public Optional getDeviceOsd(String sn, Class clazz) { + return Optional.ofNullable(clazz.cast(RedisOpsUtils.get(RedisConst.OSD_PREFIX + sn))); + } + + @Override + public Boolean delDeviceOsd(String sn) { + return RedisOpsUtils.del(RedisConst.OSD_PREFIX + sn); + } + + @Override + public void setFirmwareUpgrading(String sn, EventsReceiver events) { + RedisOpsUtils.setWithExpire(RedisConst.FIRMWARE_UPGRADING_PREFIX + sn, events, RedisConst.DEVICE_ALIVE_SECOND * 20); + } + + @Override + public Optional> getFirmwareUpgradingProgress(String sn) { + return Optional.ofNullable((EventsReceiver) RedisOpsUtils.get(RedisConst.FIRMWARE_UPGRADING_PREFIX + sn)); + } + + @Override + public Boolean delFirmwareUpgrading(String sn) { + return RedisOpsUtils.del(RedisConst.FIRMWARE_UPGRADING_PREFIX + sn); + } + + @Override + public void addEndHmsKeys(String sn, String... keys) { + RedisOpsUtils.listRPush(RedisConst.HMS_PREFIX + sn, keys); + } + + @Override + public Set getAllHmsKeys(String sn) { + return RedisOpsUtils.listGetAll(RedisConst.HMS_PREFIX + sn).stream() + .map(String::valueOf).collect(Collectors.toSet()); + } + + @Override + public Boolean delHmsKeysBySn(String sn) { + return RedisOpsUtils.del(RedisConst.HMS_PREFIX + sn); + } + + @Override + public void gatewayOffline(String gatewaySn) { + delDeviceOnline(gatewaySn); + delHmsKeysBySn(gatewaySn); + capacityCameraService.deleteCapacityCameraByDeviceSn(gatewaySn); + } + + @Override + public void subDeviceOffline(String deviceSn) { + delDeviceOnline(deviceSn); + delDeviceOsd(deviceSn); + delHmsKeysBySn(deviceSn); + capacityCameraService.deleteCapacityCameraByDeviceSn(deviceSn); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceServiceImpl.java new file mode 100644 index 0000000..b4d0ec3 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceServiceImpl.java @@ -0,0 +1,684 @@ +package com.dji.sample.manage.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.control.model.enums.DroneAuthorityEnum; +import com.dji.sample.manage.dao.IDeviceMapper; +import com.dji.sample.manage.model.dto.*; +import com.dji.sample.manage.model.entity.DeviceEntity; +import com.dji.sample.manage.model.enums.DeviceFirmwareStatusEnum; +import com.dji.sample.manage.model.enums.PropertySetFieldEnum; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.model.param.DeviceQueryParam; +import com.dji.sample.manage.model.receiver.BasicDeviceProperty; +import com.dji.sample.manage.service.*; +import com.dji.sdk.cloudapi.device.*; +import com.dji.sdk.cloudapi.firmware.*; +import com.dji.sdk.cloudapi.firmware.api.AbstractFirmwareService; +import com.dji.sdk.cloudapi.property.api.AbstractPropertyService; +import com.dji.sdk.cloudapi.tsa.DeviceIconUrl; +import com.dji.sdk.cloudapi.tsa.TopologyDeviceModel; +import com.dji.sdk.common.*; +import com.dji.sdk.config.version.GatewayManager; +import com.dji.sdk.exception.CloudSDKException; +import com.dji.sdk.mqtt.IMqttTopicService; +import com.dji.sdk.mqtt.MqttGatewayPublish; +import com.dji.sdk.mqtt.events.EventsSubscribe; +import com.dji.sdk.mqtt.osd.OsdSubscribe; +import com.dji.sdk.mqtt.property.PropertySetReplyResultEnum; +import com.dji.sdk.mqtt.property.PropertySetSubscribe; +import com.dji.sdk.mqtt.requests.RequestsSubscribe; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.ServicesSubscribe; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import com.dji.sdk.mqtt.state.StateSubscribe; +import com.dji.sdk.mqtt.status.StatusSubscribe; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * + * @author sean.zhou + * @version 0.1 + * @date 2021/11/10 + */ +@Service +@Slf4j +@Transactional +public class DeviceServiceImpl implements IDeviceService { + + @Autowired + private MqttGatewayPublish messageSender; + + @Autowired + private IDeviceMapper mapper; + + @Autowired + private IDeviceDictionaryService dictionaryService; + + @Autowired + private IMqttTopicService topicService; + + @Autowired + private IWorkspaceService workspaceService; + + @Autowired + private IDevicePayloadService payloadService; + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private IDeviceFirmwareService deviceFirmwareService; + + @Autowired + private ICapacityCameraService capacityCameraService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private StatusSubscribe statusSubscribe; + + @Autowired + private StateSubscribe stateSubscribe; + + @Autowired + private OsdSubscribe osdSubscribe; + + @Autowired + private ServicesSubscribe servicesSubscribe; + + @Autowired + private EventsSubscribe eventsSubscribe; + + @Autowired + private RequestsSubscribe requestsSubscribe; + + @Autowired + private PropertySetSubscribe propertySetSubscribe; + + @Autowired + private AbstractPropertyService abstractPropertyService; + + @Autowired + private AbstractFirmwareService abstractFirmwareService; + + @Override + public void subDeviceOffline(String deviceSn) { + // If no information about this device exists in the cache, the drone is considered to be offline. + Optional deviceOpt = deviceRedisService.getDeviceOnline(deviceSn); + if (deviceOpt.isEmpty()) { + log.debug("无人机已经离线。"); + return; + } + try { + gatewayOnlineSubscribeTopic(SDKManager.getDeviceSDK(String.valueOf(deviceOpt.get().getParentSn()))); + } catch (CloudSDKException e) { + log.debug("网关已脱机", e); + } + deviceRedisService.subDeviceOffline(deviceSn); + // Publish the latest device topology information in the current workspace. + pushDeviceOfflineTopo(deviceOpt.get().getWorkspaceId(), deviceSn); + log.debug("{} 离线。", deviceSn); + } + + @Override + public void gatewayOffline(String gatewaySn) { + // If no information about this device exists in the cache, the drone is considered to be offline. + Optional deviceOpt = deviceRedisService.getDeviceOnline(gatewaySn); + if (deviceOpt.isEmpty()) { + log.debug("网关已脱机。"); + return; + } + + deviceRedisService.subDeviceOffline(deviceOpt.get().getChildDeviceSn()); + deviceRedisService.gatewayOffline(gatewaySn); + offlineUnsubscribeTopic(SDKManager.getDeviceSDK(gatewaySn)); + // Publish the latest device topology information in the current workspace. + pushDeviceOfflineTopo(deviceOpt.get().getWorkspaceId(), gatewaySn); + log.debug("{} 离线。", gatewaySn); + } + + @Override + public void gatewayOnlineSubscribeTopic(GatewayManager gateway) { + statusSubscribe.subscribe(gateway); + stateSubscribe.subscribe(gateway, true); + osdSubscribe.subscribe(gateway, true); + servicesSubscribe.subscribe(gateway); + eventsSubscribe.subscribe(gateway, true); + requestsSubscribe.subscribe(gateway); + propertySetSubscribe.subscribe(gateway); + } + + @Override + public void subDeviceOnlineSubscribeTopic(GatewayManager gateway) { + statusSubscribe.subscribe(gateway); + stateSubscribe.subscribe(gateway, false); + osdSubscribe.subscribe(gateway, false); + servicesSubscribe.subscribe(gateway); + eventsSubscribe.subscribe(gateway, false); + requestsSubscribe.subscribe(gateway); + propertySetSubscribe.subscribe(gateway); + } + + @Override + public void offlineUnsubscribeTopic(GatewayManager gateway) { + statusSubscribe.unsubscribe(gateway); + stateSubscribe.unsubscribe(gateway); + osdSubscribe.unsubscribe(gateway); + servicesSubscribe.unsubscribe(gateway); + eventsSubscribe.unsubscribe(gateway); + requestsSubscribe.unsubscribe(gateway); + propertySetSubscribe.unsubscribe(gateway); + } + + @Override + public List getDevicesByParams(DeviceQueryParam param) { + return mapper.selectList( + new LambdaQueryWrapper() + .eq(StringUtils.hasText(param.getDeviceSn()), + DeviceEntity::getDeviceSn, param.getDeviceSn()) + .eq(param.getDeviceType() != null, + DeviceEntity::getDeviceType, param.getDeviceType()) + .eq(param.getSubType() != null, + DeviceEntity::getSubType, param.getSubType()) + .eq(StringUtils.hasText(param.getChildSn()), + DeviceEntity::getChildSn, param.getChildSn()) + .and(!CollectionUtils.isEmpty(param.getDomains()), wrapper -> { + for (Integer domain : param.getDomains()) { + wrapper.eq(DeviceEntity::getDomain, domain).or(); + } + }) + .eq(StringUtils.hasText(param.getWorkspaceId()), + DeviceEntity::getWorkspaceId, param.getWorkspaceId()) + .eq(param.getBoundStatus() != null, DeviceEntity::getBoundStatus, param.getBoundStatus()) + .orderBy(param.isOrderBy(), + param.isAsc(), DeviceEntity::getId)) + .stream() + .map(this::deviceEntityConvertToDTO) + .collect(Collectors.toList()); + } + + @Override + public List getDevicesTopoForWeb(String workspaceId) { + List devicesList = this.getDevicesByParams( + DeviceQueryParam.builder() + .workspaceId(workspaceId) + .domains(List.of(DeviceDomainEnum.REMOTER_CONTROL.getDomain(), DeviceDomainEnum.DOCK.getDomain())) + .build()); + + devicesList.stream() + .filter(gateway -> DeviceDomainEnum.DOCK == gateway.getDomain() || + deviceRedisService.checkDeviceOnline(gateway.getDeviceSn())) + .forEach(this::spliceDeviceTopo); + + return devicesList; + } + + @Override + public void spliceDeviceTopo(DeviceDTO gateway) { + + gateway.setStatus(deviceRedisService.checkDeviceOnline(gateway.getDeviceSn())); + + // sub device + if (!StringUtils.hasText(gateway.getChildDeviceSn())) { + return; + } + + DeviceDTO subDevice = getDevicesByParams(DeviceQueryParam.builder().deviceSn(gateway.getChildDeviceSn()).build()).get(0); + subDevice.setStatus(deviceRedisService.checkDeviceOnline(subDevice.getDeviceSn())); + gateway.setChildren(subDevice); + + // payloads + subDevice.setPayloadsList(payloadService.getDevicePayloadEntitiesByDeviceSn(gateway.getChildDeviceSn())); + } + + @Override + public Optional getDeviceTopoForPilot(String sn) { + if (!StringUtils.hasText(sn)) { + return Optional.empty(); + } + List topologyDeviceList = this.getDevicesByParams( + DeviceQueryParam.builder() + .deviceSn(sn) + .build()) + .stream() + .map(this::deviceConvertToTopologyDTO) + .collect(Collectors.toList()); + if (topologyDeviceList.isEmpty()) { + return Optional.empty(); + } + return Optional.of(topologyDeviceList.get(0)); + } + + @Override + public TopologyDeviceDTO deviceConvertToTopologyDTO(DeviceDTO device) { + if (device == null) { + return null; + } + return new TopologyDeviceDTO() + .setSn(device.getDeviceSn()) + .setDeviceCallsign(device.getNickname()) + .setDeviceModel(new TopologyDeviceModel() + .setDomain(device.getDomain()) + .setSubType(device.getSubType()) + .setType(device.getType()) + .setDeviceModelKey(DeviceEnum.find(device.getDomain(), device.getType(), device.getSubType()))) + .setIconUrls(device.getIconUrl()) + .setOnlineStatus(deviceRedisService.checkDeviceOnline(device.getDeviceSn())) + .setUserCallsign(device.getNickname()) + .setBoundStatus(device.getBoundStatus()) + .setModel(device.getDeviceName()) + .setUserId(device.getUserId()) + .setDomain(device.getDomain()) + .setGatewaySn(device.getParentSn()); + } + + @Override + public void pushDeviceOfflineTopo(String workspaceId, String deviceSn) { + webSocketMessageService.sendBatch( + workspaceId, null, com.dji.sdk.websocket.BizCodeEnum.DEVICE_OFFLINE.getCode(), + new TopologyDeviceDTO().setSn(deviceSn).setOnlineStatus(false)); + } + + @Override + public void pushDeviceOnlineTopo(String workspaceId, String gatewaySn, String deviceSn) { + webSocketMessageService.sendBatch( + workspaceId, null, com.dji.sdk.websocket.BizCodeEnum.DEVICE_ONLINE.getCode(), + getDeviceTopoForPilot(deviceSn).orElseGet(TopologyDeviceDTO::new).setGatewaySn(gatewaySn)); + } + + @Override + public void pushOsdDataToPilot(String workspaceId, String sn, DeviceOsdHost data) { + webSocketMessageService.sendBatch( + workspaceId, UserTypeEnum.PILOT.getVal(), com.dji.sdk.websocket.BizCodeEnum.DEVICE_OSD.getCode(), + new DeviceOsdWsResponse() + .setSn(sn) + .setHost(data)); + } + + @Override + public void pushOsdDataToWeb(String workspaceId, BizCodeEnum codeEnum, String sn, Object data) { + webSocketMessageService.sendBatch( + workspaceId, UserTypeEnum.WEB.getVal(), codeEnum.getCode(), TelemetryDTO.builder().sn(sn).host(data).build()); + } + + /** + * Save the device information and update the information directly if the device already exists. + * @param device + * @return + */ + public Boolean saveOrUpdateDevice(DeviceDTO device) { + int count = mapper.selectCount( + new LambdaQueryWrapper() + .eq(DeviceEntity::getDeviceSn, device.getDeviceSn())); + return count > 0 ? updateDevice(device) : saveDevice(device) > 0; + } + + /** + * Save the device information. + * @param device + * @return + */ + public Integer saveDevice(DeviceDTO device) { + DeviceEntity entity = deviceDTO2Entity(device); + return mapper.insert(entity) > 0 ? entity.getId() : -1; + } + + /** + * Convert database entity object into device data transfer object. + * @param entity + * @return + */ + private DeviceDTO deviceEntityConvertToDTO(DeviceEntity entity) { + if (entity == null) { + return null; + } + DeviceDTO.DeviceDTOBuilder builder = DeviceDTO.builder(); + try { + builder + .deviceSn(entity.getDeviceSn()) + .childDeviceSn(entity.getChildSn()) + .deviceName(entity.getDeviceName()) + .deviceDesc(entity.getDeviceDesc()) + .controlSource(ControlSourceEnum.find(entity.getDeviceIndex())) + .workspaceId(entity.getWorkspaceId()) + .type(DeviceTypeEnum.find(entity.getDeviceType())) + .subType(DeviceSubTypeEnum.find(entity.getSubType())) + .domain(DeviceDomainEnum.find(entity.getDomain())) + .iconUrl(new DeviceIconUrl() + .setNormalIconUrl(entity.getUrlNormal()) + .setSelectIconUrl(entity.getUrlSelect())) + .boundStatus(entity.getBoundStatus()) + .loginTime(entity.getLoginTime() != null ? + LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getLoginTime()), ZoneId.systemDefault()) + : null) + .boundTime(entity.getBoundTime() != null ? + LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getBoundTime()), ZoneId.systemDefault()) + : null) + .nickname(entity.getNickname()) + .firmwareVersion(entity.getFirmwareVersion()) + .workspaceName(entity.getWorkspaceId() != null ? + workspaceService.getWorkspaceByWorkspaceId(entity.getWorkspaceId()) + .map(WorkspaceDTO::getWorkspaceName).orElse("") : "") + .firmwareStatus(DeviceFirmwareStatusEnum.NOT_UPGRADE) + .thingVersion(entity.getVersion()).build(); + } catch (CloudSDKException e) { + log.error(e.getLocalizedMessage() + "Entity: {}", entity); + } + DeviceDTO deviceDTO = builder.build(); + addFirmwareStatus(deviceDTO, entity); + return deviceDTO; + } + + private void addFirmwareStatus(DeviceDTO deviceDTO, DeviceEntity entity) { + if (!StringUtils.hasText(entity.getFirmwareVersion())) { + return; + } + // Query whether the device is updating firmware. + Optional> progressOpt = deviceRedisService.getFirmwareUpgradingProgress(entity.getDeviceSn()); + if (progressOpt.isPresent()) { + deviceDTO.setFirmwareStatus(DeviceFirmwareStatusEnum.UPGRADING); + deviceDTO.setFirmwareProgress(progressOpt.map(EventsReceiver::getOutput) + .map(OtaProgress::getProgress) + .map(OtaProgressData::getPercent) + .orElse(0)); + return; + } + + // First query the latest firmware version of the device model and compare it with the current firmware version + // to see if it needs to be upgraded. + Optional firmwareReleaseNoteOpt = deviceFirmwareService.getLatestFirmwareReleaseNote(entity.getDeviceName()); + if (firmwareReleaseNoteOpt.isEmpty()) { + deviceDTO.setFirmwareStatus(DeviceFirmwareStatusEnum.NOT_UPGRADE); + return; + } + if (entity.getFirmwareVersion().equals(firmwareReleaseNoteOpt.get().getProductVersion())) { + deviceDTO.setFirmwareStatus(entity.getCompatibleStatus() ? + DeviceFirmwareStatusEnum.NOT_UPGRADE : + DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE); + return; + } + deviceDTO.setFirmwareStatus(DeviceFirmwareStatusEnum.NORMAL_UPGRADE); + } + + @Override + public Boolean updateDevice(DeviceDTO deviceDTO) { + int update = mapper.update(this.deviceDTO2Entity(deviceDTO), + new LambdaUpdateWrapper().eq(DeviceEntity::getDeviceSn, deviceDTO.getDeviceSn())); + return update > 0; + } + + @Override + public Boolean bindDevice(DeviceDTO device) { + device.setBoundStatus(true); + device.setBoundTime(LocalDateTime.now()); + + boolean isUpd = this.updateDevice(device); + if (!isUpd) { + return false; + } + + Optional deviceOpt = deviceRedisService.getDeviceOnline(device.getDeviceSn()); + if (deviceOpt.isEmpty()) { + return false; + } + + DeviceDTO redisDevice = deviceOpt.get(); + redisDevice.setWorkspaceId(device.getWorkspaceId()); + deviceRedisService.setDeviceOnline(redisDevice); + + String gatewaySn, deviceSn; + if (DeviceDomainEnum.REMOTER_CONTROL == redisDevice.getDomain()) { + gatewaySn = device.getDeviceSn(); + deviceSn = redisDevice.getChildDeviceSn(); + } else { + gatewaySn = redisDevice.getParentSn(); + deviceSn = device.getDeviceSn(); + } + + pushDeviceOnlineTopo(device.getWorkspaceId(), gatewaySn, deviceSn); + subDeviceOnlineSubscribeTopic(SDKManager.getDeviceSDK(gatewaySn)); + return true; + } + + @Override + public PaginationData getBoundDevicesWithDomain(String workspaceId, Long page, + Long pageSize, Integer domain) { + + Page pagination = mapper.selectPage(new Page<>(page, pageSize), + new LambdaQueryWrapper() + .eq(DeviceEntity::getDomain, domain) + .eq(DeviceEntity::getWorkspaceId, workspaceId) + .eq(DeviceEntity::getBoundStatus, true)); + List devicesList = pagination.getRecords().stream().map(this::deviceEntityConvertToDTO) + .peek(device -> { + device.setStatus(deviceRedisService.checkDeviceOnline(device.getDeviceSn())); + if (StringUtils.hasText(device.getChildDeviceSn())) { + Optional childOpt = this.getDeviceBySn(device.getChildDeviceSn()); + childOpt.ifPresent(child -> { + child.setStatus(deviceRedisService.checkDeviceOnline(child.getDeviceSn())); + child.setWorkspaceName(device.getWorkspaceName()); + device.setChildren(child); + }); + } + }) + .collect(Collectors.toList()); + return new PaginationData(devicesList, new Pagination(pagination.getCurrent(), pagination.getSize(), pagination.getTotal())); + } + + @Override + public void unbindDevice(String deviceSn) { + + Optional deviceOpt = deviceRedisService.getDeviceOnline(deviceSn); + if (deviceOpt.isPresent()) { + subDeviceOffline(deviceSn); + } else { + deviceOpt = getDeviceBySn(deviceSn); + } + if (deviceOpt.isEmpty()) { + return; + } + DeviceDTO device = DeviceDTO.builder() + .deviceSn(deviceSn) + .workspaceId("") + .userId("") + .boundStatus(false) + .build(); + this.updateDevice(device); + } + + @Override + public Optional getDeviceBySn(String sn) { + List devicesList = this.getDevicesByParams(DeviceQueryParam.builder().deviceSn(sn).build()); + if (devicesList.isEmpty()) { + return Optional.empty(); + } + DeviceDTO device = devicesList.get(0); + device.setStatus(deviceRedisService.checkDeviceOnline(sn)); + return Optional.of(device); + } + + @Override + public HttpResultResponse createDeviceOtaJob(String workspaceId, List upgradeDTOS) { + List deviceOtaFirmwares = deviceFirmwareService.getDeviceOtaFirmware(workspaceId, upgradeDTOS); + if (deviceOtaFirmwares.isEmpty()) { + return HttpResultResponse.error(); + } + + Optional deviceOpt = deviceRedisService.getDeviceOnline(deviceOtaFirmwares.get(0).getSn()); + if (deviceOpt.isEmpty()) { + throw new RuntimeException("设备处于脱机状态。"); + } + DeviceDTO device = deviceOpt.get(); + String gatewaySn = DeviceDomainEnum.DOCK == device.getDomain() ? device.getDeviceSn() : device.getParentSn(); + + checkOtaConditions(gatewaySn); + + TopicServicesResponse> response = abstractFirmwareService.otaCreate( + SDKManager.getDeviceSDK(gatewaySn), new OtaCreateRequest().setDevices(deviceOtaFirmwares)); + ServicesReplyData serviceReply = response.getData(); + String bid = response.getBid(); + if (!serviceReply.getResult().isSuccess()) { + return HttpResultResponse.error(serviceReply.getResult()); + } + + // Record the device state that needs to be updated. + deviceOtaFirmwares.forEach(deviceOta -> deviceRedisService.setFirmwareUpgrading(deviceOta.getSn(), + EventsReceiver.builder().bid(bid).sn(deviceOta.getSn()).build())); + return HttpResultResponse.success(); + } + + /** + * Determine whether the firmware can be upgraded. + * @param dockSn + */ + private void checkOtaConditions(String dockSn) { + Optional deviceOpt = deviceRedisService.getDeviceOsd(dockSn, OsdDock.class); + if (deviceOpt.isEmpty()) { + throw new RuntimeException("Dock处于脱机状态。"); + } + boolean emergencyStopState = deviceOpt.get().getEmergencyStopState(); + if (emergencyStopState) { + throw new RuntimeException("码头的紧急停止按钮被按下,无法升级。"); + } + + DockModeCodeEnum dockMode = this.getDockMode(dockSn); + if (DockModeCodeEnum.IDLE != dockMode) { + throw new RuntimeException("无法升级dock的当前状态。"); + } + } + + @Override + public int devicePropertySet(String workspaceId, String dockSn, JsonNode param) { + String property = param.fieldNames().next(); + PropertySetFieldEnum propertyEnum = PropertySetFieldEnum.find(property); + + Optional dockOpt = deviceRedisService.getDeviceOnline(dockSn); + if (dockOpt.isEmpty()) { + throw new RuntimeException("Dock处于脱机状态。"); + } + String childSn = dockOpt.get().getChildDeviceSn(); + Optional osdOpt = deviceRedisService.getDeviceOsd(childSn, OsdDockDrone.class); + if (osdOpt.isEmpty()) { + throw new RuntimeException("设备处于脱机状态。"); + } + + // Make sure the data is valid. + BasicDeviceProperty basicDeviceProperty = objectMapper.convertValue(param.get(property), propertyEnum.getClazz()); + boolean valid = basicDeviceProperty.valid(); + if (!valid) { + throw new IllegalArgumentException(CommonErrorEnum.ILLEGAL_ARGUMENT.getMessage()); + } + boolean isPublish = basicDeviceProperty.canPublish(osdOpt.get()); + if (!isPublish) { + return PropertySetReplyResultEnum.SUCCESS.getResult(); + } + BaseModel baseModel = objectMapper.convertValue(param, propertyEnum.getProperty().getClazz()); + PropertySetReplyResultEnum result = abstractPropertyService.propertySet( + SDKManager.getDeviceSDK(dockSn), propertyEnum.getProperty(), baseModel); + return result.getResult(); + } + + @Override + public DockModeCodeEnum getDockMode(String dockSn) { + return deviceRedisService.getDeviceOsd(dockSn, OsdDock.class) + .map(OsdDock::getModeCode).orElse(null); + } + + @Override + public DroneModeCodeEnum getDeviceMode(String deviceSn) { + return deviceRedisService.getDeviceOsd(deviceSn, OsdDockDrone.class) + .map(OsdDockDrone::getModeCode).orElse(DroneModeCodeEnum.DISCONNECTED); + } + + @Override + public Boolean checkDockDrcMode(String dockSn) { + return deviceRedisService.getDeviceOsd(dockSn, OsdDock.class) + .map(OsdDock::getDrcState) + .orElse(DrcStateEnum.DISCONNECTED) != DrcStateEnum.DISCONNECTED; + } + + @Override + public Boolean checkAuthorityFlight(String gatewaySn) { + return deviceRedisService.getDeviceOnline(gatewaySn).flatMap(gateway -> + Optional.of((DeviceDomainEnum.DOCK == gateway.getDomain() + || DeviceDomainEnum.REMOTER_CONTROL == gateway.getDomain()) + && ControlSourceEnum.A == gateway.getControlSource())) + .orElse(true); + } + + @Override + public void updateFlightControl(DeviceDTO gateway, ControlSourceEnum controlSource) { + if (controlSource == gateway.getControlSource()) { + return; + } + gateway.setControlSource(controlSource); + deviceRedisService.setDeviceOnline(gateway); + + webSocketMessageService.sendBatch(gateway.getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.CONTROL_SOURCE_CHANGE.getCode(), + DeviceAuthorityDTO.builder() + .controlSource(gateway.getControlSource()) + .sn(gateway.getDeviceSn()) + .type(DroneAuthorityEnum.FLIGHT) + .build()); + } + + /** + * Convert device data transfer object into database entity object. + * @param dto + * @return + */ + private DeviceEntity deviceDTO2Entity(DeviceDTO dto) { + DeviceEntity.DeviceEntityBuilder builder = DeviceEntity.builder(); + if (dto == null) { + return builder.build(); + } + + return builder.deviceSn(dto.getDeviceSn()) + .deviceIndex(Optional.ofNullable(dto.getControlSource()) + .map(ControlSourceEnum::getControlSource).orElse(null)) + .deviceName(dto.getDeviceName()) + .version(dto.getThingVersion()) + .userId(dto.getUserId()) + .nickname(dto.getNickname()) + .workspaceId(dto.getWorkspaceId()) + .boundStatus(dto.getBoundStatus()) + .domain(Optional.ofNullable(dto.getDomain()).map(DeviceDomainEnum::getDomain).orElse(null)) + .deviceType(Optional.ofNullable(dto.getType()).map(DeviceTypeEnum::getType).orElse(null)) + .subType(Optional.ofNullable(dto.getSubType()).map(DeviceSubTypeEnum::getSubType).orElse(null)) + .loginTime(dto.getLoginTime() != null ? + dto.getLoginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : null) + .boundTime(dto.getBoundTime() != null ? + dto.getBoundTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : null) + .childSn(dto.getChildDeviceSn()) + .firmwareVersion(dto.getFirmwareVersion()) + .compatibleStatus(dto.getFirmwareStatus() == null ? null : + DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE != dto.getFirmwareStatus()) + .deviceDesc(dto.getDeviceDesc()) + .build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/FirmwareModelServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/FirmwareModelServiceImpl.java new file mode 100644 index 0000000..6256527 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/FirmwareModelServiceImpl.java @@ -0,0 +1,44 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.manage.dao.IFirmwareModelMapper; +import com.dji.sample.manage.model.dto.FirmwareModelDTO; +import com.dji.sample.manage.model.entity.FirmwareModelEntity; +import com.dji.sample.manage.service.IFirmwareModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.3 + * @date 2022/12/21 + */ +@Service +@Transactional +public class FirmwareModelServiceImpl implements IFirmwareModelService { + + @Autowired + private IFirmwareModelMapper mapper; + + @Override + public void saveFirmwareDeviceName(FirmwareModelDTO firmwareModel) { + dto2Entity(firmwareModel).forEach(entity -> mapper.insert(entity)); + } + + private List dto2Entity(FirmwareModelDTO dto) { + if (Objects.isNull(dto) || CollectionUtils.isEmpty(dto.getDeviceNames())) { + return Collections.EMPTY_LIST; + } + return dto.getDeviceNames().stream() + .map(deviceName -> FirmwareModelEntity.builder() + .firmwareId(dto.getFirmwareId()) + .deviceName(deviceName).build()) + .collect(Collectors.toList()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LiveStreamServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LiveStreamServiceImpl.java new file mode 100644 index 0000000..300c88a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LiveStreamServiceImpl.java @@ -0,0 +1,233 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.manage.model.dto.*; +import com.dji.sample.manage.model.param.DeviceQueryParam; +import com.dji.sample.manage.service.*; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.device.VideoId; +import com.dji.sdk.cloudapi.livestream.*; +import com.dji.sdk.cloudapi.livestream.api.AbstractLivestreamService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author sean.zhou + * @date 2021/11/22 + * @version 0.1 + */ +@Service +@Transactional +public class LiveStreamServiceImpl implements ILiveStreamService { + + @Autowired + private ICapacityCameraService capacityCameraService; + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IWorkspaceService workspaceService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private AbstractLivestreamService abstractLivestreamService; + + @Override + public List getLiveCapacity(String workspaceId) { + + // Query all devices in this workspace. + List devicesList = deviceService.getDevicesByParams( + DeviceQueryParam.builder() + .workspaceId(workspaceId) + .domains(List.of(DeviceDomainEnum.DRONE.getDomain(), DeviceDomainEnum.DOCK.getDomain())) + .build()); + + // Query the live capability of each drone. + return devicesList.stream() + .filter(device -> deviceRedisService.checkDeviceOnline(device.getDeviceSn())) + .map(device -> CapacityDeviceDTO.builder() + .name(Objects.requireNonNullElse(device.getNickname(), device.getDeviceName())) + .sn(device.getDeviceSn()) + .camerasList(capacityCameraService.getCapacityCameraByDeviceSn(device.getDeviceSn())) + .build()) + .collect(Collectors.toList()); + } + + @Override + public HttpResultResponse liveStart(LiveTypeDTO liveParam) { + // Check if this lens is available live. + HttpResultResponse responseResult = this.checkBeforeLive(liveParam.getVideoId()); + if (HttpResultResponse.CODE_SUCCESS != responseResult.getCode()) { + return responseResult; + } + + ILivestreamUrl url = LiveStreamProperty.get(liveParam.getUrlType()); + url = setExt(liveParam.getUrlType(), url, liveParam.getVideoId()); + + TopicServicesResponse> response = abstractLivestreamService.liveStartPush( + SDKManager.getDeviceSDK(responseResult.getData().getDeviceSn()), + new LiveStartPushRequest() + .setUrl(url) + .setUrlType(liveParam.getUrlType()) + .setVideoId(liveParam.getVideoId()) + .setVideoQuality(liveParam.getVideoQuality())); + + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); + } + + LiveDTO live = new LiveDTO(); + + switch (liveParam.getUrlType()) { + case AGORA: + break; + case RTMP: + live.setUrl(url.toString().replace("rtmp", "webrtc")); + break; + case GB28181: + LivestreamGb28181Url gb28181 = (LivestreamGb28181Url) url; + live.setUrl(new StringBuilder() + .append("webrtc://") + .append(gb28181.getServerIP()) + .append("/live/") + .append(gb28181.getAgentID()) + .append("@") + .append(gb28181.getChannel()) + .toString()); + break; + case RTSP: + live.setUrl(response.getData().getOutput()); + break; + case WHIP: + live.setUrl(url.toString().replace("whip", "whep")); + break; + default: + return HttpResultResponse.error(LiveErrorCodeEnum.URL_TYPE_NOT_SUPPORTED); + } + + return HttpResultResponse.success(live); + } + + @Override + public HttpResultResponse liveStop(VideoId videoId) { + HttpResultResponse responseResult = this.checkBeforeLive(videoId); + if (HttpResultResponse.CODE_SUCCESS != responseResult.getCode()) { + return responseResult; + } + + TopicServicesResponse response = abstractLivestreamService.liveStopPush( + SDKManager.getDeviceSDK(responseResult.getData().getDeviceSn()), new LiveStopPushRequest() + .setVideoId(videoId)); + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); + } + + return HttpResultResponse.success(); + } + + @Override + public HttpResultResponse liveSetQuality(LiveTypeDTO liveParam) { + HttpResultResponse responseResult = this.checkBeforeLive(liveParam.getVideoId()); + if (responseResult.getCode() != 0) { + return responseResult; + } + + TopicServicesResponse response = abstractLivestreamService.liveSetQuality( + SDKManager.getDeviceSDK(responseResult.getData().getDeviceSn()), new LiveSetQualityRequest() + .setVideoQuality(liveParam.getVideoQuality()) + .setVideoId(liveParam.getVideoId())); + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); + } + + return HttpResultResponse.success(); + } + + @Override + public HttpResultResponse liveLensChange(LiveTypeDTO liveParam) { + HttpResultResponse responseResult = this.checkBeforeLive(liveParam.getVideoId()); + if (HttpResultResponse.CODE_SUCCESS != responseResult.getCode()) { + return responseResult; + } + + TopicServicesResponse response = abstractLivestreamService.liveLensChange( + SDKManager.getDeviceSDK(responseResult.getData().getDeviceSn()), new LiveLensChangeRequest() + .setVideoType(liveParam.getVideoType()) + .setVideoId(liveParam.getVideoId())); + + if (!response.getData().getResult().isSuccess()) { + return HttpResultResponse.error(response.getData().getResult()); + } + + return HttpResultResponse.success(); + } + + /** + * Check if this lens is available live. + * @param videoId + * @return + */ + private HttpResultResponse checkBeforeLive(VideoId videoId) { + if (Objects.isNull(videoId)) { + return HttpResultResponse.error(LiveErrorCodeEnum.ERROR_PARAMETERS); + } + + Optional deviceOpt = deviceService.getDeviceBySn(videoId.getDroneSn()); + // Check if the gateway device connected to this drone exists + if (deviceOpt.isEmpty()) { + return HttpResultResponse.error(LiveErrorCodeEnum.NO_AIRCRAFT); + } + + if (DeviceDomainEnum.DOCK == deviceOpt.get().getDomain()) { + return HttpResultResponse.success(deviceOpt.get()); + } + List gatewayList = deviceService.getDevicesByParams( + DeviceQueryParam.builder() + .childSn(videoId.getDroneSn()) + .build()); + if (gatewayList.isEmpty()) { + return HttpResultResponse.error(LiveErrorCodeEnum.NO_FLIGHT_CONTROL); + } + + return HttpResultResponse.success(gatewayList.get(0)); + } + + /** + * This is business-customized logic and is only used for testing. + * @param type + * @param url + * @param videoId + */ + private ILivestreamUrl setExt(UrlTypeEnum type, ILivestreamUrl url, VideoId videoId) { + switch (type) { + case AGORA: + LivestreamAgoraUrl agoraUrl = (LivestreamAgoraUrl) url.clone(); + return agoraUrl.setSn(videoId.getDroneSn()); + case RTMP: + LivestreamRtmpUrl rtmpUrl = (LivestreamRtmpUrl) url.clone(); + return rtmpUrl.setUrl(rtmpUrl.getUrl() + videoId.getDroneSn() + "-" + videoId.getPayloadIndex().toString()); + case GB28181: + String random = String.valueOf(Math.abs(videoId.getDroneSn().hashCode()) % 1000); + LivestreamGb28181Url gbUrl = (LivestreamGb28181Url) url.clone(); + gbUrl.setAgentID(gbUrl.getAgentID().substring(0, 20 - random.length()) + random); + String deviceType = String.valueOf(videoId.getPayloadIndex().getType().getType()); + return gbUrl.setChannel(gbUrl.getChannel().substring(0, 20 - deviceType.length()) + deviceType); + case WHIP: + LivestreamWhipUrl whipUrl = (LivestreamWhipUrl) url.clone(); + return whipUrl.setUrl(whipUrl.getUrl() + videoId.getDroneSn() + "-" + videoId.getPayloadIndex().toString()); + } + return url; + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LogsFileIndexServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LogsFileIndexServiceImpl.java new file mode 100644 index 0000000..22673f3 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LogsFileIndexServiceImpl.java @@ -0,0 +1,108 @@ +package com.dji.sample.manage.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.dji.sample.manage.dao.ILogsFileIndexMapper; +import com.dji.sample.manage.model.dto.LogsFileDTO; +import com.dji.sample.manage.model.dto.LogsFileUploadDTO; +import com.dji.sample.manage.model.entity.LogsFileIndexEntity; +import com.dji.sample.manage.service.ILogsFileIndexService; +import com.dji.sdk.cloudapi.log.LogFileIndex; +import com.dji.sdk.cloudapi.log.LogModuleEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/8 + */ +@Service +@Transactional +public class LogsFileIndexServiceImpl implements ILogsFileIndexService { + + @Autowired + private ILogsFileIndexMapper mapper; + + @Override + public Boolean insertFileIndex(LogFileIndex file, String deviceSn, Integer domain, String fileId) { + LogsFileIndexEntity entity = this.logsFile2Entity(file); + if (Objects.isNull(entity)) { + return false; + } + entity.setDomain(domain); + entity.setDeviceSn(deviceSn); + entity.setFileId(fileId); + + return mapper.insert(entity) > 0; + } + + @Override + public List getFileIndexByFileIds(List files) { + List list = new ArrayList<>(); + files.forEach(file -> { + Optional fileOpt = this.getFileIndexByFileId(file.getFileId()); + fileOpt.ifPresent(fileUpload -> { + fileUpload.setObjectKey(file.getStatus() ? file.getObjectKey() : null); + list.add(fileUpload); + }); + }); + return list; + } + + @Override + public void deleteFileIndexByFileIds(List fileIds) { + mapper.delete(new LambdaUpdateWrapper() + .or(wrapper -> fileIds.forEach(fileId -> wrapper.eq(LogsFileIndexEntity::getFileId, fileId)))); + } + + @Override + public Optional getFileIndexByFileId(String fileId) { + List logsFileIndexList = mapper.selectList( + new LambdaQueryWrapper().eq(LogsFileIndexEntity::getFileId, fileId)); + if (CollectionUtils.isEmpty(logsFileIndexList)) { + return Optional.empty(); + } + LogsFileIndexEntity entity = logsFileIndexList.get(0); + List logsFileList = logsFileIndexList.stream().map(this::entity2LogsFile).collect(Collectors.toList()); + return Optional.of(LogsFileUploadDTO.builder() + .deviceSn(entity.getDeviceSn()) + .deviceModelDomain(LogModuleEnum.find(String.valueOf(entity.getDomain()))) + .list(logsFileList) + .fileId(fileId) + .build()); + + } + + private LogFileIndex entity2LogsFile(LogsFileIndexEntity entity) { + if (Objects.isNull(entity)) { + return null; + } + return new LogFileIndex() + .setBootIndex(entity.getBootIndex()) + .setStartTime(entity.getStartTime()) + .setEndTime(entity.getEndTime()) + .setSize(entity.getSize()); + + } + + private LogsFileIndexEntity logsFile2Entity(LogFileIndex file) { + if (Objects.isNull(file)) { + return null; + } + return LogsFileIndexEntity.builder() + .bootIndex(file.getBootIndex()) + .size(file.getSize()) + .startTime(file.getStartTime()) + .endTime(file.getEndTime()) + .build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LogsFileServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LogsFileServiceImpl.java new file mode 100644 index 0000000..4a839b9 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LogsFileServiceImpl.java @@ -0,0 +1,161 @@ +package com.dji.sample.manage.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.oss.service.impl.OssServiceContext; +import com.dji.sample.manage.dao.ILogsFileMapper; +import com.dji.sample.manage.model.dto.LogsFileDTO; +import com.dji.sample.manage.model.dto.LogsFileUploadDTO; +import com.dji.sample.manage.model.entity.LogsFileEntity; +import com.dji.sample.manage.service.ILogsFileIndexService; +import com.dji.sample.manage.service.ILogsFileService; +import com.dji.sdk.cloudapi.log.FileUploadProgressFile; +import com.dji.sdk.cloudapi.log.FileUploadStartFile; +import com.dji.sdk.cloudapi.log.FileUploadStatusEnum; +import com.dji.sdk.cloudapi.log.LogFileIndex; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.2 + * @date 2022/9/7 + */ +@Service +@Transactional +public class LogsFileServiceImpl implements ILogsFileService { + + @Autowired + private ILogsFileMapper mapper; + + @Autowired + private ILogsFileIndexService logsFileIndexService; + + @Autowired + private OssServiceContext ossService; + + @Autowired + private OssServiceContext ossServiceContext; + + @Override + public List getLogsFileInfoByLogsId(String logsId) { + return mapper.selectList( + new LambdaQueryWrapper() + .eq(LogsFileEntity::getLogsId, logsId)).stream() + .map(this::entity2Dto).collect(Collectors.toList()); + } + + private LogsFileDTO entity2Dto(LogsFileEntity entity) { + if (Objects.isNull(entity)) { + return null; + } + return LogsFileDTO.builder() + .deviceSn(entity.getDeviceSn()) + .fileId(entity.getFileId()) + .fingerprint(entity.getFingerprint()) + .logsId(entity.getLogsId()) + .name(entity.getName()) + .objectKey(entity.getObjectKey()) + .size(entity.getSize()) + .status(entity.getStatus()) + .build(); + } + + @Override + public List getLogsFileByLogsId(String logsId) { + List logsFiles = this.getLogsFileInfoByLogsId(logsId); + if (CollectionUtils.isEmpty(logsFiles)) { + return new ArrayList<>(); + } + return logsFileIndexService.getFileIndexByFileIds(logsFiles); + } + + @Override + public Boolean insertFile(FileUploadStartFile file, String logsId) { + LogsFileEntity entity = LogsFileEntity.builder() + .logsId(logsId) + .fileId(UUID.randomUUID().toString()) + .objectKey(file.getObjectKey()) + .status(false) + .deviceSn(file.getDeviceSn()) + .build(); + boolean insert = mapper.insert(entity) > 0; + if (!insert) { + return false; + } + for (LogFileIndex logsFile : file.getList()) { + insert = logsFileIndexService.insertFileIndex(logsFile, file.getDeviceSn(), Integer.valueOf(file.getModule().getDomain()), entity.getFileId()); + if (!insert) { + return false; + } + } + return true; + } + + @Override + public void deleteFileByLogsId(String logsId) { + List logsFiles = this.getLogsFileInfoByLogsId(logsId); + if (CollectionUtils.isEmpty(logsFiles)) { + return; + } + mapper.delete(new LambdaUpdateWrapper().eq(LogsFileEntity::getLogsId, logsId)); + List fileIds = new ArrayList<>(); + logsFiles.forEach(file -> { + if (file.getStatus()) { + ossService.deleteObject(OssConfiguration.bucket, file.getObjectKey()); + } + fileIds.add(file.getFileId()); + }); + + logsFileIndexService.deleteFileIndexByFileIds(fileIds); + } + + @Override + public void updateFile(String logsId, FileUploadProgressFile fileReceiver) { + List logsFiles = this.getLogsFileInfoByLogsId(logsId); + if (CollectionUtils.isEmpty(logsFiles)) { + return; + } + mapper.update(receiver2Entity(fileReceiver), + new LambdaUpdateWrapper().eq(LogsFileEntity::getLogsId, logsId) + .eq(LogsFileEntity::getDeviceSn, fileReceiver.getDeviceSn())); + } + + @Override + public void updateFileUploadStatus(String logsId, Boolean isUploaded) { + mapper.update(LogsFileEntity.builder().status(isUploaded).build(), + new LambdaUpdateWrapper().eq(LogsFileEntity::getLogsId, logsId)); + } + + @Override + public URL getLogsFileUrl(String logsId, String fileId) { + LogsFileEntity logsFile = mapper.selectOne(new LambdaQueryWrapper() + .eq(LogsFileEntity::getLogsId, logsId).eq(LogsFileEntity::getFileId, fileId)); + if (Objects.isNull(logsFile)) { + return null; + } + return ossService.getObjectUrl(OssConfiguration.bucket, logsFile.getObjectKey()); + } + + private LogsFileEntity receiver2Entity(FileUploadProgressFile receiver) { + if (Objects.isNull(receiver)) { + return null; + } + return LogsFileEntity.builder() + .fingerprint(receiver.getFingerprint()) + .size(receiver.getSize()) + .status(Objects.nonNull(receiver.getProgress()) + && FileUploadStatusEnum.OK == receiver.getProgress().getStatus()) + .name(receiver.getKey().substring(receiver.getKey().lastIndexOf("/") + 1)).build(); + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/RequestConfigContext.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/RequestConfigContext.java new file mode 100644 index 0000000..85c448e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/RequestConfigContext.java @@ -0,0 +1,42 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.common.util.SpringBeanUtilsTest; +import com.dji.sample.manage.model.dto.ProductConfigDTO; +import com.dji.sample.manage.model.enums.CustomizeConfigScopeEnum; +import com.dji.sdk.cloudapi.config.ProductConfigResponse; +import com.dji.sdk.cloudapi.config.RequestsConfigRequest; +import com.dji.sdk.cloudapi.config.api.AbstractConfigService; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/10 + */ +@Service +public class RequestConfigContext extends AbstractConfigService { + + @Override + public TopicRequestsResponse requestsConfig(TopicRequestsRequest request, MessageHeaders headers) { + RequestsConfigRequest configReceiver = request.getData(); + Optional scopeEnumOpt = CustomizeConfigScopeEnum.find(configReceiver.getConfigScope().getScope()); + if (scopeEnumOpt.isEmpty()) { + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); + } + + ProductConfigDTO config = (ProductConfigDTO) SpringBeanUtilsTest.getBean(scopeEnumOpt.get().getClazz()).getConfig(); + return new TopicRequestsResponse().setData( + new ProductConfigResponse() + .setNtpServerHost(config.getNtpServerHost()) + .setAppId(config.getAppId()) + .setAppKey(config.getAppKey()) + .setAppLicense(config.getAppLicense())); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKDeviceService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKDeviceService.java new file mode 100644 index 0000000..66f4a8c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKDeviceService.java @@ -0,0 +1,504 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.dto.DevicePayloadReceiver; +import com.dji.sample.manage.model.enums.DeviceFirmwareStatusEnum; +import com.dji.sample.manage.model.param.DeviceQueryParam; +import com.dji.sample.manage.service.IDeviceDictionaryService; +import com.dji.sample.manage.service.IDevicePayloadService; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sdk.cloudapi.device.*; +import com.dji.sdk.cloudapi.device.api.AbstractDeviceService; +import com.dji.sdk.cloudapi.tsa.DeviceIconUrl; +import com.dji.sdk.cloudapi.tsa.IconUrlEnum; +import com.dji.sdk.config.version.GatewayManager; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.osd.TopicOsdRequest; +import com.dji.sdk.mqtt.state.TopicStateRequest; +import com.dji.sdk.mqtt.status.TopicStatusRequest; +import com.dji.sdk.mqtt.status.TopicStatusResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/4 + */ +@Service +@Slf4j +public class SDKDeviceService extends AbstractDeviceService { + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IDeviceDictionaryService dictionaryService; + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IDevicePayloadService devicePayloadService; + + @Override + public TopicStatusResponse updateTopoOnline(TopicStatusRequest request, MessageHeaders headers) { + UpdateTopoSubDevice updateTopoSubDevice = request.getData().getSubDevices().get(0); + String deviceSn = updateTopoSubDevice.getSn(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(deviceSn); + Optional gatewayOpt = deviceRedisService.getDeviceOnline(request.getFrom()); + GatewayManager gatewayManager = SDKManager.registerDevice(request.getFrom(), deviceSn, + request.getData().getDomain(), request.getData().getType(), + request.getData().getSubType(), request.getData().getThingVersion(), updateTopoSubDevice.getThingVersion()); + + if (deviceOpt.isPresent() && gatewayOpt.isPresent()) { + deviceOnlineAgain(deviceOpt.get().getWorkspaceId(), request.getFrom(), deviceSn); + return new TopicStatusResponse().setData(MqttReply.success()); + } + + changeSubDeviceParent(deviceSn, request.getFrom()); + + DeviceDTO gateway = deviceGatewayConvertToDevice(request.getFrom(), request.getData()); + Optional gatewayEntityOpt = onlineSaveDevice(gateway, deviceSn, null); + if (gatewayEntityOpt.isEmpty()) { + log.error("无法联机,请检查状态数据或代码逻辑。"); + return null; + } + DeviceDTO subDevice = subDeviceConvertToDevice(updateTopoSubDevice); + Optional subDeviceEntityOpt = onlineSaveDevice(subDevice, null, gateway.getDeviceSn()); + if (subDeviceEntityOpt.isEmpty()) { + log.error("无法联机,请检查状态数据或代码逻辑。"); + return null; + } + subDevice = subDeviceEntityOpt.get(); + gateway = gatewayEntityOpt.get(); + dockGoOnline(gateway, subDevice); + deviceService.gatewayOnlineSubscribeTopic(gatewayManager); + + if (!StringUtils.hasText(subDevice.getWorkspaceId())) { + return new TopicStatusResponse().setData(MqttReply.success()); + } + + // Subscribe to topic related to drone devices. + deviceService.subDeviceOnlineSubscribeTopic(gatewayManager); + deviceService.pushDeviceOnlineTopo(gateway.getWorkspaceId(), gateway.getDeviceSn(), subDevice.getDeviceSn()); + + log.debug("{} 在线的。", subDevice.getDeviceSn()); + return new TopicStatusResponse().setData(MqttReply.success()); + } + + @Override + public TopicStatusResponse updateTopoOffline(TopicStatusRequest request, MessageHeaders headers) { + GatewayManager gatewayManager = SDKManager.registerDevice(request.getFrom(), null, + request.getData().getDomain(), request.getData().getType(), + request.getData().getSubType(), request.getData().getThingVersion(), null); + deviceService.gatewayOnlineSubscribeTopic(gatewayManager); + // Only the remote controller is logged in and the aircraft is not connected. + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getFrom()); + if (deviceOpt.isEmpty()) { + // When connecting for the first time + DeviceDTO gatewayDevice = deviceGatewayConvertToDevice(request.getFrom(), request.getData()); + Optional gatewayDeviceOpt = onlineSaveDevice(gatewayDevice, null, null); + if (gatewayDeviceOpt.isEmpty()) { + return null; + } + deviceService.pushDeviceOnlineTopo(gatewayDeviceOpt.get().getWorkspaceId(), request.getFrom(), null); + return new TopicStatusResponse().setData(MqttReply.success()); + } + + String deviceSn = deviceOpt.get().getChildDeviceSn(); + if (!StringUtils.hasText(deviceSn)) { + return new TopicStatusResponse().setData(MqttReply.success()); + } + + deviceService.subDeviceOffline(deviceSn); + return new TopicStatusResponse().setData(MqttReply.success()); + } + + @Override + public void osdDock(TopicOsdRequest request, MessageHeaders headers) { + String from = request.getFrom(); + Optional deviceOpt = deviceRedisService.getDeviceOnline(from); + if (deviceOpt.isEmpty() || !StringUtils.hasText(deviceOpt.get().getWorkspaceId())) { + deviceOpt = deviceService.getDeviceBySn(from); + if (deviceOpt.isEmpty()) { + log.error("请重新启动无人机。"); + return; + } + } + + DeviceDTO device = deviceOpt.get(); + if (!StringUtils.hasText(device.getWorkspaceId())) { + log.error("请先绑好码头。"); + } + if (StringUtils.hasText(device.getChildDeviceSn())) { + deviceService.getDeviceBySn(device.getChildDeviceSn()).ifPresent(device::setChildren); + } + + deviceRedisService.setDeviceOnline(device); + fillDockOsd(from, request.getData()); + + deviceService.pushOsdDataToWeb(device.getWorkspaceId(), BizCodeEnum.DOCK_OSD, from, request.getData()); + } + + @Override + public void osdDockDrone(TopicOsdRequest request, MessageHeaders headers) { + String from = request.getFrom(); + Optional deviceOpt = deviceRedisService.getDeviceOnline(from); + if (deviceOpt.isEmpty()) { + deviceOpt = deviceService.getDeviceBySn(from); + if (deviceOpt.isEmpty()) { + log.error("请重新启动无人机。"); + return; + } + } + + if (!StringUtils.hasText(deviceOpt.get().getWorkspaceId())) { + log.error("请重新启动无人机。"); + return; + } + + DeviceDTO device = deviceOpt.get(); + deviceRedisService.setDeviceOnline(device); + deviceRedisService.setDeviceOsd(from, request.getData()); + + deviceService.pushOsdDataToWeb(device.getWorkspaceId(), BizCodeEnum.DEVICE_OSD, from, request.getData()); + } + + @Override + public void osdRemoteControl(TopicOsdRequest request, MessageHeaders headers) { + String from = request.getFrom(); + Optional deviceOpt = deviceRedisService.getDeviceOnline(from); + if (deviceOpt.isEmpty()) { + deviceOpt = deviceService.getDeviceBySn(from); + if (deviceOpt.isEmpty()) { + System.out.println("00"); + log.error("请重新启动无人机。"); + return; + } + } + DeviceDTO device = deviceOpt.get(); + if (StringUtils.hasText(device.getChildDeviceSn())) { + deviceRedisService.getDeviceOnline(device.getChildDeviceSn()).ifPresent(device::setChildren); + } + deviceRedisService.setDeviceOnline(device); + + OsdRemoteControl data = request.getData(); + deviceService.pushOsdDataToPilot(device.getWorkspaceId(), from, + new DeviceOsdHost() + .setLatitude(data.getLatitude()) + .setLongitude(data.getLongitude()) + .setHeight(data.getHeight())); + deviceService.pushOsdDataToWeb(device.getWorkspaceId(), BizCodeEnum.RC_OSD, from, data); + + } + + @Override + public void osdRcDrone(TopicOsdRequest request, MessageHeaders headers) { + String from = request.getFrom(); + Optional deviceOpt = deviceRedisService.getDeviceOnline(from); + if (deviceOpt.isEmpty()) { + deviceOpt = deviceService.getDeviceBySn(from); + if (deviceOpt.isEmpty()) { + log.error("请重新启动无人机。"); + return; + } + } + DeviceDTO device = deviceOpt.get(); + deviceRedisService.setDeviceOnline(device); + if (!StringUtils.hasText(device.getWorkspaceId())) { + log.error("请先绑定无人机。"); + return; + } + + deviceRedisService.setDeviceOnline(device); + + OsdRcDrone data = request.getData(); + deviceService.pushOsdDataToPilot(device.getWorkspaceId(), from, + new DeviceOsdHost() + .setLatitude(data.getLatitude()) + .setLongitude(data.getLongitude()) + .setElevation(data.getElevation()) + .setHeight(data.getHeight()) + .setAttitudeHead(data.getAttitudeHead()) + .setElevation(data.getElevation()) + .setHorizontalSpeed(data.getHorizontalSpeed()) + .setVerticalSpeed(data.getVerticalSpeed())); + deviceService.pushOsdDataToWeb(device.getWorkspaceId(), BizCodeEnum.DEVICE_OSD, from, data); + } + + @Override + public void dockFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + // If the reported version is empty, it will not be processed to prevent misleading page. + if (!StringUtils.hasText(request.getData().getFirmwareVersion())) { + return; + } + + DeviceDTO device = DeviceDTO.builder() + .deviceSn(request.getFrom()) + .firmwareVersion(request.getData().getFirmwareVersion()) + .firmwareStatus(request.getData().getNeedCompatibleStatus() ? + DeviceFirmwareStatusEnum.UNKNOWN : DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE) + .build(); + boolean isUpd = deviceService.updateDevice(device); + if (!isUpd) { + log.error("固件版本的数据更新失败。SN: {}", request.getFrom()); + } + } + + @Override + public void rcAndDroneFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + // If the reported version is empty, it will not be processed to prevent misleading page. + if (!StringUtils.hasText(request.getData().getFirmwareVersion())) { + return; + } + + DeviceDTO device = DeviceDTO.builder() + .deviceSn(request.getFrom()) + .firmwareVersion(request.getData().getFirmwareVersion()) + .build(); + boolean isUpd = deviceService.updateDevice(device); + if (!isUpd) { + log.error("固件版本的数据更新失败。SN: {}", request.getFrom()); + } + } + + @Override + public void rcPayloadFirmwareVersionUpdate(TopicStateRequest request, MessageHeaders headers) { + // If the reported version is empty, it will not be processed to prevent misleading page. + if (!StringUtils.hasText(request.getData().getFirmwareVersion())) { + return; + } + + boolean isUpd = devicePayloadService.updateFirmwareVersion(request.getFrom(), request.getData()); + if (!isUpd) { + log.error("有效负载固件版本的数据更新失败。SN: {}", request.getFrom()); + } + } + + @Override + public void dockControlSourceUpdate(TopicStateRequest request, MessageHeaders headers) { + // If the control source is empty, it will not be processed. + if (ControlSourceEnum.UNKNOWN == request.getData().getControlSource()) { + return; + } + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getFrom()); + if (deviceOpt.isEmpty()) { + return; + } + Optional dockOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + if (dockOpt.isEmpty()) { + return; + } + + deviceService.updateFlightControl(dockOpt.get(), request.getData().getControlSource()); + devicePayloadService.updatePayloadControl(deviceOpt.get(), + request.getData().getPayloads().stream() + .map(p -> DevicePayloadReceiver.builder() + .controlSource(p.getControlSource()) + .payloadIndex(p.getPayloadIndex()) + .sn(p.getSn()) + .deviceSn(request.getFrom()) + .build()).collect(Collectors.toList())); + } + + @Override + public void rcControlSourceUpdate(TopicStateRequest request, MessageHeaders headers) { + // If the control source is empty, it will not be processed. + if (ControlSourceEnum.UNKNOWN == request.getData().getControlSource()) { + return; + } + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getFrom()); + if (deviceOpt.isEmpty()) { + return; + } + Optional dockOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + if (dockOpt.isEmpty()) { + return; + } + + deviceService.updateFlightControl(dockOpt.get(), request.getData().getControlSource()); + devicePayloadService.updatePayloadControl(deviceOpt.get(), + request.getData().getPayloads().stream() + .map(p -> DevicePayloadReceiver.builder() + .controlSource(p.getControlSource()) + .payloadIndex(p.getPayloadIndex()) + .sn(p.getSn()) + .deviceSn(request.getFrom()) + .build()).collect(Collectors.toList())); + } + + private void dockGoOnline(DeviceDTO gateway, DeviceDTO subDevice) { + if (DeviceDomainEnum.DOCK != gateway.getDomain()) { + return; + } + if (!StringUtils.hasText(gateway.getWorkspaceId())) { + log.error("码头未绑定,请先绑定,然后再联机。"); + return; + } + if (!Objects.requireNonNullElse(subDevice.getBoundStatus(), false)) { + // Directly bind the drone of the dock to the same workspace as the dock. + deviceService.bindDevice(DeviceDTO.builder().deviceSn(subDevice.getDeviceSn()).workspaceId(gateway.getWorkspaceId()).build()); + subDevice.setWorkspaceId(gateway.getWorkspaceId()); + } + deviceRedisService.setDeviceOnline(subDevice); + } + + private void changeSubDeviceParent(String deviceSn, String gatewaySn) { + List gatewaysList = deviceService.getDevicesByParams( + DeviceQueryParam.builder() + .childSn(deviceSn) + .build()); + gatewaysList.stream() + .filter(gateway -> !gateway.getDeviceSn().equals(gatewaySn)) + .forEach(gateway -> { + gateway.setChildDeviceSn(""); + deviceService.updateDevice(gateway); + deviceRedisService.getDeviceOnline(gateway.getDeviceSn()) + .ifPresent(device -> { + device.setChildDeviceSn(null); + deviceRedisService.setDeviceOnline(device); + }); + }); + } + + + public void deviceOnlineAgain(String workspaceId, String gatewaySn, String deviceSn) { + DeviceDTO device = DeviceDTO.builder().loginTime(LocalDateTime.now()).deviceSn(deviceSn).build(); + DeviceDTO gateway = DeviceDTO.builder() + .loginTime(LocalDateTime.now()) + .deviceSn(gatewaySn) + .childDeviceSn(deviceSn).build(); + deviceService.updateDevice(gateway); + deviceService.updateDevice(device); + gateway = deviceRedisService.getDeviceOnline(gatewaySn).map(g -> { + g.setChildDeviceSn(deviceSn); + return g; + }).get(); + device = deviceRedisService.getDeviceOnline(deviceSn).map(d -> { + d.setParentSn(gatewaySn); + return d; + }).get(); + deviceRedisService.setDeviceOnline(gateway); + deviceRedisService.setDeviceOnline(device); + if (StringUtils.hasText(workspaceId)) { + deviceService.subDeviceOnlineSubscribeTopic(SDKManager.getDeviceSDK(gatewaySn)); + } + + log.warn("{} 已联机。", deviceSn); + } + + /** + * Convert the received gateway device object into a database entity object. + * @param gateway + * @return + */ + private DeviceDTO deviceGatewayConvertToDevice(String gatewaySn, UpdateTopo gateway) { + if (null == gateway) { + throw new IllegalArgumentException(); + } + return DeviceDTO.builder() + .deviceSn(gatewaySn) + .subType(gateway.getSubType()) + .type(gateway.getType()) + .thingVersion(gateway.getThingVersion()) + .domain(gateway.getDomain()) + .controlSource(gateway.getSubDevices().isEmpty() ? null : + ControlSourceEnum.find(gateway.getSubDevices().get(0).getIndex().getControlSource())) + .build(); + } + + /** + * Convert the received drone device object into a database entity object. + * @param device + * @return + */ + private DeviceDTO subDeviceConvertToDevice(UpdateTopoSubDevice device) { + if (null == device) { + throw new IllegalArgumentException(); + } + return DeviceDTO.builder() + .deviceSn(device.getSn()) + .type(device.getType()) + .subType(device.getSubType()) + .thingVersion(device.getThingVersion()) + .domain(device.getDomain()) + .build(); + } + + private Optional onlineSaveDevice(DeviceDTO device, String childSn, String parentSn) { + + device.setChildDeviceSn(childSn); + device.setLoginTime(LocalDateTime.now()); + + Optional deviceOpt = deviceService.getDeviceBySn(device.getDeviceSn()); + + if (deviceOpt.isEmpty()) { + device.setIconUrl(new DeviceIconUrl()); + // Set the icon of the gateway device displayed in the pilot's map, required in the TSA module. + device.getIconUrl().setNormalIconUrl(IconUrlEnum.NORMAL_PERSON.getUrl()); + // Set the icon of the gateway device displayed in the pilot's map when it is selected, required in the TSA module. + device.getIconUrl().setSelectIconUrl(IconUrlEnum.SELECT_PERSON.getUrl()); + device.setBoundStatus(false); + + // Query the model information of this gateway device. + dictionaryService.getOneDictionaryInfoByTypeSubType( + device.getDomain().getDomain(), device.getType().getType(), device.getSubType().getSubType()) + .ifPresent(entity -> { + device.setDeviceName(entity.getDeviceName()); + device.setNickname(entity.getDeviceName()); + device.setDeviceDesc(entity.getDeviceDesc()); + }); + } + boolean success = deviceService.saveOrUpdateDevice(device); + if (!success) { + return Optional.empty(); + } + + deviceOpt = deviceService.getDeviceBySn(device.getDeviceSn()); + DeviceDTO redisDevice = deviceOpt.get(); + redisDevice.setStatus(true); + redisDevice.setParentSn(parentSn); + + deviceRedisService.setDeviceOnline(redisDevice); + return deviceOpt; + } + + private void fillDockOsd(String dockSn, OsdDock dock) { + Optional oldDockOpt = deviceRedisService.getDeviceOsd(dockSn, OsdDock.class); + if (Objects.nonNull(dock.getJobNumber())) { + return; + } + if (oldDockOpt.isEmpty()) { + deviceRedisService.setDeviceOsd(dockSn, dock); + return; + } + OsdDock oldDock = oldDockOpt.get(); + if (Objects.nonNull(dock.getModeCode())) { + dock.setDrcState(oldDock.getDrcState()); + deviceRedisService.setDeviceOsd(dockSn, dock); + return; + } + if (Objects.nonNull(dock.getDrcState()) ) { + oldDock.setDrcState(dock.getDrcState()); + deviceRedisService.setDeviceOsd(dockSn, oldDock); + } + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKLivestreamService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKLivestreamService.java new file mode 100644 index 0000000..d19e61d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKLivestreamService.java @@ -0,0 +1,49 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.manage.model.receiver.CapacityDeviceReceiver; +import com.dji.sample.manage.service.ICapacityCameraService; +import com.dji.sdk.cloudapi.livestream.DockLivestreamAbilityUpdate; +import com.dji.sdk.cloudapi.livestream.RcLivestreamAbilityUpdate; +import com.dji.sdk.cloudapi.livestream.api.AbstractLivestreamService; +import com.dji.sdk.mqtt.state.TopicStateRequest; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/6 + */ +@Service +public class SDKLivestreamService extends AbstractLivestreamService { + + @Autowired + private ICapacityCameraService capacityCameraService; + + @Autowired + private ObjectMapper objectMapper; + + @Override + public void dockLivestreamAbilityUpdate(TopicStateRequest request, MessageHeaders headers) { + saveLiveCapacity(request.getData().getLiveCapacity().getDeviceList()); + } + + @Override + public void rcLivestreamAbilityUpdate(TopicStateRequest request, MessageHeaders headers) { + saveLiveCapacity(request.getData().getLiveCapacity().getDeviceList()); + } + + private void saveLiveCapacity(Object data) { + List devices = objectMapper.convertValue( + data, new TypeReference>() {}); + for (CapacityDeviceReceiver capacityDeviceReceiver : devices) { + capacityCameraService.saveCapacityCameraReceiverList( + capacityDeviceReceiver.getCameraList(), capacityDeviceReceiver.getSn()); + } + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKLogService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKLogService.java new file mode 100644 index 0000000..7edd96e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKLogService.java @@ -0,0 +1,14 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sdk.cloudapi.log.api.AbstractLogService; +import org.springframework.stereotype.Service; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/6 + */ +@Service +public class SDKLogService extends AbstractLogService { + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKOrganizationService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKOrganizationService.java new file mode 100644 index 0000000..5d019f4 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKOrganizationService.java @@ -0,0 +1,177 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.dto.DeviceDictionaryDTO; +import com.dji.sample.manage.model.dto.WorkspaceDTO; +import com.dji.sample.manage.service.IDeviceDictionaryService; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sample.manage.service.IWorkspaceService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.dji.sdk.cloudapi.organization.*; +import com.dji.sdk.cloudapi.organization.api.AbstractOrganizationService; +import com.dji.sdk.cloudapi.tsa.DeviceIconUrl; +import com.dji.sdk.cloudapi.tsa.IconUrlEnum; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/7 + */ +@Service +public class SDKOrganizationService extends AbstractOrganizationService { + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IDeviceDictionaryService dictionaryService; + + @Autowired + private IWorkspaceService workspaceService; + + @Override + public TopicRequestsResponse> airportBindStatus(TopicRequestsRequest request, MessageHeaders headers) { + List data = request.getData().getDevices(); + + List bindStatusResult = new ArrayList<>(); + for (BindStatusResponseDevice bindStatus : data) { + Optional deviceOpt = deviceService.getDeviceBySn(bindStatus.getSn()); + bindStatusResult.add(deviceOpt.isPresent() ? dto2BindStatus(deviceOpt.get()) : + new BindStatusRequestDevice().setSn(bindStatus.getSn()).setDeviceBindOrganization(false)); + } + return new TopicRequestsResponse>() + .setData(MqttReply.success(new AirportBindStatusResponse().setBindStatus(bindStatusResult))); + } + + @Override + public TopicRequestsResponse> airportOrganizationGet(TopicRequestsRequest request, MessageHeaders headers) { + AirportOrganizationGetRequest organizationGet = request.getData(); + if (!StringUtils.hasText(organizationGet.getDeviceBindingCode())) { + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); + } + + Optional workspace = workspaceService.getWorkspaceNameByBindCode(organizationGet.getDeviceBindingCode()); + if (workspace.isEmpty()) { + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.GET_ORGANIZATION_FAILED)); + } + + return new TopicRequestsResponse>() + .setData(MqttReply.success(new AirportOrganizationGetResponse() + .setOrganizationName(workspace.get().getWorkspaceName()))); + } + + @Override + public TopicRequestsResponse> airportOrganizationBind(TopicRequestsRequest request, MessageHeaders headers) { + List devices = request.getData().getBindDevices(); + OrganizationBindDevice dock = null; + OrganizationBindDevice drone = null; + for (OrganizationBindDevice device : devices) { + DeviceDomainEnum val = device.getDeviceModelKey().getDomain(); + if (val == DeviceDomainEnum.DOCK) { + dock = device; + } + if (val == DeviceDomainEnum.DRONE) { + drone = device; + } + } + + Optional dockOpt = bindDevice2Dto(dock); + Optional droneOpt = bindDevice2Dto(drone); + List bindResult = new ArrayList<>(); + + droneOpt.ifPresent(droneDto -> { + dockOpt.get().setChildDeviceSn(droneDto.getDeviceSn()); + boolean success = deviceService.saveOrUpdateDevice(droneDto); + bindResult.add(success ? + OrganizationBindInfo.success(droneDto.getDeviceSn()) : + new OrganizationBindInfo(droneDto.getDeviceSn(), + CommonErrorEnum.DEVICE_BINDING_FAILED.getCode()) + ); + }); + boolean success = deviceService.saveOrUpdateDevice(dockOpt.get()); + + bindResult.add(success ? + OrganizationBindInfo.success(dock.getSn()) : + new OrganizationBindInfo(dock.getSn(), + CommonErrorEnum.DEVICE_BINDING_FAILED.getCode())); + + return new TopicRequestsResponse>() + .setData(MqttReply.success(new AirportOrganizationBindResponse().setErrInfos(bindResult))); + } + + /** + * Convert device binding data object into database entity object. + * + * @param receiver + * @return + */ + public Optional bindDevice2Dto(OrganizationBindDevice receiver) { + if (receiver == null) { + return Optional.empty(); + } + + DeviceEnum deviceModelKey = receiver.getDeviceModelKey(); + Optional dictionaryOpt = dictionaryService.getOneDictionaryInfoByTypeSubType( + deviceModelKey.getDomain().getDomain(), deviceModelKey.getType().getType(), + deviceModelKey.getSubType().getSubType()); + DeviceDTO.DeviceDTOBuilder builder = DeviceDTO.builder(); + + dictionaryOpt.ifPresent(entity -> + builder.deviceName(entity.getDeviceName()) + .nickname(entity.getDeviceName()) + .deviceDesc(entity.getDeviceDesc())); + Optional workspace = workspaceService.getWorkspaceNameByBindCode(receiver.getDeviceBindingCode()); + + DeviceDTO dto = builder + .workspaceId(workspace.map(WorkspaceDTO::getWorkspaceId).orElse(receiver.getOrganizationId())) + .domain(deviceModelKey.getDomain()) + .type(deviceModelKey.getType()) + .subType(deviceModelKey.getSubType()) + .deviceSn(receiver.getSn()) + .boundStatus(true) + .loginTime(LocalDateTime.now()) + .boundTime(LocalDateTime.now()) + .iconUrl(new DeviceIconUrl() + .setSelectIconUrl(IconUrlEnum.SELECT_EQUIPMENT.getUrl()) + .setNormalIconUrl(IconUrlEnum.NORMAL_EQUIPMENT.getUrl())) + .build(); + if (StringUtils.hasText(receiver.getDeviceCallsign())) { + dto.setNickname(receiver.getDeviceCallsign()); + } else { + Optional deviceOpt = deviceService.getDeviceBySn(receiver.getSn()); + dto.setNickname(deviceOpt.map(DeviceDTO::getNickname).orElse(dto.getNickname())); + } + return Optional.of(dto); + } + + /** + * Convert device data transfer object into device binding status data object. + * @param device + * @return + */ + private BindStatusRequestDevice dto2BindStatus(DeviceDTO device) { + if (device == null) { + return null; + } + return new BindStatusRequestDevice() + .setSn(device.getDeviceSn()) + .setDeviceCallsign(device.getNickname()) + .setDeviceBindOrganization(device.getBoundStatus()) + .setOrganizationId(device.getWorkspaceId()) + .setOrganizationName(device.getWorkspaceName()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKPropertySetService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKPropertySetService.java new file mode 100644 index 0000000..73ce404 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SDKPropertySetService.java @@ -0,0 +1,14 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sdk.cloudapi.property.api.AbstractPropertyService; +import org.springframework.stereotype.Service; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/6 + */ +@Service +public class SDKPropertySetService extends AbstractPropertyService { + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/TopologyServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/TopologyServiceImpl.java new file mode 100644 index 0000000..2a37485 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/TopologyServiceImpl.java @@ -0,0 +1,64 @@ +package com.dji.sample.manage.service.impl; + +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.dto.TopologyDeviceDTO; +import com.dji.sample.manage.model.param.DeviceQueryParam; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sample.manage.service.ITopologyService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.tsa.DeviceTopology; +import com.dji.sdk.cloudapi.tsa.TopologyList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/8 + */ +@Service +public class TopologyServiceImpl implements ITopologyService { + + @Autowired + private IDeviceService deviceService; + + @Override + public List getDeviceTopology(String workspaceId) { + // Query the information of all gateway devices in the workspace. + List gatewayList = deviceService.getDevicesByParams( + DeviceQueryParam.builder() + .workspaceId(workspaceId) + .domains(List.of(DeviceDomainEnum.REMOTER_CONTROL.getDomain())) + .build()); + + List topologyList = new ArrayList<>(); + + gatewayList.forEach(device -> this.getDeviceTopologyByGatewaySn(device.getDeviceSn()) + .ifPresent(topologyList::add)); + + return topologyList; + } + + public Optional getDeviceTopologyByGatewaySn(String gatewaySn) { + Optional dtoOptional = deviceService.getDeviceBySn(gatewaySn); + if (dtoOptional.isEmpty()) { + return Optional.empty(); + } + List parents = new ArrayList<>(); + DeviceDTO device = dtoOptional.get(); + DeviceTopology gateway = deviceService.deviceConvertToTopologyDTO(device); + parents.add(gateway); + + // Query the topology data of the drone based on the drone sn. + Optional deviceTopo = deviceService.getDeviceTopoForPilot(device.getChildDeviceSn()); + List deviceTopoList = new ArrayList<>(); + deviceTopo.ifPresent(deviceTopoList::add); + + return Optional.ofNullable(new TopologyList().setParents(parents).setHosts(deviceTopoList)); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/UserServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..76a14e6 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/UserServiceImpl.java @@ -0,0 +1,214 @@ +package com.dji.sample.manage.service.impl; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.exceptions.TokenExpiredException; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.common.util.JwtUtil; +import com.dji.sample.component.mqtt.config.MqttPropertyConfiguration; +import com.dji.sample.manage.dao.IUserMapper; +import com.dji.sample.manage.model.dto.UserDTO; +import com.dji.sample.manage.model.dto.UserListDTO; +import com.dji.sample.manage.model.dto.WorkspaceDTO; +import com.dji.sample.manage.model.entity.UserEntity; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.service.IUserService; +import com.dji.sample.manage.service.IWorkspaceService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +@Service +@Transactional +public class UserServiceImpl implements IUserService { + + @Autowired + private IUserMapper mapper; + + @Autowired + private MqttPropertyConfiguration mqttPropertyConfiguration; + + @Autowired + private IWorkspaceService workspaceService; + + @Override + public HttpResultResponse getUserByUsername(String username, String workspaceId) { + + UserEntity userEntity = this.getUserByUsername(username); + if (userEntity == null) { + return new HttpResultResponse() + .setCode(HttpStatus.UNAUTHORIZED.value()) + .setMessage("无效的用户名"); + } + + UserDTO user = this.entityConvertToDTO(userEntity); + user.setWorkspaceId(workspaceId); + + return HttpResultResponse.success(user); + } + + @Override + public HttpResultResponse userLogin(String username, String password, Integer flag) { + // check user + UserEntity userEntity = this.getUserByUsername(username); + if (userEntity == null) { + return new HttpResultResponse() + .setCode(HttpStatus.UNAUTHORIZED.value()) + .setMessage("无效的用户名"); + } + if (flag.intValue() != userEntity.getUserType().intValue()) { + return HttpResultResponse.error("帐户类型不匹配。"); + } + if (!password.equals(userEntity.getPassword())) { + return new HttpResultResponse() + .setCode(HttpStatus.UNAUTHORIZED.value()) + .setMessage("无效的口令"); + } + + Optional workspaceOpt = workspaceService.getWorkspaceByWorkspaceId(userEntity.getWorkspaceId()); + if (workspaceOpt.isEmpty()) { + return new HttpResultResponse() + .setCode(HttpStatus.UNAUTHORIZED.value()) + .setMessage("无效的工作区id"); + } + + CustomClaim customClaim = new CustomClaim(userEntity.getUserId(), + userEntity.getUsername(), userEntity.getUserType(), + workspaceOpt.get().getWorkspaceId()); + + // create token + String token = JwtUtil.createToken(customClaim.convertToMap()); + + UserDTO userDTO = entityConvertToDTO(userEntity); + userDTO.setMqttAddr(MqttPropertyConfiguration.getBasicMqttAddress()); + userDTO.setAccessToken(token); + userDTO.setWorkspaceId(workspaceOpt.get().getWorkspaceId()); + return HttpResultResponse.success(userDTO); + } + + @Override + public Optional refreshToken(String token) { + if (!StringUtils.hasText(token)) { + return Optional.empty(); + } + CustomClaim customClaim; + try { + DecodedJWT jwt = JwtUtil.verifyToken(token); + customClaim = new CustomClaim(jwt.getClaims()); + } catch (TokenExpiredException e) { + customClaim = new CustomClaim(JWT.decode(token).getClaims()); + } catch (Exception e) { + e.printStackTrace(); + return Optional.empty(); + } + String refreshToken = JwtUtil.createToken(customClaim.convertToMap()); + + UserDTO user = entityConvertToDTO(this.getUserByUsername(customClaim.getUsername())); + if (Objects.isNull(user)) { + return Optional.empty(); + } + user.setWorkspaceId(customClaim.getWorkspaceId()); + user.setAccessToken(refreshToken); + return Optional.of(user); + } + + @Override + public PaginationData getUsersByWorkspaceId(long page, long pageSize, String workspaceId) { + Page userEntityPage = mapper.selectPage( + new Page<>(page, pageSize), + new LambdaQueryWrapper().eq(UserEntity::getWorkspaceId, workspaceId)); + + List usersList = userEntityPage.getRecords() + .stream() + .map(this::entity2UserListDTO) + .collect(Collectors.toList()); + return new PaginationData<>(usersList, new Pagination(userEntityPage.getCurrent(), userEntityPage.getSize(), userEntityPage.getTotal())); + } + + @Override + public Boolean updateUser(String workspaceId, String userId, UserListDTO user) { + UserEntity userEntity = mapper.selectOne( + new LambdaQueryWrapper() + .eq(UserEntity::getUserId, userId) + .eq(UserEntity::getWorkspaceId, workspaceId)); + if (userEntity == null) { + return false; + } + userEntity.setMqttUsername(user.getMqttUsername()); + userEntity.setMqttPassword(user.getMqttPassword()); + userEntity.setUpdateTime(System.currentTimeMillis()); + int id = mapper.update(userEntity, new LambdaUpdateWrapper() + .eq(UserEntity::getUserId, userId) + .eq(UserEntity::getWorkspaceId, workspaceId)); + + return id > 0; + } + + /** + * Convert database entity objects into user data transfer object. + * @param entity + * @return + */ + private UserListDTO entity2UserListDTO(UserEntity entity) { + UserListDTO.UserListDTOBuilder builder = UserListDTO.builder(); + if (entity != null) { + builder.userId(entity.getUserId()) + .username(entity.getUsername()) + .mqttUsername(entity.getMqttUsername()) + .mqttPassword(entity.getMqttPassword()) + .userType(UserTypeEnum.find(entity.getUserType()).getDesc()) + .createTime(LocalDateTime.ofInstant( + Instant.ofEpochMilli(entity.getCreateTime()), ZoneId.systemDefault())); + Optional workspaceOpt = workspaceService.getWorkspaceByWorkspaceId(entity.getWorkspaceId()); + workspaceOpt.ifPresent(workspace -> builder.workspaceName(workspace.getWorkspaceName())); + } + + return builder.build(); + } + + /** + * Query a user by username. + * @param username + * @return + */ + private UserEntity getUserByUsername(String username) { + return mapper.selectOne(new QueryWrapper() + .eq("username", username)); + } + + /** + * Convert database entity objects into user data transfer object. + * @param entity + * @return + */ + private UserDTO entityConvertToDTO(UserEntity entity) { + if (entity == null) { + return null; + } + return UserDTO.builder() + .userId(entity.getUserId()) + .username(entity.getUsername()) + .userType(entity.getUserType()) + .mqttUsername(entity.getMqttUsername()) + .mqttPassword(entity.getMqttPassword()) + .mqttAddr(MqttPropertyConfiguration.getBasicMqttAddress()) + .build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/WorkspaceServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/WorkspaceServiceImpl.java new file mode 100644 index 0000000..ff492b2 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/WorkspaceServiceImpl.java @@ -0,0 +1,57 @@ +package com.dji.sample.manage.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.dji.sample.manage.dao.IWorkspaceMapper; +import com.dji.sample.manage.model.dto.WorkspaceDTO; +import com.dji.sample.manage.model.entity.WorkspaceEntity; +import com.dji.sample.manage.service.IWorkspaceService; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +@Service +@Transactional +public class WorkspaceServiceImpl implements IWorkspaceService { + + @Autowired + private IWorkspaceMapper mapper; + + @Autowired + private ObjectMapper objectMapper; + + @Override + public Optional getWorkspaceByWorkspaceId(String workspaceId) { + return Optional.ofNullable(entityConvertToDto( + mapper.selectOne( + new LambdaQueryWrapper() + .eq(WorkspaceEntity::getWorkspaceId, workspaceId)))); + } + + @Override + public Optional getWorkspaceNameByBindCode(String bindCode) { + return Optional.ofNullable(entityConvertToDto( + mapper.selectOne(new LambdaQueryWrapper().eq(WorkspaceEntity::getBindCode, bindCode)))); + } + + /** + * Convert database entity objects into workspace data transfer object. + * @param entity + * @return + */ + private WorkspaceDTO entityConvertToDto(WorkspaceEntity entity) { + if (entity == null) { + return null; + } + return WorkspaceDTO.builder() + .id(entity.getId()) + .workspaceId(entity.getWorkspaceId()) + .platformName(entity.getPlatformName()) + .workspaceDesc(entity.getWorkspaceDesc()) + .workspaceName(entity.getWorkspaceName()) + .bindCode(entity.getBindCode()) + .build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/controller/DeviceDataController.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/controller/DeviceDataController.java new file mode 100644 index 0000000..d1ed19d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/controller/DeviceDataController.java @@ -0,0 +1,31 @@ +package com.dji.sample.map.controller; + +import com.dji.sample.map.model.dto.DeviceDataStatusDTO; +import com.dji.sample.map.service.IDeviceDataService; +import com.dji.sdk.common.HttpResultResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/24 + */ + +@RestController +@RequestMapping("${url.map.prefix}${url.map.version}/workspaces") +public class DeviceDataController { + + @Autowired + private IDeviceDataService deviceDataService; + + @GetMapping("/{workspace_id}/device-status") + public HttpResultResponse> getDeviceFlightAreaStatus(@PathVariable(name = "workspace_id") String workspaceId) { + return HttpResultResponse.success(deviceDataService.getDevicesDataStatus(workspaceId)); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/controller/FlightAreaController.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/controller/FlightAreaController.java new file mode 100644 index 0000000..2bda1a7 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/controller/FlightAreaController.java @@ -0,0 +1,66 @@ +package com.dji.sample.map.controller; + +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.map.model.dto.FlightAreaDTO; +import com.dji.sample.map.model.param.PostFlightAreaParam; +import com.dji.sample.map.model.param.PutFlightAreaParam; +import com.dji.sample.map.model.param.SyncFlightAreaParam; +import com.dji.sample.map.service.IFlightAreaService; +import com.dji.sdk.common.HttpResultResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; + +import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +@RestController +@RequestMapping("${url.map.prefix}${url.map.version}/workspaces") +public class FlightAreaController { + + @Autowired + private IFlightAreaService flightAreaService; + + @GetMapping("/{workspace_id}/flight-areas") + public HttpResultResponse> getFlightAreas(@PathVariable(name = "workspace_id") String workspaceId) { + return HttpResultResponse.success(flightAreaService.getFlightAreaList(workspaceId)); + } + + @PostMapping("/{workspace_id}/flight-area") + public HttpResultResponse createFlightArea(@PathVariable(name = "workspace_id") String workspaceId, + @Valid @RequestBody PostFlightAreaParam param, HttpServletRequest req) { + CustomClaim claims = (CustomClaim) req.getAttribute(TOKEN_CLAIM); + flightAreaService.createFlightArea(workspaceId, claims.getUsername(), param); + return HttpResultResponse.success(); + } + + @DeleteMapping("/{workspace_id}/flight-area/{area_id}") + public HttpResultResponse deleteFlightArea(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "area_id") String areaId) { + flightAreaService.deleteFlightArea(workspaceId, areaId); + return HttpResultResponse.success(); + } + + @PutMapping("/{workspace_id}/flight-area/{area_id}") + public HttpResultResponse updateFlightArea(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "area_id") String areaId, + @RequestBody PutFlightAreaParam param) { + flightAreaService.updateFlightArea(workspaceId, areaId, param); + return HttpResultResponse.success(); + } + + @PostMapping("/{workspace_id}/flight-area/sync") + public HttpResultResponse syncFlightArea(@PathVariable(name = "workspace_id") String workspaceId, + @RequestBody @Valid SyncFlightAreaParam param) { + flightAreaService.syncFlightArea(workspaceId, param.getDeviceSns()); + return HttpResultResponse.success(); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/controller/WorkspaceElementController.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/controller/WorkspaceElementController.java new file mode 100644 index 0000000..4afc12d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/controller/WorkspaceElementController.java @@ -0,0 +1,121 @@ +package com.dji.sample.map.controller; + +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.map.service.IWorkspaceElementService; +import com.dji.sdk.cloudapi.map.CreateMapElementRequest; +import com.dji.sdk.cloudapi.map.CreateMapElementResponse; +import com.dji.sdk.cloudapi.map.GetMapElementsResponse; +import com.dji.sdk.cloudapi.map.UpdateMapElementRequest; +import com.dji.sdk.cloudapi.map.api.IHttpMapService; +import com.dji.sdk.common.HttpResultResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.List; + +import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@RestController +public class WorkspaceElementController implements IHttpMapService { + + @Autowired + private IWorkspaceElementService elementService; + + @Autowired + private IWebSocketMessageService sendMessageService; + + /** + * Delete all the element information in this group based on the group id. + * @param workspaceId + * @param groupId + * @return + */ + @DeleteMapping("${url.map.prefix}${url.map.version}/workspaces/{workspace_id}/element-groups/{group_id}/elements") + public HttpResultResponse deleteAllElementByGroupId(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "group_id") String groupId) { + + return elementService.deleteAllElementByGroupId(workspaceId, groupId); + } + + /** + * In the first connection, pilot will send out this http request to obtain the group element list. + * Also, if pilot receives a group refresh instruction from WebSocket, + * it needs the same interface to request the group element list. + * @param workspaceId + * @param groupId + * @param isDistributed + * @return + */ + @Override + public HttpResultResponse> getMapElements(String workspaceId, String groupId, Boolean isDistributed, HttpServletRequest req, HttpServletResponse rsp) { + List groupsList = elementService.getAllGroupsByWorkspaceId(workspaceId, groupId, isDistributed); + return HttpResultResponse.>success(groupsList); + } + + /** + * When user draws a point, line or polygon on the PILOT/Web side. + * Save the element information to the database. + * @param workspaceId + * @param groupId + * @param elementCreate + * @return + */ + @Override + public HttpResultResponse createMapElement(String workspaceId, String groupId, + @Valid CreateMapElementRequest elementCreate, HttpServletRequest req, HttpServletResponse rsp) { + CustomClaim claims = (CustomClaim) req.getAttribute(TOKEN_CLAIM); + // Set the creator of the element + elementCreate.getResource().setUsername(claims.getUsername()); + + HttpResultResponse response = elementService.saveElement(workspaceId, groupId, elementCreate, true); + if (response.getCode() != HttpResultResponse.CODE_SUCCESS) { + return response; + } + + return HttpResultResponse.success(new CreateMapElementResponse().setId(elementCreate.getId())); + } + + /** + * When user edits a point, line or polygon on the PILOT/Web side. + * Update the element information to the database. + * @param workspaceId + * @param elementId + * @param elementUpdate + * @return + */ + @Override + public HttpResultResponse updateMapElement(String workspaceId, String elementId, @Valid UpdateMapElementRequest elementUpdate, HttpServletRequest req, HttpServletResponse rsp) { + CustomClaim claims = (CustomClaim) req.getAttribute(TOKEN_CLAIM); + + HttpResultResponse response = elementService.updateElement(workspaceId, elementId, elementUpdate, claims.getUsername(), true); + if (response.getCode() != HttpResultResponse.CODE_SUCCESS) { + return response; + } + + return response; + } + + /** + * When user delete a point, line or polygon on the PILOT/Web side, + * Delete the element information in the database. + * @param workspaceId + * @param elementId + * @return + */ + @Override + public HttpResultResponse deleteMapElement(String workspaceId, String elementId, HttpServletRequest req, HttpServletResponse rsp) { + + return elementService.deleteElement(workspaceId, elementId, true); + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IDeviceFlightAreaMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IDeviceFlightAreaMapper.java new file mode 100644 index 0000000..6d39cd9 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IDeviceFlightAreaMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.map.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.map.model.entity.DeviceFlightAreaEntity; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/23 + */ +public interface IDeviceFlightAreaMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IElementCoordinateMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IElementCoordinateMapper.java new file mode 100644 index 0000000..5073ce5 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IElementCoordinateMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.map.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.map.model.entity.ElementCoordinateEntity; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +public interface IElementCoordinateMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IFlightAreaFileMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IFlightAreaFileMapper.java new file mode 100644 index 0000000..7091605 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IFlightAreaFileMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.map.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.map.model.entity.FlightAreaFileEntity; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +public interface IFlightAreaFileMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IFlightAreaPropertyMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IFlightAreaPropertyMapper.java new file mode 100644 index 0000000..4085562 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IFlightAreaPropertyMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.map.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.map.model.entity.FlightAreaPropertyEntity; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +public interface IFlightAreaPropertyMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IGroupElementMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IGroupElementMapper.java new file mode 100644 index 0000000..4b572c7 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IGroupElementMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.map.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.map.model.entity.GroupElementEntity; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +public interface IGroupElementMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IGroupMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IGroupMapper.java new file mode 100644 index 0000000..747f7fd --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/dao/IGroupMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.map.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.map.model.entity.GroupEntity; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +public interface IGroupMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/DeviceDataStatusDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/DeviceDataStatusDTO.java new file mode 100644 index 0000000..7604092 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/DeviceDataStatusDTO.java @@ -0,0 +1,28 @@ +package com.dji.sample.map.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/24 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DeviceDataStatusDTO { + + private String deviceSn; + + private String nickname; + + private String deviceName; + + private Boolean online; + + private DeviceFlightAreaDTO flightAreaStatus; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/DeviceFlightAreaDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/DeviceFlightAreaDTO.java new file mode 100644 index 0000000..16e1ca3 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/DeviceFlightAreaDTO.java @@ -0,0 +1,32 @@ +package com.dji.sample.map.model.dto; + +import com.dji.sdk.cloudapi.flightarea.FlightAreaSyncReasonEnum; +import com.dji.sdk.cloudapi.flightarea.FlightAreaSyncStatusEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/23 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DeviceFlightAreaDTO { + + private String deviceSn; + + private String workspaceId; + + private String fileId; + + private FlightAreaSyncStatusEnum syncStatus; + + private FlightAreaSyncReasonEnum syncCode; + + private String syncMsg; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaContent.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaContent.java new file mode 100644 index 0000000..6c93e5f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaContent.java @@ -0,0 +1,32 @@ +package com.dji.sample.map.model.dto; + +import com.dji.sdk.cloudapi.map.ElementGeometryType; +import com.dji.sdk.cloudapi.map.ElementProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class FlightAreaContent { + + @NotNull + @Valid + private ElementProperty properties; + + @NotNull + @Valid + private ElementGeometryType geometry; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaDTO.java new file mode 100644 index 0000000..d5d7219 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaDTO.java @@ -0,0 +1,35 @@ +package com.dji.sample.map.model.dto; + +import com.dji.sdk.cloudapi.flightarea.GeofenceTypeEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class FlightAreaDTO { + + private String areaId; + + private String name; + + private GeofenceTypeEnum type; + + private FlightAreaContent content; + + private Boolean status; + + private String username; + + private Long createTime; + + private Long updateTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaFileDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaFileDTO.java new file mode 100644 index 0000000..4138bbd --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaFileDTO.java @@ -0,0 +1,32 @@ +package com.dji.sample.map.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/23 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class FlightAreaFileDTO { + + private String fileId; + + private String workspaceId; + + private String name; + + private String objectKey; + + private String sign; + + private Integer size; + + private Boolean latest; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaNotifyDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaNotifyDTO.java new file mode 100644 index 0000000..bf3023b --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaNotifyDTO.java @@ -0,0 +1,26 @@ +package com.dji.sample.map.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/5 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FlightAreaNotifyDTO { + + private String sn; + + private Integer result; + + private String status; + + private String message; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaPropertyDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaPropertyDTO.java new file mode 100644 index 0000000..1edcc21 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaPropertyDTO.java @@ -0,0 +1,30 @@ +package com.dji.sample.map.model.dto; + +import com.dji.sdk.cloudapi.flightarea.GeofenceTypeEnum; +import com.dji.sdk.cloudapi.flightarea.GeometrySubTypeEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class FlightAreaPropertyDTO { + + private String elementId; + + private Boolean status; + + private GeofenceTypeEnum type; + + private Float radius; + + private GeometrySubTypeEnum subType; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaPropertyUpdate.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaPropertyUpdate.java new file mode 100644 index 0000000..8a30d2e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaPropertyUpdate.java @@ -0,0 +1,25 @@ +package com.dji.sample.map.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class FlightAreaPropertyUpdate { + + private String elementId; + + private Boolean status; + + private Float radius; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaWs.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaWs.java new file mode 100644 index 0000000..99d7cd7 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/FlightAreaWs.java @@ -0,0 +1,36 @@ +package com.dji.sample.map.model.dto; + +import com.dji.sample.map.model.enums.FlightAreaOpertaionEnum; +import com.dji.sdk.cloudapi.flightarea.GeofenceTypeEnum; +import lombok.*; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/1 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Builder +public class FlightAreaWs { + + private FlightAreaOpertaionEnum operation; + + private String areaId; + + private String name; + + private GeofenceTypeEnum type; + + private FlightAreaContent content; + + private Boolean status; + + private String username; + + private Long createTime; + + private Long updateTime; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/GroupElementDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/GroupElementDTO.java new file mode 100644 index 0000000..70ff1e4 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/dto/GroupElementDTO.java @@ -0,0 +1,38 @@ +package com.dji.sample.map.model.dto; + +import com.dji.sdk.cloudapi.map.ElementResource; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@JsonInclude(JsonInclude.Include.NON_NULL) +public class GroupElementDTO { + + @JsonProperty("id") + private String elementId; + + private String name; + + @JsonProperty(value = "create_time") + private Long createTime; + + @JsonProperty(value = "update_time") + private Long updateTime; + + private ElementResource resource; + + @JsonProperty("group_id") + private String groupId; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/DeviceFlightAreaEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/DeviceFlightAreaEntity.java new file mode 100644 index 0000000..9d239c0 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/DeviceFlightAreaEntity.java @@ -0,0 +1,46 @@ +package com.dji.sample.map.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/23 + */ +@TableName("device_flight_area") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DeviceFlightAreaEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField("device_sn") + private String deviceSn; + + @TableField("workspace_id") + private String workspaceId; + + @TableField("file_id") + private String fileId; + + @TableField("sync_status") + private String syncStatus; + + @TableField("sync_code") + private Integer syncCode; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/ElementCoordinateEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/ElementCoordinateEntity.java new file mode 100644 index 0000000..26d2732 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/ElementCoordinateEntity.java @@ -0,0 +1,41 @@ +package com.dji.sample.map.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName(value = "map_element_coordinate") +public class ElementCoordinateEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField("element_id") + private String elementId; + + @TableField("longitude") + private Double longitude; + + @TableField("latitude") + private Double latitude; + + @TableField("altitude") + private Double altitude; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/FlightAreaFileEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/FlightAreaFileEntity.java new file mode 100644 index 0000000..0f8c33a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/FlightAreaFileEntity.java @@ -0,0 +1,52 @@ +package com.dji.sample.map.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@TableName("flight_area_file") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FlightAreaFileEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField("file_id") + private String fileId; + + @TableField("workspace_id") + private String workspaceId; + + @TableField("name") + private String name; + + @TableField("object_key") + private String objectKey; + + @TableField("sign") + private String sign; + + @TableField("size") + private Integer size; + + @TableField("latest") + private Boolean latest; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/FlightAreaPropertyEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/FlightAreaPropertyEntity.java new file mode 100644 index 0000000..227d403 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/FlightAreaPropertyEntity.java @@ -0,0 +1,41 @@ +package com.dji.sample.map.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/21 + */ +@TableName("flight_area_property") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FlightAreaPropertyEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField("element_id") + private String elementId; + + @TableField("type") + private String type; + + @TableField("enable") + private Boolean enable; + + @TableField("sub_type") + private String subType; + + @TableField("radius") + private Integer radius; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/GroupElementEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/GroupElementEntity.java new file mode 100644 index 0000000..7c6748a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/GroupElementEntity.java @@ -0,0 +1,55 @@ +package com.dji.sample.map.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName(value = "map_group_element") +public class GroupElementEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField("group_id") + private String groupId; + + @TableField("element_id") + private String elementId; + + @TableField("element_name") + private String elementName; + + @TableField("display") + private Integer display; + + @TableField("element_type") + private Integer elementType; + + @TableField("username") + private String username; + + @TableField("color") + private String color; + + @TableField("clamp_to_ground") + private Boolean clampToGround; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/GroupEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/GroupEntity.java new file mode 100644 index 0000000..c639a9b --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/entity/GroupEntity.java @@ -0,0 +1,49 @@ +package com.dji.sample.map.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName(value = "map_group") +public class GroupEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField("group_id") + private String groupId; + + @TableField("group_name") + private String groupName; + + @TableField("group_type") + private Integer groupType; + + @TableField("workspace_id") + private String workspaceId; + + @TableField("is_distributed") + private Boolean isDistributed; + + @TableField("is_lock") + private Boolean isLock; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/enums/FlightAreaGeometryTypeEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/enums/FlightAreaGeometryTypeEnum.java new file mode 100644 index 0000000..4cfda0d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/enums/FlightAreaGeometryTypeEnum.java @@ -0,0 +1,37 @@ +package com.dji.sample.map.model.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/24 + */ +public enum FlightAreaGeometryTypeEnum { + + CIRCLE("Circle"), + + POLYGON("Polygon"), + + ; + + private final String type; + + FlightAreaGeometryTypeEnum(String type) { + this.type = type; + } + + @JsonValue + public String getType() { + return type; + } + + @JsonCreator + public static FlightAreaGeometryTypeEnum find(String type) { + return Arrays.stream(values()).filter(typeEnum -> typeEnum.type.equals(type)).findAny() + .orElseThrow(() -> new RuntimeException("This type(" + type + ") is not supported.")); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/enums/FlightAreaOpertaionEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/enums/FlightAreaOpertaionEnum.java new file mode 100644 index 0000000..0642182 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/enums/FlightAreaOpertaionEnum.java @@ -0,0 +1,39 @@ +package com.dji.sample.map.model.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.9 + * @date 2023/12/1 + */ +public enum FlightAreaOpertaionEnum { + + ADD("add"), + + UPDATE("update"), + + DELETE("delete") + + ; + + private final String operation; + + FlightAreaOpertaionEnum(String operation) { + this.operation = operation; + } + + @JsonValue + public String getOperation() { + return operation; + } + + @JsonCreator + public static FlightAreaOpertaionEnum find(String operation) { + return Arrays.stream(values()).filter(operationEnum -> operationEnum.operation.equals(operation)).findAny() + .orElseThrow(() -> new RuntimeException("This operation(" + operation + ") is not supported.")); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/param/PostFlightAreaParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/param/PostFlightAreaParam.java new file mode 100644 index 0000000..dbeae02 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/param/PostFlightAreaParam.java @@ -0,0 +1,30 @@ +package com.dji.sample.map.model.param; + +import com.dji.sample.map.model.dto.FlightAreaContent; +import com.dji.sdk.cloudapi.flightarea.GeofenceTypeEnum; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@Data +public class PostFlightAreaParam { + + @NotNull + private String id; + + @NotNull + private String name; + + @NotNull + private GeofenceTypeEnum type; + + @NotNull + @Valid + private FlightAreaContent content; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/param/PutFlightAreaParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/param/PutFlightAreaParam.java new file mode 100644 index 0000000..a1ab489 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/param/PutFlightAreaParam.java @@ -0,0 +1,20 @@ +package com.dji.sample.map.model.param; + +import com.dji.sample.map.model.dto.FlightAreaContent; +import lombok.Data; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@Data +public class PutFlightAreaParam { + + private String name; + + private FlightAreaContent content; + + private Boolean status; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/model/param/SyncFlightAreaParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/param/SyncFlightAreaParam.java new file mode 100644 index 0000000..c21b8fd --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/model/param/SyncFlightAreaParam.java @@ -0,0 +1,21 @@ +package com.dji.sample.map.model.param; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@Data +public class SyncFlightAreaParam { + + @NotNull + @JsonProperty("device_sn") + private List deviceSns; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IDeviceDataService.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IDeviceDataService.java new file mode 100644 index 0000000..c729ec9 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IDeviceDataService.java @@ -0,0 +1,19 @@ +package com.dji.sample.map.service; + +import com.dji.sample.map.model.dto.DeviceDataStatusDTO; +import com.dji.sample.map.model.dto.DeviceFlightAreaDTO; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/24 + */ +public interface IDeviceDataService { + + List getDevicesDataStatus(String workspaceId); + + Optional getDeviceStatus(String workspaceId, String deviceSn); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IDeviceFlightAreaService.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IDeviceFlightAreaService.java new file mode 100644 index 0000000..42cb625 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IDeviceFlightAreaService.java @@ -0,0 +1,19 @@ +package com.dji.sample.map.service; + +import com.dji.sample.map.model.dto.DeviceFlightAreaDTO; + +import java.util.Optional; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/23 + */ +public interface IDeviceFlightAreaService { + + Optional getDeviceFlightAreaByDevice(String workspaceId, String deviceSn); + + Boolean updateDeviceFile(DeviceFlightAreaDTO deviceFile); + + Boolean updateOrSaveDeviceFile(DeviceFlightAreaDTO deviceFile); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IElementCoordinateService.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IElementCoordinateService.java new file mode 100644 index 0000000..5764729 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IElementCoordinateService.java @@ -0,0 +1,35 @@ +package com.dji.sample.map.service; + +import com.dji.sdk.cloudapi.map.ElementCoordinate; + +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +public interface IElementCoordinateService { + + /** + * Query all the coordinates of the element according to its id. + * @param elementId + * @return + */ + List getCoordinateByElementId(String elementId); + + /** + * Save all the coordinate data of this element. + * @param coordinate + * @param elementId + * @return + */ + Boolean saveCoordinate(List coordinate, String elementId); + + /** + * Delete all the coordinates of the element according to its id. + * @param elementId + * @return + */ + Boolean deleteCoordinateByElementId(String elementId); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IFlightAreaFileService.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IFlightAreaFileService.java new file mode 100644 index 0000000..eb32a10 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IFlightAreaFileService.java @@ -0,0 +1,25 @@ +package com.dji.sample.map.service; + +import com.dji.sample.map.model.dto.FlightAreaDTO; +import com.dji.sample.map.model.dto.FlightAreaFileDTO; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +public interface IFlightAreaFileService { + + Optional getFlightAreaFileByFileId(String fileId); + + Integer saveFlightAreaFile(FlightAreaFileDTO file); + + Integer setNonLatestByWorkspaceId(String workspaceId); + + Optional getLatestByWorkspaceId(String workspaceId); + + FlightAreaFileDTO packageFlightAreaFile(String workspaceId, List flightAreas); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IFlightAreaPropertyServices.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IFlightAreaPropertyServices.java new file mode 100644 index 0000000..977cfdf --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IFlightAreaPropertyServices.java @@ -0,0 +1,22 @@ +package com.dji.sample.map.service; + +import com.dji.sample.map.model.dto.FlightAreaPropertyDTO; +import com.dji.sample.map.model.dto.FlightAreaPropertyUpdate; + +import java.util.List; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +public interface IFlightAreaPropertyServices { + + List getPropertyByElementIds(List elementIds); + + Integer saveProperty(FlightAreaPropertyDTO property); + + Integer deleteProperty(String elementId); + + Integer updateProperty(FlightAreaPropertyUpdate property); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IFlightAreaService.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IFlightAreaService.java new file mode 100644 index 0000000..8cd1dd8 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IFlightAreaService.java @@ -0,0 +1,32 @@ +package com.dji.sample.map.service; + +import com.dji.sample.map.model.dto.FlightAreaDTO; +import com.dji.sample.map.model.dto.FlightAreaFileDTO; +import com.dji.sample.map.model.param.PostFlightAreaParam; +import com.dji.sample.map.model.param.PutFlightAreaParam; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +public interface IFlightAreaService { + + Optional getFlightAreaByAreaId(String areaId); + + List getFlightAreaList(String workspaceId); + + void createFlightArea(String workspaceId, String username, PostFlightAreaParam param); + + void syncFlightArea(String workspaceId, List deviceSns); + + FlightAreaFileDTO packageFlightArea(String workspaceId); + + void deleteFlightArea(String workspaceId, String areaId); + + void updateFlightArea(String workspaceId, String areaId, PutFlightAreaParam param); + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IGroupElementService.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IGroupElementService.java new file mode 100644 index 0000000..47097aa --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IGroupElementService.java @@ -0,0 +1,55 @@ +package com.dji.sample.map.service; + +import com.dji.sample.map.model.dto.GroupElementDTO; +import com.dji.sdk.cloudapi.map.CreateMapElementRequest; +import com.dji.sdk.cloudapi.map.MapGroupElement; +import com.dji.sdk.cloudapi.map.UpdateMapElementRequest; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +public interface IGroupElementService { + + /** + * Query all the elements in this group based on the group id. + * @param groupId + * @return + */ + List getElementsByGroupId(String groupId); + + /** + * Save all the elements. + * @param groupId + * @param elementCreate + * @return + */ + Boolean saveElement(String groupId, CreateMapElementRequest elementCreate); + + /** + * Query the element information based on the element id and update element. + * @param elementId + * @param elementUpdate + * @param username + * @return + */ + Boolean updateElement(String elementId, UpdateMapElementRequest elementUpdate, String username); + + /** + * Delete the element based on the element id. + * @param elementId + * @return + */ + Boolean deleteElement(String elementId); + + /** + * Query an element based on the element id, including the coordinate information in the elements. + * @param elementId + * @return + */ + Optional getElementByElementId(String elementId); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IGroupService.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IGroupService.java new file mode 100644 index 0000000..9ff1170 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IGroupService.java @@ -0,0 +1,31 @@ +package com.dji.sample.map.service; + +import com.dji.sdk.cloudapi.map.GetMapElementsResponse; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +public interface IGroupService { + + /** + * Query all groups in the workspace based on the workspace's id. + * If the group id does not exist, do not add this filter condition. + * @param workspaceId + * @param groupId + * @param isDistributed Used to define if the group needs to be distributed. Default is true. + * @return + */ + List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed); + + /** + * Get the custom flight area group under this workspace. + * @param workspaceId + * @return + */ + Optional getCustomGroupByWorkspaceId(String workspaceId); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IWorkspaceElementService.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IWorkspaceElementService.java new file mode 100644 index 0000000..58f5fe9 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/IWorkspaceElementService.java @@ -0,0 +1,84 @@ +package com.dji.sample.map.service; + +import com.dji.sample.map.model.dto.GroupElementDTO; +import com.dji.sdk.cloudapi.map.*; +import com.dji.sdk.common.HttpResultResponse; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +public interface IWorkspaceElementService { + + /** + * Query all groups in the workspace based on the workspace's id, + * including the information of the elements in the group, and the coordinate information in the elements. + * @param workspaceId + * @param groupId + * @param isDistributed + * @return + */ + List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed); + + /** + * Save all the elements, including the information of the elements in the group, + * and the coordinate information in the elements. + * + * @param workspaceId + * @param groupId + * @param elementCreate + * @param notify + * @return + */ + HttpResultResponse saveElement(String workspaceId, String groupId, CreateMapElementRequest elementCreate, boolean notify); + + /** + * Update the element information based on the element id, + * including the information of the elements in the group, and the coordinate information in the elements. + * + * @param workspaceId + * @param elementId + * @param elementUpdate + * @param username + * @param notify + * @return + */ + HttpResultResponse updateElement(String workspaceId, String elementId, UpdateMapElementRequest elementUpdate, String username, boolean notify); + + /** + * Delete the element information based on the element id, + * including the information of the elements in the group, and the coordinate information in the elements. + * + * @param workspaceId + * @param elementId + * @param notify + * @return + */ + HttpResultResponse deleteElement(String workspaceId, String elementId, boolean notify); + + /** + * Query an element based on the element id, + * including the information of the elements in the group, and the coordinate information in the elements. + * @param elementId + * @return + */ + Optional getElementByElementId(String elementId); + + /** + * Delete all the elements information based on the group id, + * including the information of the elements in the group, and the coordinate information in the elements. + * + * @param workspaceId + * @param groupId + * @return + */ + HttpResultResponse deleteAllElementByGroupId(String workspaceId, String groupId); + + MapElementCreateWsResponse element2CreateWsElement(GroupElementDTO element); + + MapElementUpdateWsResponse element2UpdateWsElement(GroupElementDTO element); +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/DeviceDataServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/DeviceDataServiceImpl.java new file mode 100644 index 0000000..ee591b3 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/DeviceDataServiceImpl.java @@ -0,0 +1,62 @@ +package com.dji.sample.map.service.impl; + +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.param.DeviceQueryParam; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sample.map.model.dto.DeviceDataStatusDTO; +import com.dji.sample.map.model.dto.DeviceFlightAreaDTO; +import com.dji.sample.map.service.IDeviceDataService; +import com.dji.sample.map.service.IDeviceFlightAreaService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/24 + */ +@Service +public class DeviceDataServiceImpl implements IDeviceDataService { + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private IDeviceFlightAreaService deviceFlightAreaService; + + @Override + public List getDevicesDataStatus(String workspaceId) { + List devices = deviceService.getDevicesByParams(DeviceQueryParam.builder() + .domains(List.of(DeviceDomainEnum.DOCK.getDomain())).workspaceId(workspaceId).build()); + if (CollectionUtils.isEmpty(devices)) { + throw new RuntimeException(CommonErrorEnum.ILLEGAL_ARGUMENT.getMessage()); + } + return devices.stream().map(device -> DeviceDataStatusDTO.builder() + .deviceName(device.getDeviceName()) + .deviceSn(device.getDeviceSn()) + .nickname(device.getNickname()) + .online(deviceRedisService.checkDeviceOnline(device.getDeviceSn())) + .flightAreaStatus(getDeviceStatus(workspaceId, device.getDeviceSn()).orElse(null)) + .build()) + .filter(device -> Objects.nonNull(device.getFlightAreaStatus())) + .collect(Collectors.toList()); + } + + @Override + public Optional getDeviceStatus(String workspaceId, String deviceSn) { + return deviceFlightAreaService.getDeviceFlightAreaByDevice(workspaceId, deviceSn) + .map(area -> DeviceFlightAreaDTO.builder().syncStatus(area.getSyncStatus()).syncCode(area.getSyncCode()).syncMsg(area.getSyncMsg()).build()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/DeviceFlightAreaServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/DeviceFlightAreaServiceImpl.java new file mode 100644 index 0000000..4ad5ece --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/DeviceFlightAreaServiceImpl.java @@ -0,0 +1,85 @@ +package com.dji.sample.map.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.dji.sample.map.dao.IDeviceFlightAreaMapper; +import com.dji.sample.map.model.dto.DeviceFlightAreaDTO; +import com.dji.sample.map.model.entity.DeviceFlightAreaEntity; +import com.dji.sample.map.service.IDeviceFlightAreaService; +import com.dji.sdk.cloudapi.flightarea.FlightAreaSyncReasonEnum; +import com.dji.sdk.cloudapi.flightarea.FlightAreaSyncStatusEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/23 + */ +@Service +@Transactional +public class DeviceFlightAreaServiceImpl implements IDeviceFlightAreaService { + + @Autowired + private IDeviceFlightAreaMapper mapper; + + @Override + public Optional getDeviceFlightAreaByDevice(String workspaceId, String deviceSn) { + return Optional.ofNullable(mapper.selectOne(Wrappers.lambdaQuery(DeviceFlightAreaEntity.class) + .eq(DeviceFlightAreaEntity::getWorkspaceId, workspaceId) + .eq(DeviceFlightAreaEntity::getDeviceSn, deviceSn))) + .map(this::entity2Dto); + } + + @Override + public Boolean updateDeviceFile(DeviceFlightAreaDTO deviceFile) { + return mapper.update(dto2Entity(deviceFile), + Wrappers.lambdaUpdate(DeviceFlightAreaEntity.class) + .eq(DeviceFlightAreaEntity::getWorkspaceId, deviceFile.getWorkspaceId()) + .eq(DeviceFlightAreaEntity::getDeviceSn, deviceFile.getDeviceSn())) > 0; + } + + @Override + public Boolean updateOrSaveDeviceFile(DeviceFlightAreaDTO deviceFile) { + if (getDeviceFlightAreaByDevice(deviceFile.getWorkspaceId(), deviceFile.getDeviceSn()).isPresent()) { + return updateDeviceFile(deviceFile); + } + DeviceFlightAreaEntity entity = dto2Entity(deviceFile); + entity.setFileId(UUID.randomUUID().toString()); + return mapper.insert(entity) > 0; + } + + private DeviceFlightAreaEntity dto2Entity(DeviceFlightAreaDTO dto) { + if (Objects.isNull(dto)) { + return null; + } + return DeviceFlightAreaEntity.builder() + .deviceSn(dto.getDeviceSn()) + .workspaceId(dto.getWorkspaceId()) + .fileId(dto.getFileId()) + .syncCode(dto.getSyncCode().getReason()) + .syncStatus(dto.getSyncStatus().getStatus()) + .build(); + } + + private DeviceFlightAreaDTO entity2Dto(DeviceFlightAreaEntity entity) { + if (Objects.isNull(entity)) { + return null; + } + FlightAreaSyncReasonEnum syncCodeEnum = FlightAreaSyncReasonEnum.find(entity.getSyncCode()); + return DeviceFlightAreaDTO.builder() + .deviceSn(entity.getDeviceSn()) + .workspaceId(entity.getWorkspaceId()) + .fileId(entity.getFileId()) + .syncCode(syncCodeEnum) + .syncStatus(FlightAreaSyncStatusEnum.find(entity.getSyncStatus())) + .syncMsg(syncCodeEnum.getMsg()) + .build(); + } + + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/ElementCoordinateServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/ElementCoordinateServiceImpl.java new file mode 100644 index 0000000..beff134 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/ElementCoordinateServiceImpl.java @@ -0,0 +1,91 @@ +package com.dji.sample.map.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.dji.sample.map.dao.IElementCoordinateMapper; +import com.dji.sample.map.model.entity.ElementCoordinateEntity; +import com.dji.sample.map.service.IElementCoordinateService; +import com.dji.sdk.cloudapi.map.ElementCoordinate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Service +@Transactional +public class ElementCoordinateServiceImpl implements IElementCoordinateService { + + @Autowired + private IElementCoordinateMapper mapper; + + @Override + public List getCoordinateByElementId(String elementId) { + return mapper.selectList( + new LambdaQueryWrapper() + .eq(ElementCoordinateEntity::getElementId, elementId)) + .stream() + .map(this::entityConvertToDto) + .collect(Collectors.toList()); + } + + @Override + public Boolean saveCoordinate(List coordinateList, String elementId) { + for (ElementCoordinate coordinate : coordinateList) { + ElementCoordinateEntity entity = this.dtoConvertToEntity(coordinate); + entity.setElementId(elementId); + + int insert = mapper.insert(entity); + if (insert <= 0) { + return false; + } + } + return true; + } + + @Override + public Boolean deleteCoordinateByElementId(String elementId) { + return mapper.delete(new LambdaUpdateWrapper() + .eq(ElementCoordinateEntity::getElementId, elementId)) > 0; + } + + /** + * Convert database entity objects into coordinate data transfer object. + * @param entity + * @return + */ + private ElementCoordinate entityConvertToDto(ElementCoordinateEntity entity) { + if (entity == null) { + return null; + } + + return new ElementCoordinate() + .setLongitude(entity.getLongitude()) + .setLatitude(entity.getLatitude()) + .setAltitude(entity.getAltitude()); + } + + /** + * Convert the received coordinate object into a database entity object. + * @param coordinate + * @return + */ + private ElementCoordinateEntity dtoConvertToEntity(ElementCoordinate coordinate) { + ElementCoordinateEntity.ElementCoordinateEntityBuilder builder = ElementCoordinateEntity.builder(); + if (coordinate == null) { + return builder.build(); + } + + return builder + .altitude(coordinate.getAltitude()) + .latitude(coordinate.getLatitude()) + .longitude(coordinate.getLongitude()) + .build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/FlightAreaFileServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/FlightAreaFileServiceImpl.java new file mode 100644 index 0000000..ed918ac --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/FlightAreaFileServiceImpl.java @@ -0,0 +1,184 @@ +package com.dji.sample.map.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.oss.service.impl.OssServiceContext; +import com.dji.sample.map.dao.IFlightAreaFileMapper; +import com.dji.sample.map.model.dto.FlightAreaDTO; +import com.dji.sample.map.model.dto.FlightAreaFileDTO; +import com.dji.sample.map.model.entity.FlightAreaFileEntity; +import com.dji.sample.map.service.IFlightAreaFileService; +import com.dji.sample.map.service.IFlightAreaPropertyServices; +import com.dji.sample.map.service.IGroupService; +import com.dji.sample.map.service.IWorkspaceElementService; +import com.dji.sdk.cloudapi.flightarea.*; +import com.dji.sdk.cloudapi.map.ElementCircleGeometry; +import com.dji.sdk.cloudapi.map.ElementPointGeometry; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@Service +@Transactional +public class FlightAreaFileServiceImpl implements IFlightAreaFileService { + + @Autowired + private IFlightAreaFileMapper mapper; + + @Autowired + private IWorkspaceElementService workspaceElementService; + + @Autowired + private IGroupService groupService; + + @Autowired + private OssServiceContext ossServiceContext; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private IFlightAreaPropertyServices flightAreaPropertyServices; + + @Override + public Optional getFlightAreaFileByFileId(String fileId) { + return Optional.ofNullable(mapper.selectOne(Wrappers.lambdaQuery(FlightAreaFileEntity.class) + .eq(FlightAreaFileEntity::getFileId, fileId))) + .map(this::entity2Dto); + } + + @Override + public Integer saveFlightAreaFile(FlightAreaFileDTO file) { + FlightAreaFileEntity entity = dto2Entity(file); + int id = mapper.insert(entity); + return id > 0 ? entity.getId() : id; + } + + @Override + public Integer setNonLatestByWorkspaceId(String workspaceId) { + return mapper.update(FlightAreaFileEntity.builder().latest(false).build(), + Wrappers.lambdaUpdate(FlightAreaFileEntity.class) + .eq(FlightAreaFileEntity::getWorkspaceId, workspaceId) + .eq(FlightAreaFileEntity::getLatest, true)); + } + + @Override + public Optional getLatestByWorkspaceId(String workspaceId) { + return Optional.ofNullable(mapper.selectOne(Wrappers.lambdaQuery(FlightAreaFileEntity.class) + .eq(FlightAreaFileEntity::getWorkspaceId, workspaceId) + .eq(FlightAreaFileEntity::getLatest, true) + .orderByDesc(FlightAreaFileEntity::getUpdateTime) + .last(" limit 1"))) + .map(this::entity2Dto); + } + + @Override + public FlightAreaFileDTO packageFlightAreaFile(String workspaceId, List flightAreas) { + Optional fileOpt = getLatestByWorkspaceId(workspaceId); + if (fileOpt.isPresent()) { + return fileOpt.get(); + } + FlightAreaFileDTO file = generateFlightAreaFile(workspaceId, flightAreas); + int id = saveFlightAreaFile(file); + if (id <= 0) { + throw new RuntimeException("Failed to save the flight area file."); + } + return file; + } + + private FlightAreaFileDTO generateFlightAreaFile(String workspaceId, List flightAreas) { + + FlightAreaJson flightAreaJson = new FlightAreaJson() + .setFeatures(flightAreas.stream() + .map(this::generateFlightAreaFeature) + .collect(Collectors.toList())); + try (ByteArrayOutputStream os = new ByteArrayOutputStream(64); + JsonGenerator generator = objectMapper.createGenerator(os);) { + generator.writePOJO(flightAreaJson); + try (ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray())) { + String name = String.format("geofence_%s.json", org.springframework.util.DigestUtils.md5DigestAsHex(is)); + is.reset(); + String objectKey = OssConfiguration.objectDirPrefix + "/" + name; + ossServiceContext.putObject(OssConfiguration.bucket, objectKey, is); + return FlightAreaFileDTO.builder() + .name(name) + .objectKey(objectKey) + .fileId(UUID.randomUUID().toString()) + .size(os.size()) + .workspaceId(workspaceId) + .sign(DigestUtils.sha256Hex(os.toByteArray())) + .latest(true) + .build(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + } + + private FlightAreaFeature generateFlightAreaFeature(FlightAreaDTO area) { + GeometrySubTypeEnum subType = null; + Float radius = 0f; + if (area.getContent().getGeometry() instanceof ElementCircleGeometry) { + ElementCircleGeometry geometry = (ElementCircleGeometry) area.getContent().getGeometry(); + subType = GeometrySubTypeEnum.CIRCLE; + radius = geometry.getRadius(); + area.getContent().setGeometry(new ElementPointGeometry().setCoordinates(geometry.getCoordinates())); + } + return new FlightAreaFeature() + .setGeofenceType(area.getType()) + .setId(area.getAreaId()) + .setProperties(new FeatureProperty() + .setSubType(subType) + .setRadius(radius) + .setEnable(area.getStatus())) + .setGeometry(objectMapper.convertValue(area.getContent().getGeometry(), FlightAreaGeometry.class)); + } + + private FlightAreaFileDTO entity2Dto(FlightAreaFileEntity entity) { + if (Objects.isNull(entity)) { + return null; + } + return FlightAreaFileDTO.builder() + .fileId(entity.getFileId()) + .name(entity.getName()) + .objectKey(entity.getObjectKey()) + .sign(entity.getSign()) + .size(entity.getSize()) + .workspaceId(entity.getWorkspaceId()) + .latest(entity.getLatest()) + .build(); + } + + private FlightAreaFileEntity dto2Entity(FlightAreaFileDTO dto) { + if (dto == null) { + return null; + } + return FlightAreaFileEntity.builder() + .fileId(dto.getFileId()) + .size(dto.getSize()) + .name(dto.getName()) + .sign(dto.getSign()) + .objectKey(dto.getObjectKey()) + .workspaceId(dto.getWorkspaceId()) + .latest(dto.getLatest()) + .build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/FlightAreaPropertyServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/FlightAreaPropertyServiceImpl.java new file mode 100644 index 0000000..79fc147 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/FlightAreaPropertyServiceImpl.java @@ -0,0 +1,100 @@ +package com.dji.sample.map.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.dji.sample.map.dao.IFlightAreaPropertyMapper; +import com.dji.sample.map.model.dto.FlightAreaPropertyDTO; +import com.dji.sample.map.model.dto.FlightAreaPropertyUpdate; +import com.dji.sample.map.model.entity.FlightAreaPropertyEntity; +import com.dji.sample.map.service.IFlightAreaPropertyServices; +import com.dji.sdk.cloudapi.flightarea.GeofenceTypeEnum; +import com.dji.sdk.cloudapi.flightarea.GeometrySubTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@Service +@Transactional +public class FlightAreaPropertyServiceImpl implements IFlightAreaPropertyServices { + + @Autowired + private IFlightAreaPropertyMapper mapper; + + @Override + public List getPropertyByElementIds(List elementIds) { + if (CollectionUtils.isEmpty(elementIds)) { + return Collections.emptyList(); + } + return mapper.selectList( + Wrappers.lambdaQuery(FlightAreaPropertyEntity.class) + .in(FlightAreaPropertyEntity::getElementId, elementIds)).stream() + .map(this::fillProperty).collect(Collectors.toList()); + } + + @Override + public Integer saveProperty(FlightAreaPropertyDTO property) { + FlightAreaPropertyEntity entity = dto2Entity(property); + int id = mapper.insert(entity); + return id > 0 ? entity.getId() : id; + } + + @Override + public Integer deleteProperty(String elementId) { + return mapper.delete(Wrappers.lambdaUpdate(FlightAreaPropertyEntity.class).eq(FlightAreaPropertyEntity::getElementId, elementId)); + } + + @Override + public Integer updateProperty(FlightAreaPropertyUpdate property) { + return mapper.update(update2Entity(property), + Wrappers.lambdaUpdate(FlightAreaPropertyEntity.class).eq(FlightAreaPropertyEntity::getElementId, property.getElementId())); + } + + private FlightAreaPropertyDTO fillProperty(FlightAreaPropertyEntity entity) { + if (Objects.isNull(entity)) { + return null; + } + FlightAreaPropertyDTO.FlightAreaPropertyDTOBuilder builder = FlightAreaPropertyDTO.builder() + .elementId(entity.getElementId()) + .status(entity.getEnable()) + .type(GeofenceTypeEnum.find(entity.getType())) + .subType(Optional.ofNullable(entity.getSubType()).map(GeometrySubTypeEnum::find).orElse(null)) + .radius(entity.getRadius().floatValue() / 100); + + return builder.build(); + } + + private FlightAreaPropertyEntity dto2Entity(FlightAreaPropertyDTO dto) { + if (Objects.isNull(dto)) { + return null; + } + return FlightAreaPropertyEntity.builder() + .elementId(dto.getElementId()) + .enable(dto.getStatus()) + .subType(Optional.ofNullable(dto.getSubType()).map(GeometrySubTypeEnum::getSubType).orElse(null)) + .type(dto.getType().getType()) + .radius(Optional.ofNullable(dto.getRadius()).map(radius -> radius * 100).map(Float::intValue).orElse(null)) + .build(); + } + + private FlightAreaPropertyEntity update2Entity(FlightAreaPropertyUpdate property) { + if (Objects.isNull(property)) { + return null; + } + return FlightAreaPropertyEntity.builder() + .radius(Optional.ofNullable(property.getRadius()).map(radius -> radius * 100).map(Float::intValue).orElse(null)) + .enable(property.getStatus()) + .elementId(property.getElementId()) + .build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/FlightAreaServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/FlightAreaServiceImpl.java new file mode 100644 index 0000000..8d210dd --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/FlightAreaServiceImpl.java @@ -0,0 +1,335 @@ +package com.dji.sample.map.service.impl; + +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.oss.service.impl.OssServiceContext; +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.dto.TelemetryDTO; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.map.model.dto.*; +import com.dji.sample.map.model.enums.FlightAreaGeometryTypeEnum; +import com.dji.sample.map.model.enums.FlightAreaOpertaionEnum; +import com.dji.sample.map.model.param.PostFlightAreaParam; +import com.dji.sample.map.model.param.PutFlightAreaParam; +import com.dji.sample.map.service.*; +import com.dji.sdk.cloudapi.flightarea.*; +import com.dji.sdk.cloudapi.flightarea.api.AbstractFlightAreaService; +import com.dji.sdk.cloudapi.map.*; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@Service +@Transactional +@Slf4j +public class FlightAreaServiceImpl extends AbstractFlightAreaService implements IFlightAreaService { + + @Autowired + private IFlightAreaPropertyServices flightAreaPropertyServices; + + @Autowired + private IGroupService groupService; + + @Autowired + private IWorkspaceElementService workspaceElementService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private SDKFlightAreaService abstractFlightAreaService; + + @Autowired + private IFlightAreaFileService flightAreaFileService; + + @Autowired + private IDeviceFlightAreaService deviceFlightAreaService; + + @Autowired + private OssServiceContext ossServiceContext; + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private ObjectMapper objectMapper; + + @Override + public Optional getFlightAreaByAreaId(String areaId) { + List properties = flightAreaPropertyServices.getPropertyByElementIds(List.of(areaId)); + if (CollectionUtils.isEmpty(properties)) { + return Optional.empty(); + } + Optional elementOpt = workspaceElementService.getElementByElementId(areaId); + return elementOpt.map(groupElementDTO -> this.element2FlightArea(objectMapper.convertValue(groupElementDTO, MapGroupElement.class), properties.get(0))); + } + + @Override + public List getFlightAreaList(String workspaceId) { + Optional> elementsOpt = groupService.getCustomGroupByWorkspaceId(workspaceId) + .map(group -> workspaceElementService.getAllGroupsByWorkspaceId(workspaceId, group.getId(), null)); + if (elementsOpt.isEmpty()) { + return Collections.emptyList(); + } + List elements = elementsOpt.get().get(0).getElements(); + Map propertyMap = flightAreaPropertyServices.getPropertyByElementIds( + elements.stream().map(MapGroupElement::getId).collect(Collectors.toList())) + .stream().collect(Collectors.toMap(FlightAreaPropertyDTO::getElementId, property -> property)); + return elements.stream().map(element -> this.element2FlightArea(element, propertyMap.get(element.getId()))).collect(Collectors.toList()); + } + + @Override + public void createFlightArea(String workspaceId, String username, PostFlightAreaParam param) { + Optional groupOpt = groupService.getCustomGroupByWorkspaceId(workspaceId); + if (groupOpt.isEmpty()) { + throw new RuntimeException("The custom flight area group does not exist, please create it first."); + } + ElementGeometryType geometry = param.getContent().getGeometry(); + String type = geometry.getType(); + ElementResourceTypeEnum typeEnum; + FlightAreaPropertyDTO property = new FlightAreaPropertyDTO(); + property.setType(param.getType()); + property.setStatus(true); + property.setElementId(param.getId()); + if (GeometrySubTypeEnum.CIRCLE.getSubType().equals(type)) { + ElementCircleGeometry circleGeometry = (ElementCircleGeometry) geometry; + property.setRadius(circleGeometry.getRadius()); + property.setSubType(GeometrySubTypeEnum.find(type)); + typeEnum = ElementResourceTypeEnum.find(ElementResourceTypeEnum.POINT.getTypeName()); + param.getContent().setGeometry(new ElementPointGeometry().setCoordinates(circleGeometry.getCoordinates())); + } else { + typeEnum = ElementResourceTypeEnum.find(type); + } + HttpResultResponse response = workspaceElementService.saveElement(workspaceId, groupOpt.get().getId(), + new CreateMapElementRequest().setId(param.getId()).setName(param.getName()) + .setResource(new ElementResource() + .setUsername(username) + .setType(typeEnum) + .setContent(new ElementContent() + .setGeometry(param.getContent().getGeometry()) + .setProperties(param.getContent().getProperties()))), false); + if (HttpResultResponse.CODE_FAILED == response.getCode()) { + throw new RuntimeException(response.getMessage()); + } + + int id = flightAreaPropertyServices.saveProperty(property); + if (id <= 0) { + throw new RuntimeException("Failed to save flight area properties."); + } + flightAreaFileService.setNonLatestByWorkspaceId(workspaceId); + + webSocketMessageService.sendBatch(workspaceId, BizCodeEnum.FLIGHT_AREAS_UPDATE.getCode(), + FlightAreaWs.builder() + .operation(FlightAreaOpertaionEnum.ADD) + .areaId(param.getId()) + .username(username) + .type(param.getType()) + .name(param.getName()) + .updateTime(System.currentTimeMillis()) + .createTime(System.currentTimeMillis()) + .content(FlightAreaContent.builder().geometry(geometry).properties(param.getContent().getProperties()).build()) + .status(true) + .build()); + } + + @Override + public void syncFlightArea(String workspaceId, List deviceSns) { + for (String deviceSn : deviceSns) { + Optional deviceOpt = deviceRedisService.getDeviceOnline(deviceSn); + if (deviceOpt.isEmpty() || !workspaceId.equals(deviceOpt.get().getWorkspaceId())) { + throw new RuntimeException(CommonErrorEnum.ILLEGAL_ARGUMENT.getMessage()); + } + TopicServicesResponse response = abstractFlightAreaService.flightAreasUpdate(SDKManager.getDeviceSDK(deviceSn)); + if (!response.getData().getResult().isSuccess()) { + throw new RuntimeException(response.getData().getResult().getMessage()); + } + } + packageFlightArea(workspaceId); + } + + @Override + public FlightAreaFileDTO packageFlightArea(String workspaceId) { + List flightAreas = getFlightAreaList(workspaceId); + return flightAreaFileService.packageFlightAreaFile(workspaceId, flightAreas); + } + + @Override + public void deleteFlightArea(String workspaceId, String areaId) { + HttpResultResponse response = workspaceElementService.deleteElement(workspaceId, areaId, false); + if (HttpResultResponse.CODE_SUCCESS !=response.getCode()) { + throw new RuntimeException(response.getMessage()); + } + int id = flightAreaPropertyServices.deleteProperty(areaId); + if (id <= 0) { + throw new RuntimeException("Failed to delete the flight area property."); + } + flightAreaFileService.setNonLatestByWorkspaceId(workspaceId); + webSocketMessageService.sendBatch(workspaceId, BizCodeEnum.FLIGHT_AREAS_UPDATE.getCode(), + FlightAreaWs.builder() + .operation(FlightAreaOpertaionEnum.DELETE) + .areaId(areaId) + .build()); + } + + @Override + public void updateFlightArea(String workspaceId, String areaId, PutFlightAreaParam param) { + Float radius = null; + if (Objects.nonNull(param.getContent())) { + ElementGeometryType geometry = param.getContent().getGeometry(); + FlightAreaGeometryTypeEnum typeEnum = FlightAreaGeometryTypeEnum.find(geometry.getType()); + if (FlightAreaGeometryTypeEnum.CIRCLE == typeEnum) { + radius = ((ElementCircleGeometry) geometry).getRadius(); + geometry = new ElementPointGeometry().setCoordinates(((ElementCircleGeometry) geometry).getCoordinates()); + } + Optional elementOpt = workspaceElementService.getElementByElementId(areaId); + if (elementOpt.isEmpty() || !elementOpt.get().getResource().getType().getTypeName().equals(geometry.getType())) { + throw new RuntimeException(CommonErrorEnum.ILLEGAL_ARGUMENT.getMessage()); + } + workspaceElementService.updateElement(workspaceId, areaId, + new UpdateMapElementRequest() + .setName(param.getName()) + .setContent(new ElementContent() + .setProperties(param.getContent().getProperties()) + .setGeometry(geometry)), + null, false); + } + + int id = flightAreaPropertyServices.updateProperty(FlightAreaPropertyUpdate.builder() + .elementId(areaId).status(param.getStatus()).radius(radius).build()); + if (id <= 0) { + throw new RuntimeException("Failed to update flight area properties."); + } + flightAreaFileService.setNonLatestByWorkspaceId(workspaceId); + Optional areaOpt = getFlightAreaByAreaId(areaId); + areaOpt.ifPresent(area -> webSocketMessageService.sendBatch(workspaceId, + BizCodeEnum.FLIGHT_AREAS_UPDATE.getCode(), + FlightAreaWs.builder() + .operation(FlightAreaOpertaionEnum.UPDATE) + .areaId(areaId) + .name(area.getName()) + .content(area.getContent()) + .status(area.getStatus()) + .type(area.getType()) + .username(area.getUsername()) + .createTime(area.getCreateTime()) + .updateTime(area.getUpdateTime()) + .build())); + + } + + @Override + public TopicEventsResponse flightAreasSyncProgress(TopicEventsRequest request, MessageHeaders headers) { + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + if (deviceOpt.isEmpty()) { + log.warn("method: flight_areas_sync_progress. Dock is offline."); + return null; + } + + FlightAreasSyncProgress data = request.getData(); + String workspaceId = deviceOpt.get().getWorkspaceId(); + + DeviceFlightAreaDTO deviceFlightArea = DeviceFlightAreaDTO.builder() + .deviceSn(request.getGateway()) + .workspaceId(workspaceId) + .syncStatus(data.getStatus()) + .syncCode(data.getReason()) + .build(); + deviceFlightAreaService.updateOrSaveDeviceFile(deviceFlightArea); + webSocketMessageService.sendBatch(workspaceId, BizCodeEnum.FLIGHT_AREAS_SYNC_PROGRESS.getCode(), + FlightAreaNotifyDTO.builder() + .sn(request.getGateway()) + .result(data.getReason().getReason()) + .message(data.getReason().getMsg()) + .status(data.getStatus().getStatus()) + .build()); + return new TopicEventsResponse<>(); + } + + @Override + public TopicEventsResponse flightAreasDroneLocation(TopicEventsRequest request, MessageHeaders headers) { + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + if (deviceOpt.isEmpty()) { + log.warn("method: flight_areas_drone_location. Dock is offline."); + return null; + } + if (request.getData().getDroneLocations().isEmpty()) { + return new TopicEventsResponse<>(); + } + webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), BizCodeEnum.FLIGHT_AREAS_DRONE_LOCATION.getCode(), + TelemetryDTO.builder().sn(deviceOpt.get().getChildDeviceSn()).host(request.getData()).build()); + return new TopicEventsResponse<>(); + } + + @Override + public TopicRequestsResponse> flightAreasGet(TopicRequestsRequest request, MessageHeaders headers) { + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + if (deviceOpt.isEmpty()) { + return null; + } + DeviceDTO device = deviceOpt.get(); + Optional flightAreaOpt = deviceFlightAreaService.getDeviceFlightAreaByDevice(device.getWorkspaceId(), device.getDeviceSn()); + Optional fileOpt = Optional.empty(); + if (flightAreaOpt.isPresent()) { + fileOpt = flightAreaFileService.getFlightAreaFileByFileId(flightAreaOpt.get().getFileId()); + } + FlightAreaFileDTO file = fileOpt.orElse(null); + if (flightAreaOpt.isEmpty() || fileOpt.isEmpty()) { + file = packageFlightArea(device.getWorkspaceId()); + } + return new TopicRequestsResponse>().setData( + MqttReply.success(new FlightAreasGetResponse().setFiles( + List.of(new FlightAreaGetFile() + .setName(file.getName()) + .setSize(file.getSize()) + .setChecksum(file.getSign()) + .setUrl(ossServiceContext.getObjectUrl(OssConfiguration.bucket, file.getObjectKey()).toString()) + )))); + } + + private FlightAreaDTO element2FlightArea(MapGroupElement element, FlightAreaPropertyDTO property) { + FlightAreaDTO.FlightAreaDTOBuilder builder = FlightAreaDTO.builder() + .areaId(element.getId()) + .name(element.getName()) + .createTime(element.getCreateTime()) + .updateTime(element.getUpdateTime()) + .username(element.getResource().getUsername()) + .content(FlightAreaContent.builder() + .properties(element.getResource().getContent().getProperties()) + .geometry(element.getResource().getContent().getGeometry()) + .build()); + if (Objects.isNull(property)) { + return builder.build(); + } + FlightAreaDTO flightArea = builder.type(property.getType()).status(property.getStatus()).build(); + if (GeometrySubTypeEnum.CIRCLE == property.getSubType()) { + ElementPointGeometry point = (ElementPointGeometry) flightArea.getContent().getGeometry(); + flightArea.getContent().setGeometry(new ElementCircleGeometry() + .setRadius(property.getRadius()) + .setCoordinates(new Double[]{point.getCoordinates()[0], point.getCoordinates()[1]})); + } + return flightArea; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/GroupElementServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/GroupElementServiceImpl.java new file mode 100644 index 0000000..21b25e5 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/GroupElementServiceImpl.java @@ -0,0 +1,216 @@ +package com.dji.sample.map.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.dji.sample.map.dao.IGroupElementMapper; +import com.dji.sample.map.model.dto.GroupElementDTO; +import com.dji.sample.map.model.entity.GroupElementEntity; +import com.dji.sdk.cloudapi.map.ElementTypeEnum; +import com.dji.sample.map.service.IElementCoordinateService; +import com.dji.sample.map.service.IGroupElementService; +import com.dji.sdk.cloudapi.map.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Service +@Transactional +public class GroupElementServiceImpl implements IGroupElementService { + + @Autowired + private IGroupElementMapper mapper; + + @Autowired + private IElementCoordinateService elementCoordinateService; + + @Override + public List getElementsByGroupId(String groupId) { + List elementList = mapper.selectList( + new LambdaQueryWrapper() + .eq(GroupElementEntity::getGroupId, groupId)); + + List groupElementList = new ArrayList<>(); + for (GroupElementEntity elementEntity : elementList) { + MapGroupElement groupElement = this.entityConvertToDto(elementEntity); + groupElementList.add(groupElement); + + this.addCoordinateToElement(groupElement, elementEntity); + } + return groupElementList; + } + + @Override + public Boolean saveElement(String groupId, CreateMapElementRequest elementCreate) { + Optional groupElementOpt = this.getEntityByElementId(elementCreate.getId()); + + if (groupElementOpt.isPresent()) { + return false; + } + GroupElementEntity groupElement = this.createDtoConvertToEntity(elementCreate); + groupElement.setGroupId(groupId); + + boolean saveElement = mapper.insert(groupElement) > 0; + if (!saveElement) { + return false; + } + // save coordinate + return elementCoordinateService.saveCoordinate( + elementCreate.getResource().getContent().getGeometry().convertToList(), elementCreate.getId()); + } + + @Override + public Boolean updateElement(String elementId, UpdateMapElementRequest elementUpdate, String username) { + Optional groupElementOpt = this.getEntityByElementId(elementId); + if (groupElementOpt.isEmpty()) { + return false; + } + + GroupElementEntity groupElement = groupElementOpt.get(); + groupElement.setUsername(username); + this.updateEntityWithDto(elementUpdate, groupElement); + boolean update = mapper.updateById(groupElement) > 0; + if (!update) { + return false; + } + // delete all coordinates according to element id. + boolean delCoordinate = elementCoordinateService.deleteCoordinateByElementId(elementId); + // save coordinate + boolean saveCoordinate = elementCoordinateService.saveCoordinate( + elementUpdate.getContent().getGeometry().convertToList(), elementId); + return delCoordinate & saveCoordinate; + } + + @Override + public Boolean deleteElement(String elementId) { + Optional groupElementOpt = this.getEntityByElementId(elementId); + if (groupElementOpt.isEmpty()) { + return true; + } + + GroupElementEntity groupElement = groupElementOpt.get(); + return mapper.deleteById(groupElement.getId()) > 0; + } + + + @Override + public Optional getElementByElementId(String elementId) { + Optional elementEntityOpt = this.getEntityByElementId(elementId); + if (elementEntityOpt.isEmpty()) { + return Optional.empty(); + } + GroupElementEntity elementEntity = elementEntityOpt.get(); + MapGroupElement groupElement = this.entityConvertToDto(elementEntity); + + this.addCoordinateToElement(groupElement, elementEntity); + return Optional.ofNullable(groupElement2Dto(groupElement, elementEntity.getGroupId())); + } + + private GroupElementDTO groupElement2Dto(MapGroupElement element, String groupId) { + if (null == element) { + return null; + } + return GroupElementDTO.builder() + .elementId(element.getId()) + .groupId(groupId) + .updateTime(element.getUpdateTime()) + .createTime(element.getCreateTime()) + .name(element.getName()) + .resource(element.getResource()) + .build(); + } + + /** + * Adds the received coordinate data to the element object. + * @param element + * @param elementEntity + */ + private void addCoordinateToElement(MapGroupElement element, GroupElementEntity elementEntity) { + Optional coordinateOpt = ElementTypeEnum.findType(elementEntity.getElementType()); + if (coordinateOpt.isEmpty()) { + return; + } + element.getResource() + .setContent(new ElementContent() + .setProperties(new ElementProperty() + .setClampToGround(elementEntity.getClampToGround()) + .setColor(elementEntity.getColor())) + .setGeometry(coordinateOpt.get())); + + coordinateOpt.get().adapterCoordinateType( + elementCoordinateService.getCoordinateByElementId(elementEntity.getElementId())); + } + + /** + * Query an element based on the element id。 + * @param elementId + * @return + */ + private Optional getEntityByElementId(String elementId) { + return Optional.ofNullable(mapper.selectOne( + new LambdaQueryWrapper() + .eq(GroupElementEntity::getElementId, elementId))); + } + + /** + * Convert database entity objects into element data transfer object. + * @param entity + * @return + */ + private MapGroupElement entityConvertToDto(GroupElementEntity entity) { + if (entity == null) { + return null; + } + + return new MapGroupElement() + .setId(entity.getElementId()) + .setName(entity.getElementName()) + .setCreateTime(entity.getCreateTime()) + .setUpdateTime(entity.getUpdateTime()) + .setResource(new ElementResource() + .setType(ElementResourceTypeEnum.find(entity.getElementType())) + .setUsername(entity.getUsername())); + } + + /** + * Convert the received element object into a database entity object. + * @param elementCreate + * @return + */ + private GroupElementEntity createDtoConvertToEntity(CreateMapElementRequest elementCreate) { + ElementProperty properties = elementCreate.getResource().getContent().getProperties(); + return GroupElementEntity.builder() + .elementId(elementCreate.getId()) + .elementName(elementCreate.getName()) + .username(elementCreate.getResource().getUsername()) + .elementType(ElementTypeEnum.findVal(elementCreate.getResource().getContent().getGeometry().getType())) + .clampToGround(properties.getClampToGround() != null && properties.getClampToGround()) + .color(properties.getColor()) + .build(); + } + + /** + * Add the content that needs to be updated to the entity object to be updated. + * @param elementUpdate + * @param groupElement + */ + private void updateEntityWithDto(UpdateMapElementRequest elementUpdate, GroupElementEntity groupElement) { + if (elementUpdate == null || groupElement == null) { + return; + } + + groupElement.setElementName(elementUpdate.getName()); + groupElement.setElementType(ElementTypeEnum.findVal(elementUpdate.getContent().getGeometry().getType())); + groupElement.setColor(elementUpdate.getContent().getProperties().getColor()); + + Boolean clampToGround = elementUpdate.getContent().getProperties().getClampToGround(); + groupElement.setClampToGround(clampToGround); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/GroupServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/GroupServiceImpl.java new file mode 100644 index 0000000..a73cc3b --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/GroupServiceImpl.java @@ -0,0 +1,74 @@ +package com.dji.sample.map.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.dji.sample.map.dao.IGroupMapper; +import com.dji.sample.map.model.entity.GroupEntity; +import com.dji.sample.map.service.IGroupElementService; +import com.dji.sample.map.service.IGroupService; +import com.dji.sdk.cloudapi.map.GetMapElementsResponse; +import com.dji.sdk.cloudapi.map.GroupTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/29 + */ +@Service +@Transactional +public class GroupServiceImpl implements IGroupService { + + @Autowired + private IGroupMapper mapper; + + @Autowired + private IGroupElementService groupElementService; + + @Override + public List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed) { + + return mapper.selectList( + new LambdaQueryWrapper() + .eq(GroupEntity::getWorkspaceId, workspaceId) + .eq(StringUtils.hasText(groupId), GroupEntity::getGroupId, groupId) + .eq(isDistributed != null, GroupEntity::getIsDistributed, isDistributed)) + .stream() + .map(this::entityConvertToDto) + .collect(Collectors.toList()); + } + + @Override + public Optional getCustomGroupByWorkspaceId(String workspaceId) { + return Optional.ofNullable(mapper.selectOne( + Wrappers.lambdaQuery(GroupEntity.class) + .eq(GroupEntity::getWorkspaceId, workspaceId) + .eq(GroupEntity::getGroupType, GroupTypeEnum.CUSTOM.getType()) + .last(" limit 1"))) + .map(this::entityConvertToDto); + } + + /** + * Convert database entity objects into group data transfer object. + * @param entity + * @return + */ + private GetMapElementsResponse entityConvertToDto(GroupEntity entity) { + if (entity == null) { + return null; + } + + return new GetMapElementsResponse() + .setId(entity.getGroupId()) + .setName(entity.getGroupName()) + .setType(GroupTypeEnum.find(entity.getGroupType())) + .setLock(entity.getIsLock()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/SDKFlightAreaService.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/SDKFlightAreaService.java new file mode 100644 index 0000000..7076452 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/SDKFlightAreaService.java @@ -0,0 +1,14 @@ +package com.dji.sample.map.service.impl; + +import com.dji.sdk.cloudapi.flightarea.api.AbstractFlightAreaService; +import org.springframework.stereotype.Service; + +/** + * @author sean + * @version 1.9 + * @date 2023/11/22 + */ +@Service +public class SDKFlightAreaService extends AbstractFlightAreaService { + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/WorkspaceElementServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/WorkspaceElementServiceImpl.java new file mode 100644 index 0000000..e7a40b9 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/map/service/impl/WorkspaceElementServiceImpl.java @@ -0,0 +1,149 @@ +package com.dji.sample.map.service.impl; + +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.map.model.dto.GroupElementDTO; +import com.dji.sample.map.service.IElementCoordinateService; +import com.dji.sample.map.service.IGroupElementService; +import com.dji.sample.map.service.IGroupService; +import com.dji.sample.map.service.IWorkspaceElementService; +import com.dji.sdk.cloudapi.map.*; +import com.dji.sdk.common.HttpResultResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 0.2 + * @date 2021/11/30 + */ +@Transactional +@Service +public class WorkspaceElementServiceImpl implements IWorkspaceElementService { + + @Autowired + private IGroupService groupService; + + @Autowired + private IGroupElementService groupElementService; + + @Autowired + private IElementCoordinateService elementCoordinateService; + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Override + public List getAllGroupsByWorkspaceId(String workspaceId, String groupId, Boolean isDistributed) { + List groupList = groupService.getAllGroupsByWorkspaceId(workspaceId, groupId, isDistributed); + groupList.forEach(group -> group.setElements(groupElementService.getElementsByGroupId(group.getId()))); + return groupList; + } + + @Override + public HttpResultResponse saveElement(String workspaceId, String groupId, CreateMapElementRequest elementCreate, boolean notify) { + boolean saveElement = groupElementService.saveElement(groupId, elementCreate); + if (!saveElement) { + return HttpResultResponse.error("未能保存元素。"); + } + if (notify) { + // Notify all WebSocket connections in this workspace to be updated when an element is created. + getElementByElementId(elementCreate.getId()) + .ifPresent(groupElement -> webSocketMessageService.sendBatch( + workspaceId, BizCodeEnum.MAP_ELEMENT_CREATE.getCode(), + element2CreateWsElement(groupElement))); + } + return HttpResultResponse.success(); + } + + @Override + public HttpResultResponse updateElement(String workspaceId, String elementId, UpdateMapElementRequest elementUpdate, String username, boolean notify) { + boolean updElement = groupElementService.updateElement(elementId, elementUpdate, username); + if (!updElement) { + return HttpResultResponse.error("未能更新元素。"); + } + + if (notify) { + // Notify all WebSocket connections in this workspace to update when there is an element update. + getElementByElementId(elementId) + .ifPresent(groupElement -> webSocketMessageService.sendBatch( + workspaceId, BizCodeEnum.MAP_ELEMENT_UPDATE.getCode(), + element2UpdateWsElement(groupElement))); + } + return HttpResultResponse.success(); + } + + @Override + public HttpResultResponse deleteElement(String workspaceId, String elementId, boolean notify) { + Optional elementOpt = getElementByElementId(elementId); + boolean delElement = groupElementService.deleteElement(elementId); + if (!delElement) { + return HttpResultResponse.error("未能删除元素。"); + } + + // delete all coordinates according to element id. + boolean delCoordinate = elementCoordinateService.deleteCoordinateByElementId(elementId); + if (!delCoordinate) { + return HttpResultResponse.error("删除坐标失败。"); + } + + if (notify) { + // Notify all WebSocket connections in this workspace to update when an element is deleted. + elementOpt.ifPresent(element -> + webSocketMessageService.sendBatch(workspaceId, BizCodeEnum.MAP_ELEMENT_DELETE.getCode(), + new MapElementDeleteWsResponse() + .setGroupId(element.getGroupId()) + .setId(elementId))); + } + + return HttpResultResponse.success(); + } + + @Override + public Optional getElementByElementId(String elementId) { + return groupElementService.getElementByElementId(elementId); + } + + @Override + public HttpResultResponse deleteAllElementByGroupId(String workspaceId, String groupId) { + List groupElementList = groupElementService.getElementsByGroupId(groupId); + for (MapGroupElement groupElement : groupElementList) { + HttpResultResponse response = this.deleteElement(workspaceId, groupElement.getId(), true); + if (HttpResultResponse.CODE_SUCCESS != response.getCode()) { + return response; + } + } + + return HttpResultResponse.success(); + } + + public MapElementCreateWsResponse element2CreateWsElement(GroupElementDTO element) { + if (element == null) { + return null; + } + return new MapElementCreateWsResponse() + .setId(element.getElementId()) + .setGroupId(element.getGroupId()) + .setName(element.getName()) + .setResource(element.getResource()) + .setUpdateTime(element.getUpdateTime()) + .setCreateTime(element.getCreateTime()); + } + + public MapElementUpdateWsResponse element2UpdateWsElement(GroupElementDTO element) { + if (element == null) { + return null; + } + return new MapElementUpdateWsResponse() + .setId(element.getElementId()) + .setGroupId(element.getGroupId()) + .setName(element.getName()) + .setResource(element.getResource()) + .setUpdateTime(element.getUpdateTime()) + .setCreateTime(element.getCreateTime()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/controller/FileController.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/controller/FileController.java new file mode 100644 index 0000000..3934014 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/controller/FileController.java @@ -0,0 +1,57 @@ +package com.dji.sample.media.controller; + +import com.dji.sample.media.model.MediaFileDTO; +import com.dji.sample.media.service.IFileService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URL; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +@RestController +@RequestMapping("${url.media.prefix}${url.media.version}/files") +public class FileController { + + @Autowired + private IFileService fileService; + + /** + * Get information about all the media files in this workspace based on the workspace id. + * @param workspaceId + * @return + */ + @GetMapping("/{workspace_id}/files") + public HttpResultResponse> getFilesList(@RequestParam(defaultValue = "1") Long page, + @RequestParam(name = "page_size", defaultValue = "10") Long pageSize, + @PathVariable(name = "workspace_id") String workspaceId) { + PaginationData filesList = fileService.getMediaFilesPaginationByWorkspaceId(workspaceId, page, pageSize); + return HttpResultResponse.success(filesList); + } + + /** + * Query the download address of the file according to the media file id, + * and redirect to this address directly for download. + * @param workspaceId + * @param fileId + * @param response + */ + @GetMapping("/{workspace_id}/file/{file_id}/url") + public void getFileUrl(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "file_id") String fileId, HttpServletResponse response) { + + try { + URL url = fileService.getObjectUrl(workspaceId, fileId); + response.sendRedirect(url.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/controller/MediaController.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/controller/MediaController.java new file mode 100644 index 0000000..ec21a54 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/controller/MediaController.java @@ -0,0 +1,71 @@ +package com.dji.sample.media.controller; + +import com.dji.sample.media.service.IMediaService; +import com.dji.sdk.cloudapi.media.*; +import com.dji.sdk.cloudapi.media.api.IHttpMediaService; +import com.dji.sdk.common.HttpResultResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/7 + */ +@Slf4j +@RestController +public class MediaController implements IHttpMediaService { + + @Autowired + private IMediaService mediaService; + + /** + * Check if the file has been uploaded by the fingerprint. + * @param workspaceId + * @param request + * @return + */ + @Override + public HttpResultResponse mediaFastUpload(String workspaceId, @Valid MediaFastUploadRequest request, HttpServletRequest req, HttpServletResponse rsp) { + boolean isExist = mediaService.fastUpload(workspaceId, request.getFingerprint()); + + return isExist ? HttpResultResponse.success() : HttpResultResponse.error(request.getFingerprint() + "don't exist."); + } + + /** + * When the file is uploaded to the storage server by pilot, + * the basic information of the file is reported through this interface. + * @param workspaceId + * @param request + * @return + */ + @Override + public HttpResultResponse mediaUploadCallback(String workspaceId, @Valid MediaUploadCallbackRequest request, HttpServletRequest req, HttpServletResponse rsp) { + mediaService.saveMediaFile(workspaceId, request); + return HttpResultResponse.success(request.getObjectKey()); + } + + /** + * Query the files that already exist in this workspace based on the workspace id and the collection of tiny fingerprints. + * @param workspaceId + * @param request There is only one tiny_fingerprint parameter in the body. + * But it is not recommended to use Map to receive the parameter. + * @return + */ + @Override + public HttpResultResponse getExistFileTinyFingerprint(String workspaceId, @Valid GetFileFingerprintRequest request, HttpServletRequest req, HttpServletResponse rsp) { + List existingList = mediaService.getExistTinyFingerprints(workspaceId, request.getTinyFingerprints()); + return HttpResultResponse.success(new GetFileFingerprintResponse().setTinyFingerprints(existingList)); + } + + @Override + public HttpResultResponse folderUploadCallback(String workspaceId, @Valid FolderUploadCallbackRequest request, HttpServletRequest req, HttpServletResponse rsp) { + return null; + } +} \ No newline at end of file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/dao/IFileMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/dao/IFileMapper.java new file mode 100644 index 0000000..ec01af1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/dao/IFileMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.media.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.media.model.MediaFileEntity; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +public interface IFileMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaFileCountDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaFileCountDTO.java new file mode 100644 index 0000000..2aa952a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaFileCountDTO.java @@ -0,0 +1,32 @@ +package com.dji.sample.media.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MediaFileCountDTO { + + private String tid; + + private String bid; + + private String preJobId; + + private String jobId; + + private Integer mediaCount; + + private Integer uploadedCount; + + private String deviceSn; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaFileDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaFileDTO.java new file mode 100644 index 0000000..dec1a1b --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaFileDTO.java @@ -0,0 +1,44 @@ +package com.dji.sample.media.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MediaFileDTO { + + private String fileId; + + private String fileName; + + private String filePath; + + private String objectKey; + + private String subFileType; + + private Boolean isOriginal; + + private String drone; + + private String payload; + + private String tinnyFingerprint; + + private String fingerprint; + + private LocalDateTime createTime; + + private String jobId; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaFileEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaFileEntity.java new file mode 100644 index 0000000..78a747c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaFileEntity.java @@ -0,0 +1,68 @@ +package com.dji.sample.media.model; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +@TableName(value = "media_file") +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class MediaFileEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField("file_id") + private String fileId; + + @TableField("file_name") + private String fileName; + + @TableField("file_path") + private String filePath; + + @TableField("workspace_id") + private String workspaceId; + + @TableField("fingerprint") + private String fingerprint; + + @TableField("tinny_fingerprint") + private String tinnyFingerprint; + + @TableField("object_key") + private String objectKey; + + @TableField("sub_file_type") + private Integer subFileType; + + @TableField("is_original") + private Boolean isOriginal; + + @TableField("drone") + private String drone; + + @TableField("payload") + private String payload; + + @TableField("job_id") + private String jobId; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; +} + diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaMethodEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaMethodEnum.java new file mode 100644 index 0000000..4de860f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/model/MediaMethodEnum.java @@ -0,0 +1,20 @@ +package com.dji.sample.media.model; + +import lombok.Getter; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/23 + */ +@Getter +public enum MediaMethodEnum { + + UPLOAD_FLIGHT_TASK_MEDIA_PRIORITIZE("upload_flighttask_media_prioritize"); + + private String method; + + MediaMethodEnum(String method) { + this.method = method; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IFileService.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IFileService.java new file mode 100644 index 0000000..72f41a1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IFileService.java @@ -0,0 +1,64 @@ +package com.dji.sample.media.service; + +import com.dji.sample.media.model.MediaFileDTO; +import com.dji.sdk.cloudapi.media.MediaUploadCallbackRequest; +import com.dji.sdk.common.PaginationData; + +import java.net.URL; +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +public interface IFileService { + + /** + * Query if the file already exists based on the workspace id and the fingerprint of the file. + * @param workspaceId + * @param fingerprint + * @return + */ + Boolean checkExist(String workspaceId, String fingerprint); + + /** + * Save the basic information of the file to the database. + * @param workspaceId + * @param file + * @return + */ + Integer saveFile(String workspaceId, MediaUploadCallbackRequest file); + + /** + * Query information about all files in this workspace based on the workspace id. + * @param workspaceId + * @return + */ + List getAllFilesByWorkspaceId(String workspaceId); + + /** + * Paginate through all media files in this workspace. + * @param workspaceId + * @param page + * @param pageSize + * @return + */ + PaginationData getMediaFilesPaginationByWorkspaceId(String workspaceId, long page, long pageSize); + + /** + * Get the download address of the file. + * @param workspaceId + * @param fileId + * @return + */ + URL getObjectUrl(String workspaceId, String fileId); + + /** + * Query all media files of a job. + * @param workspaceId + * @param jobId + * @return + */ + List getFilesByWorkspaceAndJobId(String workspaceId, String jobId); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IMediaRedisService.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IMediaRedisService.java new file mode 100644 index 0000000..03fc446 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IMediaRedisService.java @@ -0,0 +1,26 @@ +package com.dji.sample.media.service; + +import com.dji.sample.media.model.MediaFileCountDTO; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +public interface IMediaRedisService { + + void setMediaCount(String gatewaySn, String jobId, MediaFileCountDTO mediaFile); + + MediaFileCountDTO getMediaCount(String gatewaySn, String jobId); + + boolean delMediaCount(String gatewaySn, String jobId); + + boolean detMediaCountByDeviceSn(String gatewaySn); + + void setMediaHighestPriority(String gatewaySn, MediaFileCountDTO mediaFile); + + MediaFileCountDTO getMediaHighestPriority(String gatewaySn); + + boolean delMediaHighestPriority(String gatewaySn); + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IMediaService.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IMediaService.java new file mode 100644 index 0000000..4b55d2f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IMediaService.java @@ -0,0 +1,45 @@ +package com.dji.sample.media.service; + +import com.dji.sdk.cloudapi.media.MediaUploadCallbackRequest; + +import java.util.List; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +public interface IMediaService { + + /** + * Check if the file has been uploaded by the fingerprint. + * @param workspaceId + * @param fingerprint + * @return + */ + Boolean fastUpload(String workspaceId, String fingerprint); + + /** + * Save the basic information of the file to the database. + * @param workspaceId + * @param file + * @return + */ + Integer saveMediaFile(String workspaceId, MediaUploadCallbackRequest file); + + /** + * Query tiny fingerprints about all files in this workspace based on the workspace id. + * @param workspaceId + * @return + */ + List getAllTinyFingerprintsByWorkspaceId(String workspaceId); + + /** + * Query the fingerprints that already exist in it based on the incoming tiny fingerprints data. + * @param workspaceId + * @param tinyFingerprints + * @return + */ + List getExistTinyFingerprints(String workspaceId, List tinyFingerprints); + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/FileServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/FileServiceImpl.java new file mode 100644 index 0000000..e837436 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/FileServiceImpl.java @@ -0,0 +1,176 @@ +package com.dji.sample.media.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.oss.service.impl.OssServiceContext; +import com.dji.sample.manage.model.dto.DeviceDictionaryDTO; +import com.dji.sample.manage.service.IDeviceDictionaryService; +import com.dji.sample.media.dao.IFileMapper; +import com.dji.sample.media.model.MediaFileDTO; +import com.dji.sample.media.model.MediaFileEntity; +import com.dji.sample.media.service.IFileService; +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.dji.sdk.cloudapi.media.MediaSubFileTypeEnum; +import com.dji.sdk.cloudapi.media.MediaUploadCallbackRequest; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.net.URL; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +@Service +@Transactional +public class FileServiceImpl implements IFileService { + + @Autowired + private IFileMapper mapper; + + @Autowired + private IDeviceDictionaryService deviceDictionaryService; + + @Autowired + private OssServiceContext ossService; + + private Optional getMediaByFingerprint(String workspaceId, String fingerprint) { + MediaFileEntity fileEntity = mapper.selectOne(new LambdaQueryWrapper() + .eq(MediaFileEntity::getWorkspaceId, workspaceId) + .eq(MediaFileEntity::getFingerprint, fingerprint)); + return Optional.ofNullable(fileEntity); + } + + private Optional getMediaByFileId(String workspaceId, String fileId) { + MediaFileEntity fileEntity = mapper.selectOne(new LambdaQueryWrapper() + .eq(MediaFileEntity::getWorkspaceId, workspaceId) + .eq(MediaFileEntity::getFileId, fileId)); + return Optional.ofNullable(fileEntity); + } + + @Override + public Boolean checkExist(String workspaceId, String fingerprint) { + return this.getMediaByFingerprint(workspaceId, fingerprint).isPresent(); + } + + @Override + public Integer saveFile(String workspaceId, MediaUploadCallbackRequest file) { + MediaFileEntity fileEntity = this.fileUploadConvertToEntity(file); + fileEntity.setWorkspaceId(workspaceId); + fileEntity.setFileId(UUID.randomUUID().toString()); + return mapper.insert(fileEntity); + } + + @Override + public List getAllFilesByWorkspaceId(String workspaceId) { + return mapper.selectList(new LambdaQueryWrapper() + .eq(MediaFileEntity::getWorkspaceId, workspaceId)) + .stream() + .map(this::entityConvertToDto) + .collect(Collectors.toList()); + } + + @Override + public PaginationData getMediaFilesPaginationByWorkspaceId(String workspaceId, long page, long pageSize) { + Page pageData = mapper.selectPage( + new Page(page, pageSize), + new LambdaQueryWrapper() + .eq(MediaFileEntity::getWorkspaceId, workspaceId) + .orderByDesc(MediaFileEntity::getId)); + List records = pageData.getRecords() + .stream() + .map(this::entityConvertToDto) + .collect(Collectors.toList()); + + return new PaginationData(records, new Pagination(pageData.getCurrent(), pageData.getSize(), pageData.getTotal())); + } + + @Override + public URL getObjectUrl(String workspaceId, String fileId) { + Optional mediaFileOpt = getMediaByFileId(workspaceId, fileId); + if (mediaFileOpt.isEmpty()) { + throw new IllegalArgumentException("{} 不存在。"); + } + + return ossService.getObjectUrl(OssConfiguration.bucket, mediaFileOpt.get().getObjectKey()); + } + + @Override + public List getFilesByWorkspaceAndJobId(String workspaceId, String jobId) { + return mapper.selectList(new LambdaQueryWrapper() + .eq(MediaFileEntity::getWorkspaceId, workspaceId) + .eq(MediaFileEntity::getJobId, jobId)) + .stream() + .map(this::entityConvertToDto).collect(Collectors.toList()); + } + + /** + * Convert the received file object into a database entity object. + * @param file + * @return + */ + private MediaFileEntity fileUploadConvertToEntity(MediaUploadCallbackRequest file) { + MediaFileEntity.MediaFileEntityBuilder builder = MediaFileEntity.builder(); + + if (file != null) { + builder.fileName(file.getName()) + .filePath(file.getPath()) + .fingerprint(file.getFingerprint()) + .objectKey(file.getObjectKey()) + .subFileType(Optional.ofNullable(file.getSubFileType()).map(MediaSubFileTypeEnum::getType).orElse(null)) + .isOriginal(file.getExt().getOriginal()) + .jobId(file.getExt().getFileGroupId()) + .drone(file.getExt().getSn()) + .tinnyFingerprint(file.getExt().getTinnyFingerprint()) + .payload(file.getExt().getPayloadModelKey().getDevice()); + + // domain-type-subType + DeviceEnum payloadModelKey = file.getExt().getPayloadModelKey(); + Optional payloadDict = deviceDictionaryService + .getOneDictionaryInfoByTypeSubType(payloadModelKey.getDomain().getDomain(), + payloadModelKey.getType().getType(), payloadModelKey.getSubType().getSubType()); + payloadDict.ifPresent(payload -> builder.payload(payload.getDeviceName())); + } + return builder.build(); + } + + /** + * Convert database entity objects into file data transfer object. + * @param entity + * @return + */ + private MediaFileDTO entityConvertToDto(MediaFileEntity entity) { + MediaFileDTO.MediaFileDTOBuilder builder = MediaFileDTO.builder(); + + if (entity != null) { + builder.fileName(entity.getFileName()) + .fileId(entity.getFileId()) + .filePath(entity.getFilePath()) + .isOriginal(entity.getIsOriginal()) + .fingerprint(entity.getFingerprint()) + .objectKey(entity.getObjectKey()) + .tinnyFingerprint(entity.getTinnyFingerprint()) + .payload(entity.getPayload()) + .createTime(LocalDateTime.ofInstant( + Instant.ofEpochMilli(entity.getCreateTime()), ZoneId.systemDefault())) + .drone(entity.getDrone()) + .jobId(entity.getJobId()); + + } + + return builder.build(); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/MediaRedisServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/MediaRedisServiceImpl.java new file mode 100644 index 0000000..9090d75 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/MediaRedisServiceImpl.java @@ -0,0 +1,54 @@ +package com.dji.sample.media.service.impl; + +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.media.model.MediaFileCountDTO; +import com.dji.sample.media.service.IMediaRedisService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +@Service +@Slf4j +public class MediaRedisServiceImpl implements IMediaRedisService { + + + @Override + public void setMediaCount(String gatewaySn, String jobId, MediaFileCountDTO mediaFile) { + RedisOpsUtils.hashSet(RedisConst.MEDIA_FILE_PREFIX + gatewaySn, jobId, mediaFile); + } + + @Override + public MediaFileCountDTO getMediaCount(String gatewaySn, String jobId) { + return (MediaFileCountDTO) RedisOpsUtils.hashGet(RedisConst.MEDIA_FILE_PREFIX + gatewaySn, jobId); + } + + @Override + public boolean delMediaCount(String gatewaySn, String jobId) { + return RedisOpsUtils.hashDel(RedisConst.MEDIA_FILE_PREFIX + gatewaySn, new String[]{jobId}); + } + + @Override + public boolean detMediaCountByDeviceSn(String gatewaySn) { + return RedisOpsUtils.del(RedisConst.MEDIA_FILE_PREFIX + gatewaySn); + } + + @Override + public void setMediaHighestPriority(String gatewaySn, MediaFileCountDTO mediaFile) { + RedisOpsUtils.setWithExpire(RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + gatewaySn, mediaFile, RedisConst.DEVICE_ALIVE_SECOND * 5); + } + + @Override + public MediaFileCountDTO getMediaHighestPriority(String gatewaySn) { + return (MediaFileCountDTO) RedisOpsUtils.get(RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + gatewaySn); + } + + @Override + public boolean delMediaHighestPriority(String gatewaySn) { + return RedisOpsUtils.del(RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + gatewaySn); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/MediaServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/MediaServiceImpl.java new file mode 100644 index 0000000..ac9cc77 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/MediaServiceImpl.java @@ -0,0 +1,216 @@ +package com.dji.sample.media.service.impl; + +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sample.media.model.MediaFileCountDTO; +import com.dji.sample.media.model.MediaFileDTO; +import com.dji.sample.media.service.IFileService; +import com.dji.sample.media.service.IMediaRedisService; +import com.dji.sample.media.service.IMediaService; +import com.dji.sample.wayline.service.IWaylineJobService; +import com.dji.sdk.cloudapi.media.*; +import com.dji.sdk.cloudapi.media.api.AbstractMediaService; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 0.2 + * @date 2021/12/9 + */ +@Service +@Slf4j +public class MediaServiceImpl extends AbstractMediaService implements IMediaService { + + @Autowired + private IFileService fileService; + + @Autowired + private IWaylineJobService waylineJobService; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private IMediaRedisService mediaRedisService; + + @Override + public Boolean fastUpload(String workspaceId, String fingerprint) { + return fileService.checkExist(workspaceId, fingerprint); + } + + @Override + public Integer saveMediaFile(String workspaceId, MediaUploadCallbackRequest file) { + return fileService.saveFile(workspaceId, file); + } + + @Override + public List getAllTinyFingerprintsByWorkspaceId(String workspaceId) { + return fileService.getAllFilesByWorkspaceId(workspaceId) + .stream() + .map(MediaFileDTO::getTinnyFingerprint) + .collect(Collectors.toList()); + } + + @Override + public List getExistTinyFingerprints(String workspaceId, List tinyFingerprints) { + List tinyFingerprintList = this.getAllTinyFingerprintsByWorkspaceId(workspaceId); + return tinyFingerprints + .stream() + .filter(tinyFingerprintList::contains) + .collect(Collectors.toList()); + + } + + @Override + public TopicEventsResponse fileUploadCallback(TopicEventsRequest request, MessageHeaders headers) { + FileUploadCallback callback = request.getData(); + + if (MqttReply.CODE_SUCCESS != callback.getResult()) { + log.error("媒体文件上传失败!"); + return null; + } + + String jobId = callback.getFile().getExt().getFlightId(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + MediaFileCountDTO mediaFileCount = mediaRedisService.getMediaCount(request.getGateway(), jobId); + // duplicate data + if (deviceOpt.isEmpty() + || (Objects.nonNull(mediaFileCount) && request.getBid().equals(mediaFileCount.getBid()) + && request.getTid().equals(mediaFileCount.getTid()))) { + return new TopicEventsResponse().setData(MqttReply.success()); + } + + DeviceDTO device = deviceOpt.get(); + boolean isSave = parseMediaFile(callback, device); + if (!isSave) { + log.error("将文件保存到数据库失败,请手动检查数据。"); + return null; + } + + notifyUploadedCount(mediaFileCount, request, jobId, device); + return new TopicEventsResponse().setData(MqttReply.success()); + } + + @Override + public TopicEventsResponse highestPriorityUploadFlightTaskMedia( + TopicEventsRequest request, MessageHeaders headers) { + String jobId = request.getData().getFlightId(); + if (!StringUtils.hasText(jobId)) { + return null; + } + + MediaFileCountDTO countDTO = mediaRedisService.getMediaHighestPriority(request.getGateway()); + if (Objects.nonNull(countDTO)) { + if (jobId.equals(countDTO.getJobId())) { + mediaRedisService.setMediaHighestPriority(request.getGateway(), countDTO); + return new TopicEventsResponse().setData(MqttReply.success()); + } + countDTO.setPreJobId(countDTO.getJobId()); + } + countDTO.setJobId(jobId); + mediaRedisService.setMediaHighestPriority(request.getGateway(), countDTO); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getGateway()); + if (deviceOpt.isEmpty()) { + return null; + } + + webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA.getCode(), countDTO); + + return new TopicEventsResponse().setData(MqttReply.success()); + } + + private Boolean parseMediaFile(FileUploadCallback callback, DeviceDTO device) { + MediaUploadCallbackRequest file = convert2callbackRequest(callback.getFile()); + // Set the drone sn that shoots the media + file.getExt().setSn(device.getChildDeviceSn()); + + // set path + String objectKey = file.getObjectKey(); + file.setPath(objectKey.substring(Optional.of(objectKey.indexOf(OssConfiguration.objectDirPrefix)) + .filter(index -> index > 0).map(index -> index++).orElse(0), + objectKey.lastIndexOf("/"))); + + return fileService.saveFile(device.getWorkspaceId(), file) > 0; + } + + private void notifyUploadedCount(MediaFileCountDTO mediaFileCount, TopicEventsRequest request, String jobId, DeviceDTO dock) { + // Do not notify when files that do not belong to the route are uploaded. + if (Objects.isNull(mediaFileCount)) { + return; + } + mediaFileCount.setBid(request.getBid()); + mediaFileCount.setTid(request.getTid()); + mediaFileCount.setUploadedCount(mediaFileCount.getUploadedCount() + 1); + + // After all the files of the job are uploaded, delete the media file key. + if (mediaFileCount.getUploadedCount() >= mediaFileCount.getMediaCount()) { + mediaRedisService.delMediaCount(request.getGateway(), jobId); + + // After uploading, delete the key with the highest priority. + MediaFileCountDTO fileCount = mediaRedisService.getMediaHighestPriority(request.getGateway()); + if (Objects.nonNull(fileCount) && jobId.equals(fileCount.getJobId())) { + mediaRedisService.delMediaHighestPriority(request.getGateway()); + } + } else { + mediaRedisService.setMediaCount(request.getGateway(), jobId, mediaFileCount); + } + + webSocketMessageService.sendBatch(dock.getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.FILE_UPLOAD_CALLBACK.getCode(), mediaFileCount); + } + + private MediaUploadCallbackRequest convert2callbackRequest(FileUploadCallbackFile file) { + if (Objects.isNull(file)) { + return null; + } + return new MediaUploadCallbackRequest() + .setExt(Optional.ofNullable(file.getExt()) + .map(ext -> new MediaFileExtension() + .setDroneModelKey(ext.getDroneModelKey()) + .setFileGroupId(ext.getFlightId()) + .setOriginal(ext.getOriginal()) + .setPayloadModelKey(ext.getPayloadModelKey())) + .orElse(new MediaFileExtension())) + .setMetadata(Optional.ofNullable(file.getMetadata()) + .map(data -> new MediaFileMetadata() + .setAbsoluteAltitude(data.getAbsoluteAltitude()) + .setGimbalYawDegree(data.getGimbalYawDegree()) + .setRelativeAltitude(data.getRelativeAltitude()) + .setShootPosition(data.getShootPosition()) + .setCreatedTime(data.getCreatedTime())) + .get()) + .setName(file.getName()) + .setObjectKey(file.getObjectKey()) + .setPath(file.getPath()); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/storage/controller/StorageController.java b/dk-modules/sample/src/main/java/org/dromara/sample/storage/controller/StorageController.java new file mode 100644 index 0000000..1097cb1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/storage/controller/StorageController.java @@ -0,0 +1,34 @@ +package com.dji.sample.storage.controller; + +import com.dji.sample.storage.service.IStorageService; +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; +import com.dji.sdk.cloudapi.storage.api.IHttpStorageService; +import com.dji.sdk.common.HttpResultResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/29 + */ +@RestController +public class StorageController implements IHttpStorageService { + + @Autowired + private IStorageService storageService; + + /** + * Get temporary credentials for uploading the media and wayline in DJI Pilot. + * @param workspaceId + * @return + */ + @Override + public HttpResultResponse getTemporaryCredential(String workspaceId, HttpServletRequest req, HttpServletResponse rsp) { + StsCredentialsResponse stsCredentials = storageService.getSTSCredentials(); + return HttpResultResponse.success(stsCredentials); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/storage/service/IStorageService.java b/dk-modules/sample/src/main/java/org/dromara/sample/storage/service/IStorageService.java new file mode 100644 index 0000000..4d86788 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/storage/service/IStorageService.java @@ -0,0 +1,18 @@ +package com.dji.sample.storage.service; + +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/29 + */ +public interface IStorageService { + + /** + * Get custom temporary credentials object for uploading the media and wayline. + * @return temporary credentials object + */ + StsCredentialsResponse getSTSCredentials(); + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/storage/service/impl/StorageServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/storage/service/impl/StorageServiceImpl.java new file mode 100644 index 0000000..6295400 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/storage/service/impl/StorageServiceImpl.java @@ -0,0 +1,42 @@ +package com.dji.sample.storage.service.impl; + +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.oss.service.impl.OssServiceContext; +import com.dji.sample.storage.service.IStorageService; +import com.dji.sdk.cloudapi.media.StorageConfigGet; +import com.dji.sdk.cloudapi.media.api.AbstractMediaService; +import com.dji.sdk.cloudapi.storage.StsCredentialsResponse; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; + +/** + * @author sean + * @version 0.3 + * @date 2022/3/9 + */ +@Service +public class StorageServiceImpl extends AbstractMediaService implements IStorageService { + + @Autowired + private OssServiceContext ossService; + + @Override + public StsCredentialsResponse getSTSCredentials() { + return new StsCredentialsResponse() + .setEndpoint(OssConfiguration.endpoint) + .setBucket(OssConfiguration.bucket) + .setCredentials(ossService.getCredentials()) + .setProvider(OssConfiguration.provider) + .setObjectKeyPrefix(OssConfiguration.objectDirPrefix) + .setRegion(OssConfiguration.region); + } + + @Override + public TopicRequestsResponse> storageConfigGet(TopicRequestsRequest response, MessageHeaders headers) { + return new TopicRequestsResponse>().setData(MqttReply.success(getSTSCredentials())); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineFileController.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineFileController.java new file mode 100644 index 0000000..37e6d61 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineFileController.java @@ -0,0 +1,184 @@ +package com.dji.sample.wayline.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.wayline.model.dto.WaylineFileDTO; +import com.dji.sample.wayline.model.entity.WaylineFileEntity; +import com.dji.sample.wayline.service.IWaylineFileService; +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.dji.sdk.cloudapi.wayline.*; +import com.dji.sdk.cloudapi.wayline.api.IHttpWaylineService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.IOException; +import java.net.URL; +import java.sql.SQLException; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@RestController +public class WaylineFileController implements IHttpWaylineService { + + @Autowired + private IWaylineFileService waylineFileService; + + /** + * Delete the wayline file in the workspace according to the wayline id. + * @param workspaceId + * @param waylineId + * @return + */ + @DeleteMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/{wayline_id}") + public HttpResultResponse deleteWayline(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "wayline_id") String waylineId) { + boolean isDel = waylineFileService.deleteByWaylineId(workspaceId, waylineId); + return isDel ? HttpResultResponse.success() : HttpResultResponse.error("航线删除失败"); + } + + /** + * Import kmz wayline files. + * @param file + * @return + */ + @PostMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/file/upload") + public HttpResultResponse importKmzFile(HttpServletRequest request, MultipartFile file) { + if (Objects.isNull(file)) { + return HttpResultResponse.error("No file received."); + } + CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); + String workspaceId = customClaim.getWorkspaceId(); + String creator = customClaim.getUsername(); + waylineFileService.importKmzFile(file, workspaceId, creator); + return HttpResultResponse.success(); + } + + /** + * Query the basic data of the wayline file according to the query conditions. + * The query condition field in pilot is fixed. + * @param request + * @param workspaceId + * @return + */ + @Override + public HttpResultResponse> getWaylineList(@Valid GetWaylineListRequest request, String workspaceId, HttpServletRequest req, HttpServletResponse rsp) { + PaginationData data = waylineFileService.getWaylinesByParam(workspaceId, request); + return HttpResultResponse.success(data); + } + + /** + * Query the download address of the file according to the wayline file id, + * and redirect to this address directly for download. + * @param workspaceId + * @param waylineId + * @param req + * @param rsp + */ + @Override + public void getWaylineFileDownloadAddress(String workspaceId, String waylineId, HttpServletRequest req, HttpServletResponse rsp) { + try { + URL url = waylineFileService.getObjectUrl(workspaceId, waylineId); + rsp.sendRedirect(url.toString()); + + } catch (IOException | SQLException e) { + e.printStackTrace(); + } + } + + /** + * Checking whether the name already exists according to the wayline name must ensure the uniqueness of the wayline name. + * This interface will be called when uploading waylines and must be available. + * @param workspaceId + * @param names + * @return + */ + @Override + public HttpResultResponse> getDuplicatedWaylineName(String workspaceId, @NotNull @Size(min = 1) List names, HttpServletRequest req, HttpServletResponse rsp) { + List existNamesList = waylineFileService.getDuplicateNames(workspaceId, names); + + return HttpResultResponse.success(existNamesList); + } + + /** + * When the wayline file is uploaded to the storage server by pilot, + * the basic information of the file is reported through this interface. + * @param request + * @param workspaceId + * @return + */ + @Override + public HttpResultResponse fileUploadResultReport(String workspaceId, @Valid WaylineUploadCallbackRequest request, HttpServletRequest req, HttpServletResponse rsp) { + CustomClaim customClaim = (CustomClaim)req.getAttribute(TOKEN_CLAIM); + + WaylineUploadCallbackMetadata metadata = request.getMetadata(); + + WaylineFileDTO file = WaylineFileDTO.builder() + .username(customClaim.getUsername()) + .objectKey(request.getObjectKey()) + .name(request.getName()) + .templateTypes(metadata.getTemplateTypes().stream().map(WaylineTypeEnum::getValue).collect(Collectors.toList())) + .payloadModelKeys(metadata.getPayloadModelKeys().stream().map(DeviceEnum::getDevice).collect(Collectors.toList())) + .droneModelKey(metadata.getDroneModelKey().getDevice()) + .build(); + + int id = waylineFileService.saveWaylineFile(workspaceId, file); + + return id <= 0 ? HttpResultResponse.error() : HttpResultResponse.success(); + } + + /** + * Favorite the wayline file according to the wayline file id. + * @param workspaceId + * @param ids wayline file id + * @return + */ + @Override + public HttpResultResponse batchFavoritesWayline(String workspaceId, @NotNull @Size(min = 1) List ids, HttpServletRequest req, HttpServletResponse rsp) { + boolean isMark = waylineFileService.markFavorite(workspaceId, ids, true); + + return isMark ? HttpResultResponse.success() : HttpResultResponse.error(); + } + + /** + * Delete the favorites of this wayline file based on the wayline file id. + * @param workspaceId + * @param ids wayline file id + * @return + */ + @Override + public HttpResultResponse batchUnfavoritesWayline(String workspaceId, @NotNull @Size(min = 1) List ids, HttpServletRequest req, HttpServletResponse rsp) { + boolean isMark = waylineFileService.markFavorite(workspaceId, ids, false); + + return isMark ? HttpResultResponse.success() : HttpResultResponse.error(); + } + + /** + * Import kmz wayline files. + * @return + */ + @PostMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/file/save") + public HttpResultResponse importDeptIdKmzFile(HttpServletRequest request, @Valid @RequestBody WaylineFileDTO metadata, + @PathVariable(name = "workspace_id") String workspaceId) { + Integer fileId = waylineFileService.saveWaylineFile(workspaceId, metadata); + if(fileId > 0){ + return HttpResultResponse.success(waylineFileService.getWaylineIdByFileId(fileId)); + } + return HttpResultResponse.error(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineJobController.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineJobController.java new file mode 100644 index 0000000..5d8c259 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineJobController.java @@ -0,0 +1,102 @@ +package com.dji.sample.wayline.controller; + +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.wayline.model.dto.WaylineJobDTO; +import com.dji.sample.wayline.model.param.CreateJobParam; +import com.dji.sample.wayline.model.param.UpdateJobParam; +import com.dji.sample.wayline.service.IFlightTaskService; +import com.dji.sample.wayline.service.IWaylineJobService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.PaginationData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.sql.SQLException; +import java.util.Set; + +import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@RequestMapping("${url.wayline.prefix}${url.wayline.version}/workspaces") +@RestController +public class WaylineJobController { + + @Autowired + private IWaylineJobService waylineJobService; + + @Autowired + private IFlightTaskService flighttaskService; + + /** + * Create a wayline task for the Dock. + * @param request + * @param param + * @param workspaceId + * @return + * @throws SQLException + */ + @PostMapping("/{workspace_id}/flight-tasks") + public HttpResultResponse createJob(HttpServletRequest request, @Valid @RequestBody CreateJobParam param, + @PathVariable(name = "workspace_id") String workspaceId) throws SQLException { + CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM); + customClaim.setWorkspaceId(workspaceId); + + return flighttaskService.publishFlightTask(param, customClaim); + } + + /** + * Paginate through all jobs in this workspace. + * @param page + * @param pageSize + * @param workspaceId + * @return + */ + @GetMapping("/{workspace_id}/jobs") + public HttpResultResponse> getJobs(@RequestParam(defaultValue = "1") Long page, + @RequestParam(name = "page_size", defaultValue = "10") Long pageSize, + @PathVariable(name = "workspace_id") String workspaceId) { + PaginationData data = waylineJobService.getJobsByWorkspaceId(workspaceId, page, pageSize); + return HttpResultResponse.success(data); + } + + /** + * Send the command to cancel the jobs. + * @param jobIds + * @param workspaceId + * @return + * @throws SQLException + */ + @DeleteMapping("/{workspace_id}/jobs") + public HttpResultResponse publishCancelJob(@RequestParam(name = "job_id") Set jobIds, + @PathVariable(name = "workspace_id") String workspaceId) throws SQLException { + flighttaskService.cancelFlightTask(workspaceId, jobIds); + return HttpResultResponse.success(); + } + + /** + * Set the media files for this job to upload immediately. + * @param workspaceId + * @param jobId + * @return + */ + @PostMapping("/{workspace_id}/jobs/{job_id}/media-highest") + public HttpResultResponse uploadMediaHighestPriority(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "job_id") String jobId) { + flighttaskService.uploadMediaHighestPriority(workspaceId, jobId); + return HttpResultResponse.success(); + } + + @PutMapping("/{workspace_id}/jobs/{job_id}") + public HttpResultResponse updateJobStatus(@PathVariable(name = "workspace_id") String workspaceId, + @PathVariable(name = "job_id") String jobId, + @Valid @RequestBody UpdateJobParam param) { + flighttaskService.updateJobStatus(workspaceId, jobId, param); + return HttpResultResponse.success(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/dao/IWaylineFileMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/dao/IWaylineFileMapper.java new file mode 100644 index 0000000..5537e4f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/dao/IWaylineFileMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.wayline.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.wayline.model.entity.WaylineFileEntity; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +public interface IWaylineFileMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/dao/IWaylineJobMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/dao/IWaylineJobMapper.java new file mode 100644 index 0000000..9a18c69 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/dao/IWaylineJobMapper.java @@ -0,0 +1,12 @@ +package com.dji.sample.wayline.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dji.sample.wayline.model.entity.WaylineJobEntity; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +public interface IWaylineJobMapper extends BaseMapper { +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/ConditionalWaylineJobKey.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/ConditionalWaylineJobKey.java new file mode 100644 index 0000000..2dd1ca2 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/ConditionalWaylineJobKey.java @@ -0,0 +1,39 @@ +package com.dji.sample.wayline.model.dto; + +import com.dji.sample.component.redis.RedisConst; +import lombok.Data; + +import java.util.Objects; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/28 + */ +@Data +public class ConditionalWaylineJobKey { + + private String workspaceId; + + private String dockSn; + + private String jobId; + + public ConditionalWaylineJobKey(String workspaceId, String dockSn, String jobId) { + this.workspaceId = workspaceId; + this.dockSn = dockSn; + this.jobId = jobId; + } + + public ConditionalWaylineJobKey(String key) { + if (Objects.isNull(key)) { + return; + } + String[] keyArr = key.split(RedisConst.DELIMITER); + new ConditionalWaylineJobKey(keyArr[0], keyArr[1], keyArr[2]); + } + + public String getKey() { + return String.join(RedisConst.DELIMITER, workspaceId, dockSn, jobId); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/FlighttaskProgressExt.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/FlighttaskProgressExt.java new file mode 100644 index 0000000..a04ea45 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/FlighttaskProgressExt.java @@ -0,0 +1,20 @@ +package com.dji.sample.wayline.model.dto; + +import lombok.Data; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +@Data +public class FlighttaskProgressExt { + + private Integer currentWaypointIndex; + + private Integer mediaCount; + + private String flightId; + + private String trackId; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/FlighttaskProgressProgress.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/FlighttaskProgressProgress.java new file mode 100644 index 0000000..46e525d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/FlighttaskProgressProgress.java @@ -0,0 +1,16 @@ +package com.dji.sample.wayline.model.dto; + +import lombok.Data; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +@Data +public class FlighttaskProgressProgress { + + private Integer currentStep; + + private Integer percent; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/KmzFileProperties.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/KmzFileProperties.java new file mode 100644 index 0000000..f729961 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/KmzFileProperties.java @@ -0,0 +1,39 @@ +package com.dji.sample.wayline.model.dto; + +/** + * @author sean + * @version 1.3 + * @date 2022/10/27 + */ +public class KmzFileProperties { + + private KmzFileProperties() { + + } + + public static final String WAYLINE_FILE_SUFFIX = ".kmz"; + + public static final String FILE_DIR_FIRST = "wpmz"; + + public static final String FILE_DIR_SECOND_RES = "res"; + + public static final String FILE_DIR_SECOND_TEMPLATE = "template.kml"; + + public static final String FILE_DIR_SECOND_WAYLINES = "waylines.wpml"; + + public static final String TAG_WPML_PREFIX = "wpml:"; + + public static final String TAG_DRONE_INFO = "droneInfo"; + + public static final String TAG_DRONE_ENUM_VALUE = "droneEnumValue"; + + public static final String TAG_DRONE_SUB_ENUM_VALUE = "droneSubEnumValue"; + + public static final String TAG_PAYLOAD_INFO = "payloadInfo"; + + public static final String TAG_PAYLOAD_ENUM_VALUE = "payloadEnumValue"; + + public static final String TAG_PAYLOAD_SUB_ENUM_VALUE = "payloadSubEnumValue"; + + public static final String TAG_TEMPLATE_TYPE = "templateType"; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineFileDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineFileDTO.java new file mode 100644 index 0000000..8e6282a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineFileDTO.java @@ -0,0 +1,43 @@ +package com.dji.sample.wayline.model.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class WaylineFileDTO { + + private String name; + + @JsonProperty("id") + private String waylineId; + + private String droneModelKey; + + private String sign; + + private List payloadModelKeys; + + private Boolean favorited; + + private List templateTypes; + + private String objectKey; + + @JsonProperty("user_name") + private String username; + + private Long updateTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineJobBreakPointDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineJobBreakPointDTO.java new file mode 100644 index 0000000..ca59f2f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineJobBreakPointDTO.java @@ -0,0 +1,36 @@ +package com.dji.sample.wayline.model.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Data +public class WaylineJobBreakPointDTO { + + /** + * 断点序号 + */ + private Integer index; + + /** + * 断点状态 + * {"0":"在航段上","1":"在航点上"} + */ + private Integer state; + + /** + * {"min":"0","max":"1.0"} + */ + private Float progress; + + /** + * 航线 ID + */ + @JsonProperty(value = "wayline_id") + private Integer waylineId; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineJobDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineJobDTO.java new file mode 100644 index 0000000..0d38d59 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineJobDTO.java @@ -0,0 +1,71 @@ +package com.dji.sample.wayline.model.dto; + +import com.dji.sdk.cloudapi.wayline.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class WaylineJobDTO { + + private String jobId; + + private String jobName; + + private String fileId; + + private String fileName; + + private String dockSn; + + private String dockName; + + private String workspaceId; + + private WaylineTypeEnum waylineType; + + private TaskTypeEnum taskType; + + private LocalDateTime executeTime; + + private LocalDateTime beginTime; + + private LocalDateTime endTime; + + private LocalDateTime completedTime; + + private Integer status; + + private Integer progress; + + private String username; + + private Integer code; + + private Integer rthAltitude; + + private OutOfControlActionEnum outOfControlAction; + + private Integer mediaCount; + + private Integer uploadedCount; + + private Boolean uploading; + + private WaylineTaskConditionDTO conditions; + + private String parentId; + + private ProgressExtBreakPoint breakPoint; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskConditionDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskConditionDTO.java new file mode 100644 index 0000000..c924b07 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskConditionDTO.java @@ -0,0 +1,24 @@ +package com.dji.sample.wayline.model.dto; + +import com.dji.sdk.cloudapi.wayline.ExecutableConditions; +import com.dji.sdk.cloudapi.wayline.ReadyConditions; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/16 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class WaylineTaskConditionDTO { + + private ReadyConditions readyConditions; + + private ExecutableConditions executableConditions; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskCreateBreakPointDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskCreateBreakPointDTO.java new file mode 100644 index 0000000..054e238 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskCreateBreakPointDTO.java @@ -0,0 +1,41 @@ +package com.dji.sample.wayline.model.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class WaylineTaskCreateBreakPointDTO { + + /** + * 断点序号 + */ + private Integer index; + + /** + * 断点状态 + * {"0":"在航段上","1":"在航点上"} + */ + private Integer state; + + /** + * {"min":"0","max":"1.0"} + */ + private Float progress; + + /** + * 航线 ID + */ + @JsonProperty(value = "wayline_id") + private Integer waylineId; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskCreateDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskCreateDTO.java new file mode 100644 index 0000000..da6fe1c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskCreateDTO.java @@ -0,0 +1,38 @@ +package com.dji.sample.wayline.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class WaylineTaskCreateDTO { + + private String flightId; + + private Integer taskType; + + private Integer waylineType; + + private Long executeTime; + + private WaylineTaskFileDTO file; + + private Integer rthAltitude; + + private Integer outOfControlAction; + + private WaylineTaskReadyConditionDTO readyConditions; + + private WaylineTaskExecutableConditionDTO executableConditions; + + private WaylineTaskCreateBreakPointDTO breakPoint; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskExecutableConditionDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskExecutableConditionDTO.java new file mode 100644 index 0000000..24cfc4c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskExecutableConditionDTO.java @@ -0,0 +1,23 @@ +package com.dji.sample.wayline.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/16 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class WaylineTaskExecutableConditionDTO { + + /** + * unit: MB + */ + private Integer storageCapacity; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskFileDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskFileDTO.java new file mode 100644 index 0000000..604eb9d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskFileDTO.java @@ -0,0 +1,22 @@ +package com.dji.sample.wayline.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class WaylineTaskFileDTO { + + private String url; + + private String fingerprint; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskProgressReceiver.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskProgressReceiver.java new file mode 100644 index 0000000..75671c4 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskProgressReceiver.java @@ -0,0 +1,19 @@ +package com.dji.sample.wayline.model.dto; + +import lombok.Data; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +@Data +public class WaylineTaskProgressReceiver { + + private FlighttaskProgressExt ext; + + private FlighttaskProgressProgress progress; + + private String status; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskReadyConditionDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskReadyConditionDTO.java new file mode 100644 index 0000000..61fe5a7 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineTaskReadyConditionDTO.java @@ -0,0 +1,24 @@ +package com.dji.sample.wayline.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/16 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class WaylineTaskReadyConditionDTO { + + private Integer batteryCapacity; + + private Long beginTime; + + private Long endTime; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/entity/WaylineFileEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/entity/WaylineFileEntity.java new file mode 100644 index 0000000..27be0bf --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/entity/WaylineFileEntity.java @@ -0,0 +1,62 @@ +package com.dji.sample.wayline.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Data +@TableName("wayline_file") +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class WaylineFileEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField("name") + private String name; + + @TableField("wayline_id") + private String waylineId; + + @TableField("drone_model_key") + private String droneModelKey; + + @TableField("payload_model_keys") + private String payloadModelKeys; + + @TableField("sign") + private String sign; + + @TableField("workspace_id") + private String workspaceId; + + @TableField("favorited") + private Boolean favorited; + + @TableField("template_types") + private String templateTypes; + + @TableField("object_key") + private String objectKey; + + @TableField("user_name") + private String username; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/entity/WaylineJobEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/entity/WaylineJobEntity.java new file mode 100644 index 0000000..93f1637 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/entity/WaylineJobEntity.java @@ -0,0 +1,90 @@ +package com.dji.sample.wayline.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.dji.sdk.cloudapi.wayline.FlighttaskBreakPoint; +import com.dji.sdk.cloudapi.wayline.ProgressExtBreakPoint; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("wayline_job") +public class WaylineJobEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField("job_id") + private String jobId; + + @TableField("name") + private String name; + + @TableField("file_id") + private String fileId; + + @TableField("dock_sn") + private String dockSn; + + @TableField("workspace_id") + private String workspaceId; + + @TableField("task_type") + private Integer taskType; + + @TableField("wayline_type") + private Integer waylineType; + + @TableField("username") + private String username; + + @TableField("execute_time") + private Long executeTime; + + @TableField("end_time") + private Long endTime; + + @TableField("error_code") + private Integer errorCode; + + @TableField("status") + private Integer status; + + @TableField("rth_altitude") + private Integer rthAltitude; + + @TableField("out_of_control") + private Integer outOfControlAction; + + @TableField("media_count") + private Integer mediaCount; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Long createTime; + + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private Long updateTime; + + @TableField("begin_time") + private Long beginTime; + + @TableField("completed_time") + private Long completedTime; + + @TableField("parent_id") + private String parentId; + + @TableField(exist = false) + private ProgressExtBreakPoint breakPoint; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineErrorCodeEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineErrorCodeEnum.java new file mode 100644 index 0000000..45b42a1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineErrorCodeEnum.java @@ -0,0 +1,83 @@ +package com.dji.sample.wayline.model.enums; + +import com.dji.sdk.common.IErrorInfo; +import com.fasterxml.jackson.annotation.JsonCreator; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/17 + */ +public enum WaylineErrorCodeEnum implements IErrorInfo { + + SUCCESS(0, "success", false), + + EMERGENCY_BUTTON(316026, "机箱上的紧急按钮被按下了。", true), + + NOT_IDLE(319001, "任务中心当前未处于空闲状态。", true), + + PERFORMING_TASK(319016, "机箱正在执行其他任务。", true), + + EXPORTING_LOGS(319018, "机箱正在导出日志。", true), + + PULLING_LOGS(319019, "机箱正在拉日志。", true), + + HEIGHT_LIMIT(321513, "航线高度已超过无人机的高度限制。", true), + + DISTANCE_LIMIT(321514, "路线距离已超过无人机的限制。", true), + + RESTRICTED_FLIGHT_AREA(321515, "航线通过一个飞行禁区。", true), + + SDR_DISCONNECT(514120, "机箱和无人机之间的sdr链路断开。", true), + + HEAVY_RAIN(514134, "大雨使飞行受阻。", true), + + STRONG_WIND(514135, "强风使飞行受阻。", true), + + POWER_DISCONNECT(514136, "机箱的电源已断开。", true), + + LOW_TEMPERATURE(514137, "环境的低温使飞行受阻。", true), + + DEBUGGING(514145, "机箱正在调试中。", true), + + REMOTE_DEBUGGING(514146, "正在远程调试机箱", true), + + DOCK_UPGRADING(514147, "机箱正在升级。", true), + + DOCK_WORKING(514148, "机箱正在工作,无法执行新任务。", true), + + UNKNOWN(-1, "未知路线错误。", false); + + private String msg; + + private int code; + + boolean block; + + WaylineErrorCodeEnum(int code, String msg, boolean block) { + this.code = code; + this.msg = msg; + this.block = block; + } + + @Override + public String getMessage() { + return msg; + } + + @Override + public Integer getCode() { + return code; + } + + public boolean isBlock() { + return block; + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static WaylineErrorCodeEnum find(int code) { + return Arrays.stream(WaylineErrorCodeEnum.values()).filter(error -> error.code == code).findAny().orElse(UNKNOWN); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineJobStatusEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineJobStatusEnum.java new file mode 100644 index 0000000..dcd5bb7 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineJobStatusEnum.java @@ -0,0 +1,41 @@ +package com.dji.sample.wayline.model.enums; + +import lombok.Getter; + +import java.util.Arrays; + +/** + * @author sean + * @version 1.3 + * @date 2022/9/26 + */ +@Getter +public enum WaylineJobStatusEnum { + + PENDING(1, false), + + IN_PROGRESS(2, false), + + SUCCESS(3, true), + + CANCEL(4, true), + + FAILED(5, true), + + PAUSED(6, false), + + UNKNOWN(-1, true); + + int val; + + Boolean end; + + WaylineJobStatusEnum(int val, boolean end) { + this.end = end; + this.val = val; + } + + public static WaylineJobStatusEnum find(int val) { + return Arrays.stream(WaylineJobStatusEnum.values()).filter(statue -> statue.val == val).findAny().orElse(UNKNOWN); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineMethodEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineMethodEnum.java new file mode 100644 index 0000000..6ad9807 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineMethodEnum.java @@ -0,0 +1,28 @@ +package com.dji.sample.wayline.model.enums; + +import lombok.Getter; + +/** + * @author sean + * @version 1.3 + * @date 2022/11/14 + */ +@Getter +public enum WaylineMethodEnum { + + FLIGHT_TASK_PREPARE("flighttask_prepare"), + + FLIGHT_TASK_EXECUTE("flighttask_execute"), + + FLIGHT_TASK_CANCEL("flighttask_undo"), + + FLIGHT_TASK_PAUSE("flighttask_pause"), + + FLIGHT_TASK_RESUME("flighttask_recovery"); + + private String method; + + WaylineMethodEnum(String method) { + this.method = method; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineTaskStatusEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineTaskStatusEnum.java new file mode 100644 index 0000000..9bdf4f6 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineTaskStatusEnum.java @@ -0,0 +1,19 @@ +package com.dji.sample.wayline.model.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/1 + */ +public enum WaylineTaskStatusEnum { + + PAUSE, RESUME; + + @JsonValue + public int getVal() { + return ordinal(); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineTemplateTypeEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineTemplateTypeEnum.java new file mode 100644 index 0000000..760fc8d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/enums/WaylineTemplateTypeEnum.java @@ -0,0 +1,46 @@ +package com.dji.sample.wayline.model.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; +import java.util.Optional; + +/** + * @author sean + * @version 1.3 + * @date 2022/9/26 + */ +public enum WaylineTemplateTypeEnum { + + WAYPOINT(0, "waypoint"), + + MAPPING_2D(1, "mapping2d"), + + MAPPING_3D(2, "mapping3d"), + + MAPPING_STRIP(4, "mappingStrip"); + + int val; + + String type; + + WaylineTemplateTypeEnum(int val, String type) { + this.val = val; + this.type = type; + } + + @JsonValue + public int getVal() { + return val; + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static WaylineTemplateTypeEnum find(Integer val) { + return Arrays.stream(values()).filter(templateTypeEnum -> templateTypeEnum.val == val).findAny().get(); + } + + public static Optional find(String type) { + return Arrays.stream(values()).filter(templateTypeEnum -> templateTypeEnum.type.equals(type)).findAny(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/CreateJobBreakPointParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/CreateJobBreakPointParam.java new file mode 100644 index 0000000..da09921 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/CreateJobBreakPointParam.java @@ -0,0 +1,37 @@ +package com.dji.sample.wayline.model.param; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Data +public class CreateJobBreakPointParam { + + /** + * 断点序号 + */ + private Integer index; + + /** + * 断点状态 + * {"0":"在航段上","1":"在航点上"} + */ + private Integer state; + + /** + * {"min":"0","max":"1.0"} + */ + private Float progress; + + /** + * 航线 ID + */ + @JsonProperty(value = "wayline_id") + private Integer waylineId; + + private String jobId; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/CreateJobParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/CreateJobParam.java new file mode 100644 index 0000000..e6ce07c --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/CreateJobParam.java @@ -0,0 +1,56 @@ +package com.dji.sample.wayline.model.param; + +import com.dji.sdk.cloudapi.wayline.OutOfControlActionEnum; +import com.dji.sdk.cloudapi.wayline.ProgressExtBreakPoint; +import com.dji.sdk.cloudapi.wayline.TaskTypeEnum; +import com.dji.sdk.cloudapi.wayline.WaylineTypeEnum; +import lombok.Data; +import org.hibernate.validator.constraints.Range; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Data +public class CreateJobParam { + + private String jobId; + + @NotBlank + private String name; + + @NotBlank + private String fileId; + + @NotBlank + private String dockSn; + + @NotNull + private WaylineTypeEnum waylineType; + + @NotNull + private TaskTypeEnum taskType; + + @Range(min = 20, max = 500) + @NotNull + private Integer rthAltitude; + + @NotNull + private OutOfControlActionEnum outOfControlAction; + + @Range(min = 50, max = 90) + private Integer minBatteryCapacity; + + private Integer minStorageCapacity; + + private List taskDays; + + private List> taskPeriods; + + private ProgressExtBreakPoint breakPoint; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/UpdateJobParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/UpdateJobParam.java new file mode 100644 index 0000000..dfa8e37 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/UpdateJobParam.java @@ -0,0 +1,22 @@ +package com.dji.sample.wayline.model.param; + +import com.dji.sample.wayline.model.enums.WaylineTaskStatusEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 1.3 + * @date 2023/2/1 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class UpdateJobParam { + + private WaylineTaskStatusEnum status; + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/WaylineQueryParam.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/WaylineQueryParam.java new file mode 100644 index 0000000..e0c39ce --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/param/WaylineQueryParam.java @@ -0,0 +1,30 @@ +package com.dji.sample.wayline.model.param; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class WaylineQueryParam { + + private boolean favorited; + + @Builder.Default + private int page = 1; + + @Builder.Default + private int pageSize = 10; + + private String orderBy; + + private Integer[] templateType; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IFlightTaskService.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IFlightTaskService.java new file mode 100644 index 0000000..79c4857 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IFlightTaskService.java @@ -0,0 +1,78 @@ +package com.dji.sample.wayline.service; + +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.wayline.model.dto.ConditionalWaylineJobKey; +import com.dji.sample.wayline.model.dto.WaylineJobDTO; +import com.dji.sample.wayline.model.param.CreateJobParam; +import com.dji.sample.wayline.model.param.UpdateJobParam; +import com.dji.sdk.common.HttpResultResponse; + +import java.sql.SQLException; +import java.util.Collection; +import java.util.List; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +public interface IFlightTaskService { + + + /** + * Issue wayline mission to the dock. + * @param param + * @param customClaim user info + * @return + */ + HttpResultResponse publishFlightTask(CreateJobParam param, CustomClaim customClaim) throws SQLException; + + /** + * Issue wayline mission to the dock. + * @param waylineJob + * @return + * @throws SQLException + */ + HttpResultResponse publishOneFlightTask(WaylineJobDTO waylineJob) throws SQLException; + + /** + * Execute the task immediately. + * @param jobId + * @throws SQLException + * @return + */ + Boolean executeFlightTask(String workspaceId, String jobId); + + /** + * Cancel the task Base on job Ids. + * @param workspaceId + * @param jobIds + * @throws SQLException + */ + void cancelFlightTask(String workspaceId, Collection jobIds); + + /** + * Cancel the dock tasks that have been issued but have not yet been executed. + * @param workspaceId + * @param dockSn + * @param jobIds + */ + void publishCancelTask(String workspaceId, String dockSn, List jobIds); + + /** + * Set the media files for this job to upload immediately. + * @param workspaceId + * @param jobId + */ + void uploadMediaHighestPriority(String workspaceId, String jobId); + + /** + * Manually control the execution status of wayline job. + * @param workspaceId + * @param jobId + * @param param + */ + void updateJobStatus(String workspaceId, String jobId, UpdateJobParam param); + + void retryPrepareJob(ConditionalWaylineJobKey jobKey, WaylineJobDTO waylineJob); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineFileService.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineFileService.java new file mode 100644 index 0000000..d48d7ca --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineFileService.java @@ -0,0 +1,87 @@ +package com.dji.sample.wayline.service; + +import com.dji.sample.wayline.model.dto.WaylineFileDTO; +import com.dji.sdk.cloudapi.wayline.GetWaylineListRequest; +import com.dji.sdk.cloudapi.wayline.GetWaylineListResponse; +import com.dji.sdk.common.PaginationData; +import org.springframework.web.multipart.MultipartFile; + +import java.net.URL; +import java.sql.SQLException; +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +public interface IWaylineFileService { + + /** + * Perform paging queries based on query parameters. + * @param workspaceId + * @param param + * @return + */ + PaginationData getWaylinesByParam(String workspaceId, GetWaylineListRequest param); + + /** + * Query the information of this wayline file according to the wayline file id. + * @param workspaceId + * @param waylineId + * @return + */ + Optional getWaylineByWaylineId(String workspaceId, String waylineId); + + /** + * Get the download address of the file object. + * @param workspaceId + * @param waylineId + * @return + */ + URL getObjectUrl(String workspaceId, String waylineId) throws SQLException; + + /** + * Save the basic information of the wayline file. + * @param workspaceId + * @param metadata + * @return + */ + Integer saveWaylineFile(String workspaceId, WaylineFileDTO metadata); + + /** + * Updates whether the file is collected or not based on the passed parameters. + * @param workspaceId + * @param ids wayline id + * @param isFavorite Whether the wayline file is favorited or not. + * @return + */ + Boolean markFavorite(String workspaceId, List ids, Boolean isFavorite); + + /** + * Batch query for duplicate file names in workspace. + * @param workspaceId + * @param names + * @return + */ + List getDuplicateNames(String workspaceId, List names); + + /** + * Delete the wayline file based on the wayline id. + * @param workspaceId + * @param waylineId + */ + Boolean deleteByWaylineId(String workspaceId, String waylineId); + + /** + * Import kmz wayline file. + * @param file + * @param workspaceId + * @param creator + * @return + */ + void importKmzFile(MultipartFile file, String workspaceId, String creator); + + String getWaylineIdByFileId(Integer fileId); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineJobService.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineJobService.java new file mode 100644 index 0000000..1b5c84f --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineJobService.java @@ -0,0 +1,77 @@ +package com.dji.sample.wayline.service; + +import com.dji.sample.wayline.model.dto.WaylineJobDTO; +import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum; +import com.dji.sample.wayline.model.param.CreateJobParam; +import com.dji.sdk.common.PaginationData; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +public interface IWaylineJobService { + + /** + * Create wayline job in the database. + * @param param + * @param workspaceId user info + * @param username user info + * @param beginTime The time the job started. + * @param endTime The time the job ended. + * @return + */ + Optional createWaylineJob(CreateJobParam param, String workspaceId, String username, Long beginTime, Long endTime); + + /** + * Create a sub-task based on the information of the parent task. + * @param workspaceId + * @param parentId + * @return + */ + Optional createWaylineJobByParent(String workspaceId, String parentId); + + /** + * Query wayline jobs based on conditions. + * @param workspaceId + * @param jobIds + * @param status + * @return + */ + List getJobsByConditions(String workspaceId, Collection jobIds, WaylineJobStatusEnum status); + + /** + * Query job information based on job id. + * @param workspaceId + * @param jobId + * @return job information + */ + Optional getJobByJobId(String workspaceId, String jobId); + + /** + * Update job data. + * @param dto + * @return + */ + Boolean updateJob(WaylineJobDTO dto); + + /** + * Paginate through all jobs in this workspace. + * @param workspaceId + * @param page + * @param pageSize + * @return + */ + PaginationData getJobsByWorkspaceId(String workspaceId, long page, long pageSize); + + /** + * Query the wayline execution status of the dock. + * @param dockSn + * @return + */ + WaylineJobStatusEnum getWaylineState(String dockSn); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineRedisService.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineRedisService.java new file mode 100644 index 0000000..7230c50 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineRedisService.java @@ -0,0 +1,100 @@ +package com.dji.sample.wayline.service; + +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.wayline.model.dto.ConditionalWaylineJobKey; +import com.dji.sample.wayline.model.dto.WaylineJobDTO; +import com.dji.sdk.cloudapi.wayline.FlighttaskProgress; + +import java.util.Optional; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/24 + */ +public interface IWaylineRedisService { + + /** + * Save the status of the wayline job performed by the dock into redis. + * @param dockSn + * @param data + */ + void setRunningWaylineJob(String dockSn, EventsReceiver data); + + /** + * Query the status of wayline job performed by the dock in redis. + * @param dockSn + * @return + */ + Optional> getRunningWaylineJob(String dockSn); + + /** + * Delete the wayline job status of the dock operation in redis. + * @param dockSn + * @return + */ + Boolean delRunningWaylineJob(String dockSn); + + /** + * Save the wayline job suspended by the dock to redis. + * @param dockSn + * @param jobId + */ + void setPausedWaylineJob(String dockSn, String jobId); + + /** + * Query the wayline job id suspended by the dock in redis. + * @param dockSn + * @return + */ + String getPausedWaylineJobId(String dockSn); + + /** + * Delete the wayline job suspended by the dock in redis. + * @param dockSn + * @return + */ + Boolean delPausedWaylineJob(String dockSn); + + /** + * Save the wayline job blocked by the dock to redis. + * @param dockSn + * @param jobId + */ + void setBlockedWaylineJob(String dockSn, String jobId); + + /** + * Query the wayline job id blocked by the dock in redis. + * @param dockSn + * @return + */ + String getBlockedWaylineJobId(String dockSn); + + /** + * Save the conditional wayline job by the dock to redis. + * @param waylineJob + */ + void setConditionalWaylineJob(WaylineJobDTO waylineJob); + + /** + * Query the conditional wayline job id by the dock in redis. + * @param jobId + * @return + */ + Optional getConditionalWaylineJob(String jobId); + + /** + * Delete the conditional wayline job by the dock in redis. + * @param jobId + * @return + */ + Boolean delConditionalWaylineJob(String jobId); + + Boolean addPrepareConditionalWaylineJob(WaylineJobDTO waylineJob); + + Optional getNearestConditionalWaylineJob(); + + Double getConditionalWaylineJobTime(ConditionalWaylineJobKey jobKey); + + Boolean removePrepareConditionalWaylineJob(ConditionalWaylineJobKey jobKey); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/FlightTaskServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/FlightTaskServiceImpl.java new file mode 100644 index 0000000..cdef858 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/FlightTaskServiceImpl.java @@ -0,0 +1,560 @@ +package com.dji.sample.wayline.service.impl; + +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.common.model.CustomClaim; +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.media.model.MediaFileCountDTO; +import com.dji.sample.media.service.IMediaRedisService; +import com.dji.sample.wayline.model.dto.ConditionalWaylineJobKey; +import com.dji.sample.wayline.model.dto.WaylineJobDTO; +import com.dji.sample.wayline.model.dto.WaylineTaskConditionDTO; +import com.dji.sample.wayline.model.enums.WaylineErrorCodeEnum; +import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum; +import com.dji.sample.wayline.model.param.CreateJobParam; +import com.dji.sample.wayline.model.param.UpdateJobParam; +import com.dji.sample.wayline.service.IFlightTaskService; +import com.dji.sample.wayline.service.IWaylineFileService; +import com.dji.sample.wayline.service.IWaylineJobService; +import com.dji.sample.wayline.service.IWaylineRedisService; +import com.dji.sdk.cloudapi.device.ExitWaylineWhenRcLostEnum; +import com.dji.sdk.cloudapi.media.UploadFlighttaskMediaPrioritize; +import com.dji.sdk.cloudapi.media.api.AbstractMediaService; +import com.dji.sdk.cloudapi.wayline.*; +import com.dji.sdk.cloudapi.wayline.api.AbstractWaylineService; +import com.dji.sdk.common.HttpResultResponse; +import com.dji.sdk.common.SDKManager; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.services.ServicesReplyData; +import com.dji.sdk.mqtt.services.TopicServicesResponse; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.messaging.MessageHeaders; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.net.URL; +import java.sql.SQLException; +import java.time.*; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/9 + */ +@Service +@Slf4j +public class FlightTaskServiceImpl extends AbstractWaylineService implements IFlightTaskService { + + @Autowired + private ObjectMapper mapper; + + @Autowired + private IWebSocketMessageService websocketMessageService; + + @Autowired + private IWaylineJobService waylineJobService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private IWaylineRedisService waylineRedisService; + + @Autowired + private IMediaRedisService mediaRedisService; + + @Autowired + private IWaylineFileService waylineFileService; + + @Autowired + private SDKWaylineService abstractWaylineService; + + @Autowired + @Qualifier("mediaServiceImpl") + private AbstractMediaService abstractMediaService; + + @Scheduled(initialDelay = 10, fixedRate = 5, timeUnit = TimeUnit.SECONDS) + public void checkScheduledJob() { + Object jobIdValue = RedisOpsUtils.zGetMin(RedisConst.WAYLINE_JOB_TIMED_EXECUTE); + if (Objects.isNull(jobIdValue)) { + return; + } + log.info("检查路线的定时任务。 {}", jobIdValue); + // format: {workspace_id}:{dock_sn}:{job_id} + String[] jobArr = String.valueOf(jobIdValue).split(RedisConst.DELIMITER); + double time = RedisOpsUtils.zScore(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue); + long now = System.currentTimeMillis(); + int offset = 30_000; + + // Expired tasks are deleted directly. + if (time < now - offset) { + RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue); + waylineJobService.updateJob(WaylineJobDTO.builder() + .jobId(jobArr[2]) + .status(WaylineJobStatusEnum.FAILED.getVal()) + .executeTime(LocalDateTime.now()) + .completedTime(LocalDateTime.now()) + .code(HttpStatus.SC_REQUEST_TIMEOUT).build()); + return; + } + + if (now <= time && time <= now + offset) { + try { + this.executeFlightTask(jobArr[0], jobArr[2]); + } catch (Exception e) { + log.info("计划的任务传递失败。"); + waylineJobService.updateJob(WaylineJobDTO.builder() + .jobId(jobArr[2]) + .status(WaylineJobStatusEnum.FAILED.getVal()) + .executeTime(LocalDateTime.now()) + .completedTime(LocalDateTime.now()) + .code(HttpStatus.SC_INTERNAL_SERVER_ERROR).build()); + } finally { + RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, jobIdValue); + } + } + } + + @Scheduled(initialDelay = 10, fixedRate = 5, timeUnit = TimeUnit.SECONDS) + public void prepareConditionJob() { + Optional jobKeyOpt = waylineRedisService.getNearestConditionalWaylineJob(); + if (jobKeyOpt.isEmpty()) { + return; + } + ConditionalWaylineJobKey jobKey = jobKeyOpt.get(); + log.info("检查路线的条件任务。 {}", jobKey.toString()); + // format: {workspace_id}:{dock_sn}:{job_id} + double time = waylineRedisService.getConditionalWaylineJobTime(jobKey); + long now = System.currentTimeMillis(); + // prepare the task one day in advance. + int offset = 86_400_000; + + if (now + offset < time) { + return; + } + + WaylineJobDTO job = WaylineJobDTO.builder() + .jobId(jobKey.getJobId()) + .status(WaylineJobStatusEnum.FAILED.getVal()) + .executeTime(LocalDateTime.now()) + .completedTime(LocalDateTime.now()) + .code(HttpStatus.SC_INTERNAL_SERVER_ERROR).build(); + try { + Optional waylineJobOpt = waylineRedisService.getConditionalWaylineJob(jobKey.getJobId()); + if (waylineJobOpt.isEmpty()) { + job.setCode(CommonErrorEnum.REDIS_DATA_NOT_FOUND.getCode()); + waylineJobService.updateJob(job); + waylineRedisService.removePrepareConditionalWaylineJob(jobKey); + return; + } + WaylineJobDTO waylineJob = waylineJobOpt.get(); + + HttpResultResponse result = this.publishOneFlightTask(waylineJob); + waylineRedisService.removePrepareConditionalWaylineJob(jobKey); + + if (HttpResultResponse.CODE_SUCCESS == result.getCode()) { + return; + } + + // If the end time is exceeded, no more retries will be made. + waylineRedisService.delConditionalWaylineJob(jobKey.getJobId()); + if (waylineJob.getEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - RedisConst.WAYLINE_JOB_BLOCK_TIME * 1000 < now) { + return; + } + + // Retry if the end time has not been exceeded. + this.retryPrepareJob(jobKey, waylineJob); + + } catch (Exception e) { + log.info("无法准备条件任务。"); + waylineJobService.updateJob(job); + } + + } + + /** + * For immediate tasks, the server time shall prevail. + * @param param + */ + private void fillImmediateTime(CreateJobParam param) { + if (TaskTypeEnum.IMMEDIATE != param.getTaskType()) { + return; + } + long now = System.currentTimeMillis() / 1000; + param.setTaskDays(List.of(now)); + param.setTaskPeriods(List.of(List.of(now))); + } + + + private void addConditions(WaylineJobDTO waylineJob, CreateJobParam param, Long beginTime, Long endTime) { + if (TaskTypeEnum.CONDITIONAL != param.getTaskType()) { + return; + } + + waylineJob.setConditions( + WaylineTaskConditionDTO.builder() + .executableConditions(Objects.nonNull(param.getMinStorageCapacity()) ? + new ExecutableConditions().setStorageCapacity(param.getMinStorageCapacity()) : null) + .readyConditions(new ReadyConditions() + .setBatteryCapacity(param.getMinBatteryCapacity()) + .setBeginTime(beginTime) + .setEndTime(endTime)) + .build()); + + waylineRedisService.setConditionalWaylineJob(waylineJob); + // key: wayline_job_condition, value: {workspace_id}:{dock_sn}:{job_id} + boolean isAdd = waylineRedisService.addPrepareConditionalWaylineJob(waylineJob); + if (!isAdd) { + throw new RuntimeException("无法创建有条件的作业。"); + } + } + + @Override + public HttpResultResponse publishFlightTask(CreateJobParam param, CustomClaim customClaim) throws SQLException { + fillImmediateTime(param); + for (Long taskDay : param.getTaskDays()) { + LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(taskDay), ZoneId.systemDefault()); + for (List taskPeriod : param.getTaskPeriods()) { + long beginTime = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(taskPeriod.get(0)), ZoneId.systemDefault())) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + long endTime = taskPeriod.size() > 1 ? + LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(taskPeriod.get(1)), ZoneId.systemDefault())) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : beginTime; + if (TaskTypeEnum.IMMEDIATE != param.getTaskType() && endTime < System.currentTimeMillis()) { + continue; + } + + Optional waylineJobOpt = waylineJobService.createWaylineJob(param, customClaim.getWorkspaceId(), customClaim.getUsername(), beginTime, endTime); + if (waylineJobOpt.isEmpty()) { + throw new SQLException("无法创建路线作业。"); + } + WaylineJobDTO waylineJob = waylineJobOpt.get(); + // If it is a conditional task type, add conditions to the job parameters. + addConditions(waylineJob, param, beginTime, endTime); + + HttpResultResponse response = this.publishOneFlightTask(waylineJob); + if (HttpResultResponse.CODE_SUCCESS != response.getCode()) { + return response; + } + } + } + return HttpResultResponse.success(); + } + + public HttpResultResponse publishOneFlightTask(WaylineJobDTO waylineJob) throws SQLException { + + boolean isOnline = deviceRedisService.checkDeviceOnline(waylineJob.getDockSn()); + if (!isOnline) { + throw new RuntimeException("Dock处于脱机状态。"); + } + + boolean isSuccess = this.prepareFlightTask(waylineJob); + if (!isSuccess) { + return HttpResultResponse.error("无法准备作业。"); + } + + // Issue an immediate task execution command. + if (TaskTypeEnum.IMMEDIATE == waylineJob.getTaskType()) { + if (!executeFlightTask(waylineJob.getWorkspaceId(), waylineJob.getJobId())) { + return HttpResultResponse.error("无法执行作业。"); + } + } + + if (TaskTypeEnum.TIMED == waylineJob.getTaskType()) { + // key: wayline_job_timed, value: {workspace_id}:{dock_sn}:{job_id} + boolean isAdd = RedisOpsUtils.zAdd(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, + waylineJob.getWorkspaceId() + RedisConst.DELIMITER + waylineJob.getDockSn() + RedisConst.DELIMITER + waylineJob.getJobId(), + waylineJob.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + if (!isAdd) { + return HttpResultResponse.error("无法创建计划作业。"); + } + } + + return HttpResultResponse.success(); + } + + private Boolean prepareFlightTask(WaylineJobDTO waylineJob) throws SQLException { + // get wayline file + Optional waylineFile = waylineFileService.getWaylineByWaylineId(waylineJob.getWorkspaceId(), waylineJob.getFileId()); + if (waylineFile.isEmpty()) { + throw new SQLException("路线文件不存在。"); + } + + // get file url + URL url = waylineFileService.getObjectUrl(waylineJob.getWorkspaceId(), waylineFile.get().getId()); + + FlighttaskPrepareRequest flightTask = new FlighttaskPrepareRequest() + .setFlightId(waylineJob.getJobId()) + .setExecuteTime(waylineJob.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()) + .setTaskType(waylineJob.getTaskType()) + .setWaylineType(waylineJob.getWaylineType()) + .setRthAltitude(waylineJob.getRthAltitude()) + .setOutOfControlAction(waylineJob.getOutOfControlAction()) + .setExitWaylineWhenRcLost(ExitWaylineWhenRcLostEnum.EXECUTE_RC_LOST_ACTION) + .setFile(new FlighttaskFile() + .setUrl(url.toString()) + .setFingerprint(waylineFile.get().getSign())); + + if(waylineJob.getBreakPoint() != null){ + FlighttaskBreakPoint flighttaskBreakPoint = new FlighttaskBreakPoint().setIndex(waylineJob.getBreakPoint().getIndex()).setState(waylineJob.getBreakPoint().getState()).setProgress(waylineJob.getBreakPoint().getProgress()).setWaylineId(waylineJob.getBreakPoint().getWaylineId()); + flightTask.setBreakPoint(flighttaskBreakPoint); + } + + if (TaskTypeEnum.CONDITIONAL == waylineJob.getTaskType()) { + if (Objects.isNull(waylineJob.getConditions())) { + throw new IllegalArgumentException(); + } + flightTask.setReadyConditions(waylineJob.getConditions().getReadyConditions()); + flightTask.setExecutableConditions(waylineJob.getConditions().getExecutableConditions()); + } + + TopicServicesResponse serviceReply = abstractWaylineService.flighttaskPrepare( + SDKManager.getDeviceSDK(waylineJob.getDockSn()), flightTask); + if (!serviceReply.getData().getResult().isSuccess()) { + log.info("准备任务 ====> 错误代码: {}", serviceReply.getData().getResult()); + waylineJobService.updateJob(WaylineJobDTO.builder() + .workspaceId(waylineJob.getWorkspaceId()) + .jobId(waylineJob.getJobId()) + .executeTime(LocalDateTime.now()) + .status(WaylineJobStatusEnum.FAILED.getVal()) + .completedTime(LocalDateTime.now()) + .code(serviceReply.getData().getResult().getCode()).build()); + return false; + } + return true; + } + + + @Override + public Boolean executeFlightTask(String workspaceId, String jobId) { + // get job + Optional waylineJob = waylineJobService.getJobByJobId(workspaceId, jobId); + if (waylineJob.isEmpty()) { + throw new IllegalArgumentException("作业不存在。"); + } + + boolean isOnline = deviceRedisService.checkDeviceOnline(waylineJob.get().getDockSn()); + if (!isOnline) { + throw new RuntimeException("Dock处于脱机状态。"); + } + + WaylineJobDTO job = waylineJob.get(); + + TopicServicesResponse serviceReply = abstractWaylineService.flighttaskExecute( + SDKManager.getDeviceSDK(job.getDockSn()), new FlighttaskExecuteRequest().setFlightId(jobId)); + if (!serviceReply.getData().getResult().isSuccess()) { + log.info("执行作业 ====> 错误: {}", serviceReply.getData().getResult()); + waylineJobService.updateJob(WaylineJobDTO.builder() + .jobId(jobId) + .executeTime(LocalDateTime.now()) + .status(WaylineJobStatusEnum.FAILED.getVal()) + .completedTime(LocalDateTime.now()) + .code(serviceReply.getData().getResult().getCode()).build()); + // The conditional task fails and enters the blocking status. + if (TaskTypeEnum.CONDITIONAL == job.getTaskType() + && WaylineErrorCodeEnum.find(serviceReply.getData().getResult().getCode()).isBlock()) { + waylineRedisService.setBlockedWaylineJob(job.getDockSn(), jobId); + } + return false; + } + + waylineJobService.updateJob(WaylineJobDTO.builder() + .jobId(jobId) + .executeTime(LocalDateTime.now()) + .status(WaylineJobStatusEnum.IN_PROGRESS.getVal()) + .build()); + waylineRedisService.setRunningWaylineJob(job.getDockSn(), EventsReceiver.builder().bid(jobId).sn(job.getDockSn()).build()); + return true; + } + + @Override + public void cancelFlightTask(String workspaceId, Collection jobIds) { + List waylineJobs = waylineJobService.getJobsByConditions(workspaceId, jobIds, WaylineJobStatusEnum.PENDING); + + Set waylineJobIds = waylineJobs.stream().map(WaylineJobDTO::getJobId).collect(Collectors.toSet()); + // Check if the task status is correct. + boolean isErr = !jobIds.removeAll(waylineJobIds) || !jobIds.isEmpty() ; + if (isErr) { + throw new IllegalArgumentException("这些任务的状态不正确,无法取消。 " + Arrays.toString(jobIds.toArray())); + } + + // Group job id by dock sn. + Map> dockJobs = waylineJobs.stream() + .collect(Collectors.groupingBy(WaylineJobDTO::getDockSn, + Collectors.mapping(WaylineJobDTO::getJobId, Collectors.toList()))); + dockJobs.forEach((dockSn, idList) -> this.publishCancelTask(workspaceId, dockSn, idList)); + + } + + public void publishCancelTask(String workspaceId, String dockSn, List jobIds) { + boolean isOnline = deviceRedisService.checkDeviceOnline(dockSn); + if (!isOnline) { + throw new RuntimeException("Dock处于脱机状态。"); + } + + TopicServicesResponse serviceReply = abstractWaylineService.flighttaskUndo(SDKManager.getDeviceSDK(dockSn), + new FlighttaskUndoRequest().setFlightIds(jobIds)); + if (!serviceReply.getData().getResult().isSuccess()) { + log.info("取消作业 ====> 错误: {}", serviceReply.getData().getResult()); + throw new RuntimeException("未能取消的路线作业 " + dockSn); + } + + for (String jobId : jobIds) { + waylineJobService.updateJob(WaylineJobDTO.builder() + .workspaceId(workspaceId) + .jobId(jobId) + .status(WaylineJobStatusEnum.CANCEL.getVal()) + .completedTime(LocalDateTime.now()) + .build()); + RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_TIMED_EXECUTE, workspaceId + RedisConst.DELIMITER + dockSn + RedisConst.DELIMITER + jobId); + } + + } + + @Override + public void uploadMediaHighestPriority(String workspaceId, String jobId) { + Optional jobOpt = waylineJobService.getJobByJobId(workspaceId, jobId); + if (jobOpt.isEmpty()) { + throw new RuntimeException(CommonErrorEnum.ILLEGAL_ARGUMENT.getMessage()); + } + + String dockSn = jobOpt.get().getDockSn(); + String key = RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + dockSn; + if (RedisOpsUtils.checkExist(key) && jobId.equals(((MediaFileCountDTO) RedisOpsUtils.get(key)).getJobId())) { + return; + } + + TopicServicesResponse reply = abstractMediaService.uploadFlighttaskMediaPrioritize( + SDKManager.getDeviceSDK(dockSn), new UploadFlighttaskMediaPrioritize().setFlightId(jobId)); + if (!reply.getData().getResult().isSuccess()) { + throw new RuntimeException("无法设置媒体作业上载优先级。错误: " + reply.getData().getResult()); + } + } + + @Override + public void updateJobStatus(String workspaceId, String jobId, UpdateJobParam param) { + Optional waylineJobOpt = waylineJobService.getJobByJobId(workspaceId, jobId); + if (waylineJobOpt.isEmpty()) { + throw new RuntimeException("作业不存在。"); + } + WaylineJobDTO waylineJob = waylineJobOpt.get(); + WaylineJobStatusEnum statusEnum = waylineJobService.getWaylineState(waylineJob.getDockSn()); + if (statusEnum.getEnd() || WaylineJobStatusEnum.PENDING == statusEnum) { + throw new RuntimeException("路线作业状态不匹配,因此无法执行该操作。"); + } + + switch (param.getStatus()) { + case PAUSE: + pauseJob(workspaceId, waylineJob.getDockSn(), jobId, statusEnum); + break; + case RESUME: + resumeJob(workspaceId, waylineJob.getDockSn(), jobId, statusEnum); + break; + } + + } + + private void pauseJob(String workspaceId, String dockSn, String jobId, WaylineJobStatusEnum statusEnum) { + if (WaylineJobStatusEnum.PAUSED == statusEnum && jobId.equals(waylineRedisService.getPausedWaylineJobId(dockSn))) { + waylineRedisService.setPausedWaylineJob(dockSn, jobId); + return; + } + + TopicServicesResponse reply = abstractWaylineService.flighttaskPause(SDKManager.getDeviceSDK(dockSn)); + if (!reply.getData().getResult().isSuccess()) { + throw new RuntimeException("无法暂停路线作业。错误: " + reply.getData().getResult()); + } + waylineRedisService.delRunningWaylineJob(dockSn); + waylineRedisService.setPausedWaylineJob(dockSn, jobId); + } + + private void resumeJob(String workspaceId, String dockSn, String jobId, WaylineJobStatusEnum statusEnum) { + Optional> runningDataOpt = waylineRedisService.getRunningWaylineJob(dockSn); + if (WaylineJobStatusEnum.IN_PROGRESS == statusEnum && jobId.equals(runningDataOpt.map(EventsReceiver::getSn).get())) { + waylineRedisService.setRunningWaylineJob(dockSn, runningDataOpt.get()); + return; + } + TopicServicesResponse reply = abstractWaylineService.flighttaskRecovery(SDKManager.getDeviceSDK(dockSn)); + if (!reply.getData().getResult().isSuccess()) { + throw new RuntimeException("无法恢复路线作业。错误: " + reply.getData().getResult()); + } + + runningDataOpt.ifPresent(runningData -> waylineRedisService.setRunningWaylineJob(dockSn, runningData)); + waylineRedisService.delPausedWaylineJob(dockSn); + } + + @Override + public void retryPrepareJob(ConditionalWaylineJobKey jobKey, WaylineJobDTO waylineJob) { + Optional childJobOpt = waylineJobService.createWaylineJobByParent(jobKey.getWorkspaceId(), jobKey.getJobId()); + if (childJobOpt.isEmpty()) { + log.error("无法创建路线作业。"); + return; + } + + WaylineJobDTO newJob = childJobOpt.get(); + newJob.setBeginTime(LocalDateTime.now().plusSeconds(RedisConst.WAYLINE_JOB_BLOCK_TIME)); + boolean isAdd = waylineRedisService.addPrepareConditionalWaylineJob(newJob); + if (!isAdd) { + log.error("无法创建路线作业。 {}", newJob.getJobId()); + return; + } + + waylineJob.setJobId(newJob.getJobId()); + waylineRedisService.setConditionalWaylineJob(waylineJob); + } + + + @Override + public TopicEventsResponse flighttaskReady(TopicEventsRequest response, MessageHeaders headers) { + List flightIds = response.getData().getFlightIds(); + + log.info("就绪任务列表:{}", Arrays.toString(flightIds.toArray()) ); + // Check conditional task blocking status. + String blockedId = waylineRedisService.getBlockedWaylineJobId(response.getGateway()); + if (!StringUtils.hasText(blockedId)) { + return null; + } + + Optional deviceOpt = deviceRedisService.getDeviceOnline(response.getGateway()); + if (deviceOpt.isEmpty()) { + return null; + } + DeviceDTO device = deviceOpt.get(); + + try { + for (String jobId : flightIds) { + boolean isExecute = this.executeFlightTask(device.getWorkspaceId(), jobId); + if (!isExecute) { + return null; + } + Optional waylineJobOpt = waylineRedisService.getConditionalWaylineJob(jobId); + if (waylineJobOpt.isEmpty()) { + log.info("条件作业已过期,将不再执行。"); + return new TopicEventsResponse<>(); + } + WaylineJobDTO waylineJob = waylineJobOpt.get(); + this.retryPrepareJob(new ConditionalWaylineJobKey(device.getWorkspaceId(), response.getGateway(), jobId), waylineJob); + return new TopicEventsResponse<>(); + } + } catch (Exception e) { + log.error("未能执行条件任务。"); + e.printStackTrace(); + } + return new TopicEventsResponse<>(); + } + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/SDKWaylineService.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/SDKWaylineService.java new file mode 100644 index 0000000..a129b66 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/SDKWaylineService.java @@ -0,0 +1,159 @@ +package com.dji.sample.wayline.service.impl; + +import com.dji.sample.common.error.CommonErrorEnum; +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.websocket.model.BizCodeEnum; +import com.dji.sample.component.websocket.service.IWebSocketMessageService; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.model.enums.UserTypeEnum; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.media.model.MediaFileCountDTO; +import com.dji.sample.media.service.IMediaRedisService; +import com.dji.sample.wayline.model.dto.WaylineJobDTO; +import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum; +import com.dji.sample.wayline.service.IWaylineFileService; +import com.dji.sample.wayline.service.IWaylineJobService; +import com.dji.sample.wayline.service.IWaylineRedisService; +import com.dji.sdk.cloudapi.wayline.*; +import com.dji.sdk.cloudapi.wayline.api.AbstractWaylineService; +import com.dji.sdk.mqtt.MqttReply; +import com.dji.sdk.mqtt.events.EventsDataRequest; +import com.dji.sdk.mqtt.events.TopicEventsRequest; +import com.dji.sdk.mqtt.events.TopicEventsResponse; +import com.dji.sdk.mqtt.requests.TopicRequestsRequest; +import com.dji.sdk.mqtt.requests.TopicRequestsResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; + +import java.net.URL; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.util.Objects; +import java.util.Optional; + +/** + * @author sean + * @version 1.7 + * @date 2023/7/7 + */ +@Service +@Slf4j +public class SDKWaylineService extends AbstractWaylineService { + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private IWaylineRedisService waylineRedisService; + + @Autowired + private IMediaRedisService mediaRedisService; + + @Autowired + private IWebSocketMessageService webSocketMessageService; + + @Autowired + private IWaylineJobService waylineJobService; + + @Autowired + private IWaylineFileService waylineFileService; + + @Override + public TopicEventsResponse deviceExitHomingNotify(TopicEventsRequest request, MessageHeaders headers) { + return super.deviceExitHomingNotify(request, headers); + } + + @Override + public TopicEventsResponse flighttaskProgress(TopicEventsRequest> response, MessageHeaders headers) { + EventsReceiver eventsReceiver = new EventsReceiver<>(); + eventsReceiver.setResult(response.getData().getResult()); + eventsReceiver.setOutput(response.getData().getOutput()); + eventsReceiver.setBid(response.getBid()); + eventsReceiver.setSn(response.getGateway()); + + FlighttaskProgress output = eventsReceiver.getOutput(); + log.info("Task progress: {}", output.getProgress().toString()); + if (!eventsReceiver.getResult().isSuccess()) { + log.error("Task progress ===> Error: " + eventsReceiver.getResult()); + } + + Optional deviceOpt = deviceRedisService.getDeviceOnline(response.getGateway()); + if (deviceOpt.isEmpty()) { + return new TopicEventsResponse<>(); + } + + FlighttaskStatusEnum statusEnum = output.getStatus(); + waylineRedisService.setRunningWaylineJob(response.getGateway(), eventsReceiver); + + if (statusEnum.isEnd()) { + WaylineJobDTO job = WaylineJobDTO.builder() + .jobId(response.getBid()) + .status(WaylineJobStatusEnum.SUCCESS.getVal()) + .completedTime(LocalDateTime.now()) + .mediaCount(output.getExt().getMediaCount()) + .build(); + + // record the update of the media count. + if (Objects.nonNull(job.getMediaCount()) && job.getMediaCount() != 0) { + mediaRedisService.setMediaCount(response.getGateway(), job.getJobId(), + MediaFileCountDTO.builder().deviceSn(deviceOpt.get().getChildDeviceSn()) + .jobId(response.getBid()).mediaCount(job.getMediaCount()).uploadedCount(0).build()); + } + + if (FlighttaskStatusEnum.OK != statusEnum) { + job.setCode(eventsReceiver.getResult().getCode()); + job.setStatus(WaylineJobStatusEnum.FAILED.getVal()); + } + waylineJobService.updateJob(job); + waylineRedisService.delRunningWaylineJob(response.getGateway()); + waylineRedisService.delPausedWaylineJob(response.getBid()); + } + + webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), + BizCodeEnum.FLIGHT_TASK_PROGRESS.getCode(), eventsReceiver); + + return new TopicEventsResponse<>(); + } + + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Override + public TopicRequestsResponse> flighttaskResourceGet(TopicRequestsRequest response, MessageHeaders headers) { + String jobId = response.getData().getFlightId(); + + Optional deviceOpt = deviceRedisService.getDeviceOnline(response.getGateway()); + if (deviceOpt.isEmpty()) { + log.error("设备处于脱机状态,请稍后再试。"); + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.DEVICE_OFFLINE)); + } + Optional waylineJobOpt = waylineJobService.getJobByJobId(deviceOpt.get().getWorkspaceId(), jobId); + if (waylineJobOpt.isEmpty()) { + log.error("路线作业不存在。"); + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); + } + + WaylineJobDTO waylineJob = waylineJobOpt.get(); + + // get wayline file + Optional waylineFile = waylineFileService.getWaylineByWaylineId(waylineJob.getWorkspaceId(), waylineJob.getFileId()); + if (waylineFile.isEmpty()) { + log.error("路线文件不存在。"); + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.ILLEGAL_ARGUMENT)); + } + // get file url + try { + URL url = waylineFileService.getObjectUrl(waylineJob.getWorkspaceId(), waylineFile.get().getId()); + return new TopicRequestsResponse>().setData( + MqttReply.success(new FlighttaskResourceGetResponse() + .setFile(new FlighttaskFile() + .setUrl(url.toString()) + .setFingerprint(waylineFile.get().getSign())))); + } catch (SQLException | NullPointerException e) { + e.printStackTrace(); + return new TopicRequestsResponse().setData(MqttReply.error(CommonErrorEnum.SYSTEM_ERROR)); + } + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineFileServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineFileServiceImpl.java new file mode 100644 index 0000000..d90a98e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineFileServiceImpl.java @@ -0,0 +1,303 @@ +package com.dji.sample.wayline.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dji.sample.component.oss.model.OssConfiguration; +import com.dji.sample.component.oss.service.impl.OssServiceContext; +import com.dji.sample.wayline.dao.IWaylineFileMapper; +import com.dji.sample.wayline.model.dto.KmzFileProperties; +import com.dji.sample.wayline.model.dto.WaylineFileDTO; +import com.dji.sample.wayline.model.entity.WaylineFileEntity; +import com.dji.sample.wayline.service.IWaylineFileService; +import com.dji.sdk.cloudapi.device.DeviceDomainEnum; +import com.dji.sdk.cloudapi.device.DeviceEnum; +import com.dji.sdk.cloudapi.device.DeviceSubTypeEnum; +import com.dji.sdk.cloudapi.device.DeviceTypeEnum; +import com.dji.sdk.cloudapi.wayline.GetWaylineListRequest; +import com.dji.sdk.cloudapi.wayline.GetWaylineListResponse; +import com.dji.sdk.cloudapi.wayline.WaylineTypeEnum; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Node; +import org.dom4j.io.SAXReader; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.DigestUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import static com.dji.sample.wayline.model.dto.KmzFileProperties.WAYLINE_FILE_SUFFIX; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Service +@Transactional +public class WaylineFileServiceImpl implements IWaylineFileService { + + @Autowired + private IWaylineFileMapper mapper; + + @Autowired + private OssServiceContext ossService; + + @Override + public PaginationData getWaylinesByParam(String workspaceId, GetWaylineListRequest param) { + // Paging Query + Page page = mapper.selectPage( + new Page(param.getPage(), param.getPageSize()), + new LambdaQueryWrapper() + .eq(WaylineFileEntity::getWorkspaceId, workspaceId) + .eq(Objects.nonNull(param.getFavorited()), WaylineFileEntity::getFavorited, param.getFavorited()) + .and(param.getTemplateType() != null, wrapper -> { + for (WaylineTypeEnum type : param.getTemplateType()) { + wrapper.like(WaylineFileEntity::getTemplateTypes, type.getValue()).or(); + } + }) + .and(param.getPayloadModelKey() != null, wrapper -> { + for (DeviceEnum type : param.getPayloadModelKey()) { + wrapper.like(WaylineFileEntity::getPayloadModelKeys, type.getType()).or(); + } + }) + .and(param.getDroneModelKeys() != null, wrapper -> { + for (DeviceEnum type : param.getDroneModelKeys()) { + wrapper.eq(WaylineFileEntity::getDroneModelKey, type.getType()).or(); + } + }) + .like(Objects.nonNull(param.getKey()), WaylineFileEntity::getName, param.getKey()) + // There is a risk of SQL injection + .last(Objects.nonNull(param.getOrderBy()), " order by " + param.getOrderBy().toString())); + + // Wrap the results of a paging query into a custom paging object. + List records = page.getRecords() + .stream() + .map(this::entityConvertToDTO) + .collect(Collectors.toList()); + + return new PaginationData<>(records, new Pagination(page.getCurrent(), page.getSize(), page.getTotal())); + } + + @Override + public Optional getWaylineByWaylineId(String workspaceId, String waylineId) { + return Optional.ofNullable( + this.entityConvertToDTO( + mapper.selectOne( + new LambdaQueryWrapper() + .eq(WaylineFileEntity::getWorkspaceId, workspaceId) + .eq(WaylineFileEntity::getWaylineId, waylineId)))); + } + + @Override + public URL getObjectUrl(String workspaceId, String waylineId) throws SQLException { + Optional waylineOpt = this.getWaylineByWaylineId(workspaceId, waylineId); + if (waylineOpt.isEmpty()) { + throw new SQLException(waylineId + " 不存在。"); + } + return ossService.getObjectUrl(OssConfiguration.bucket, waylineOpt.get().getObjectKey()); + } + + @Override + public Integer saveWaylineFile(String workspaceId, WaylineFileDTO metadata) { + WaylineFileEntity file = this.dtoConvertToEntity(metadata); + file.setWaylineId(UUID.randomUUID().toString()); + file.setWorkspaceId(workspaceId); + + if (!StringUtils.hasText(file.getSign())) { + try (InputStream object = ossService.getObject(OssConfiguration.bucket, metadata.getObjectKey())) { + if (object.available() == 0) { + throw new RuntimeException("文件 " + metadata.getObjectKey() + + " 桶中不存在[" + OssConfiguration.bucket + "]."); + } + file.setSign(DigestUtils.md5DigestAsHex(object)); + } catch (IOException e) { + e.printStackTrace(); + } + } + int insertId = mapper.insert(file); + return insertId > 0 ? file.getId() : insertId; + } + + @Override + public Boolean markFavorite(String workspaceId, List waylineIds, Boolean isFavorite) { + if (waylineIds.isEmpty()) { + return false; + } + if (isFavorite == null) { + return true; + } + return mapper.update(null, new LambdaUpdateWrapper() + .set(WaylineFileEntity::getFavorited, isFavorite) + .eq(WaylineFileEntity::getWorkspaceId, workspaceId) + .in(WaylineFileEntity::getWaylineId, waylineIds)) > 0; + } + + @Override + public List getDuplicateNames(String workspaceId, List names) { + return mapper.selectList(new LambdaQueryWrapper() + .eq(WaylineFileEntity::getWorkspaceId, workspaceId) + .in(WaylineFileEntity::getName, names)) + .stream() + .map(WaylineFileEntity::getName) + .collect(Collectors.toList()); + } + + @Override + public Boolean deleteByWaylineId(String workspaceId, String waylineId) { + Optional waylineOpt = this.getWaylineByWaylineId(workspaceId, waylineId); + if (waylineOpt.isEmpty()) { + return true; + } + GetWaylineListResponse wayline = waylineOpt.get(); + boolean isDel = mapper.delete(new LambdaUpdateWrapper() + .eq(WaylineFileEntity::getWorkspaceId, workspaceId) + .eq(WaylineFileEntity::getWaylineId, waylineId)) + > 0; + if (!isDel) { + return false; + } + return ossService.deleteObject(OssConfiguration.bucket, wayline.getObjectKey()); + } + + @Override + public void importKmzFile(MultipartFile file, String workspaceId, String creator) { + Optional waylineFileOpt = validKmzFile(file); + if (waylineFileOpt.isEmpty()) { + throw new RuntimeException("文件格式不正确。"); + } + + try { + WaylineFileDTO waylineFile = waylineFileOpt.get(); + waylineFile.setUsername(creator); + + ossService.putObject(OssConfiguration.bucket, waylineFile.getObjectKey(), file.getInputStream()); + this.saveWaylineFile(workspaceId, waylineFile); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public String getWaylineIdByFileId(Integer fileId) { + String waylineId = mapper.selectOne( + new LambdaQueryWrapper() + .eq(WaylineFileEntity::getId, fileId)).getWaylineId(); + return waylineId; + } + + private Optional validKmzFile(MultipartFile file) { + String filename = file.getOriginalFilename(); + if (Objects.nonNull(filename) && !filename.endsWith(WAYLINE_FILE_SUFFIX)) { + throw new RuntimeException("文件格式不正确。"); + } + try (ZipInputStream unzipFile = new ZipInputStream(file.getInputStream(), StandardCharsets.UTF_8)) { + + ZipEntry nextEntry = unzipFile.getNextEntry(); + while (Objects.nonNull(nextEntry)) { + boolean isWaylines = (KmzFileProperties.FILE_DIR_FIRST + "/" + KmzFileProperties.FILE_DIR_SECOND_TEMPLATE).equals(nextEntry.getName()); + if (!isWaylines) { + nextEntry = unzipFile.getNextEntry(); + continue; + } + SAXReader reader = new SAXReader(); + Document document = reader.read(unzipFile); + if (!StandardCharsets.UTF_8.name().equals(document.getXMLEncoding())) { + throw new RuntimeException("文件编码格式不正确。"); + } + + Node droneNode = document.selectSingleNode("//" + KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_DRONE_INFO); + Node payloadNode = document.selectSingleNode("//" + KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_PAYLOAD_INFO); + if (Objects.isNull(droneNode) || Objects.isNull(payloadNode)) { + throw new RuntimeException("文件格式不正确。"); + } + + DeviceTypeEnum type = DeviceTypeEnum.find(Integer.parseInt(droneNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_DRONE_ENUM_VALUE))); + DeviceSubTypeEnum subType = DeviceSubTypeEnum.find(Integer.parseInt(droneNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_DRONE_SUB_ENUM_VALUE))); + DeviceTypeEnum payloadType = DeviceTypeEnum.find(Integer.parseInt(payloadNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_PAYLOAD_ENUM_VALUE))); + DeviceSubTypeEnum payloadSubType = DeviceSubTypeEnum.find(Integer.parseInt(payloadNode.valueOf(KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_PAYLOAD_SUB_ENUM_VALUE))); + String templateType = document.valueOf("//" + KmzFileProperties.TAG_WPML_PREFIX + KmzFileProperties.TAG_TEMPLATE_TYPE); + + return Optional.of(WaylineFileDTO.builder() + .droneModelKey(DeviceEnum.find(DeviceDomainEnum.DRONE, type, subType).getDevice()) + .payloadModelKeys(List.of(DeviceEnum.find(DeviceDomainEnum.PAYLOAD, payloadType, payloadSubType).getDevice())) + .objectKey((OssConfiguration.objectDirPrefix + File.separator + filename).replace("\\","/")) + .name(filename.substring(0, filename.lastIndexOf(WAYLINE_FILE_SUFFIX))) + .sign(DigestUtils.md5DigestAsHex(file.getInputStream())) + .templateTypes(List.of(WaylineTypeEnum.find(templateType).getValue())) + .build()); + } + + } catch (IOException | DocumentException e) { + e.printStackTrace(); + } + return Optional.empty(); + } + /** + * Convert database entity objects into wayline data transfer object. + * @param entity + * @return + */ + private GetWaylineListResponse entityConvertToDTO(WaylineFileEntity entity) { + if (entity == null) { + return null; + } + return new GetWaylineListResponse() + .setDroneModelKey(DeviceEnum.find(entity.getDroneModelKey())) + .setFavorited(entity.getFavorited()) + .setName(entity.getName()) + .setPayloadModelKeys(entity.getPayloadModelKeys() != null ? + Arrays.stream(entity.getPayloadModelKeys().split(",")).map(DeviceEnum::find).collect(Collectors.toList()) : null) + .setTemplateTypes(Arrays.stream(entity.getTemplateTypes().split(",")) + .map(Integer::parseInt).map(WaylineTypeEnum::find) + .collect(Collectors.toList())) + .setUsername(entity.getUsername()) + .setObjectKey(entity.getObjectKey()) + .setSign(entity.getSign()) + .setUpdateTime(entity.getUpdateTime()) + .setCreateTime(entity.getCreateTime()) + .setId(entity.getWaylineId()); + + } + + /** + * Convert the received wayline object into a database entity object. + * @param file + * @return + */ + private WaylineFileEntity dtoConvertToEntity(WaylineFileDTO file) { + WaylineFileEntity.WaylineFileEntityBuilder builder = WaylineFileEntity.builder(); + + if (file != null) { + builder.droneModelKey(file.getDroneModelKey()) + .name(file.getName()) + .username(file.getUsername()) + .objectKey(file.getObjectKey()) + // Separate multiple payload data with ",". + .payloadModelKeys(String.join(",", file.getPayloadModelKeys())) + .templateTypes(file.getTemplateTypes().stream() + .map(String::valueOf) + .collect(Collectors.joining(","))) + .favorited(file.getFavorited()) + .sign(file.getSign()) + .build(); + } + + return builder.build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineJobServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineJobServiceImpl.java new file mode 100644 index 0000000..9724f04 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineJobServiceImpl.java @@ -0,0 +1,301 @@ +package com.dji.sample.wayline.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.manage.model.dto.DeviceDTO; +import com.dji.sample.manage.service.IDeviceRedisService; +import com.dji.sample.manage.service.IDeviceService; +import com.dji.sample.media.model.MediaFileCountDTO; +import com.dji.sample.media.service.IFileService; +import com.dji.sample.wayline.dao.IWaylineJobMapper; +import com.dji.sample.wayline.model.dto.WaylineJobDTO; +import com.dji.sample.wayline.model.entity.WaylineJobEntity; +import com.dji.sample.wayline.model.enums.WaylineJobStatusEnum; +import com.dji.sample.wayline.model.param.CreateJobParam; +import com.dji.sample.wayline.service.IWaylineFileService; +import com.dji.sample.wayline.service.IWaylineJobService; +import com.dji.sample.wayline.service.IWaylineRedisService; +import com.dji.sdk.cloudapi.device.DockModeCodeEnum; +import com.dji.sdk.cloudapi.device.DroneModeCodeEnum; +import com.dji.sdk.cloudapi.device.OsdDock; +import com.dji.sdk.cloudapi.device.OsdDockDrone; +import com.dji.sdk.cloudapi.wayline.*; +import com.dji.sdk.common.Pagination; +import com.dji.sdk.common.PaginationData; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author sean + * @version 1.1 + * @date 2022/6/1 + */ +@Service +@Transactional +@Slf4j +public class WaylineJobServiceImpl implements IWaylineJobService { + + @Autowired + private IWaylineJobMapper mapper; + + @Autowired + private IWaylineFileService waylineFileService; + + @Autowired + private IDeviceService deviceService; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private IFileService fileService; + + @Autowired + private IDeviceRedisService deviceRedisService; + + @Autowired + private IWaylineRedisService waylineRedisService; + + private Optional insertWaylineJob(WaylineJobEntity jobEntity) { + int id = mapper.insert(jobEntity); + if (id <= 0) { + return Optional.empty(); + } + return Optional.ofNullable(this.entity2Dto(jobEntity)); + } + + @Override + public Optional createWaylineJob(CreateJobParam param, String workspaceId, String username, Long beginTime, Long endTime) { + if (Objects.isNull(param)) { + return Optional.empty(); + } + // Immediate tasks, allocating time on the backend. + WaylineJobEntity jobEntity = WaylineJobEntity.builder() + .name(param.getName()) + .dockSn(param.getDockSn()) + .fileId(param.getFileId()) + .username(username) + .workspaceId(workspaceId) + .jobId(StringUtils.hasText(param.getJobId())?param.getJobId():UUID.randomUUID().toString()) + .beginTime(beginTime) + .endTime(endTime) + .status(WaylineJobStatusEnum.PENDING.getVal()) + .taskType(param.getTaskType().getType()) + .waylineType(param.getWaylineType().getValue()) + .outOfControlAction(param.getOutOfControlAction().getAction()) + .rthAltitude(param.getRthAltitude()) + .mediaCount(0) + .breakPoint(param.getBreakPoint()) + .build(); + + return insertWaylineJob(jobEntity); + } + + @Override + public Optional createWaylineJobByParent(String workspaceId, String parentId) { + Optional parentJobOpt = this.getJobByJobId(workspaceId, parentId); + if (parentJobOpt.isEmpty()) { + return Optional.empty(); + } + WaylineJobEntity jobEntity = this.dto2Entity(parentJobOpt.get()); + jobEntity.setJobId(UUID.randomUUID().toString()); + jobEntity.setErrorCode(null); + jobEntity.setCompletedTime(null); + jobEntity.setExecuteTime(null); + jobEntity.setStatus(WaylineJobStatusEnum.PENDING.getVal()); + jobEntity.setParentId(parentId); + + return this.insertWaylineJob(jobEntity); + } + + public List getJobsByConditions(String workspaceId, Collection jobIds, WaylineJobStatusEnum status) { + return mapper.selectList( + new LambdaQueryWrapper() + .eq(WaylineJobEntity::getWorkspaceId, workspaceId) + .eq(Objects.nonNull(status), WaylineJobEntity::getStatus, status.getVal()) + .and(!CollectionUtils.isEmpty(jobIds), + wrapper -> jobIds.forEach(id -> wrapper.eq(WaylineJobEntity::getJobId, id).or()))) + .stream() + .map(this::entity2Dto) + .collect(Collectors.toList()); + } + + @Override + public Optional getJobByJobId(String workspaceId, String jobId) { + WaylineJobEntity jobEntity = mapper.selectOne( + new LambdaQueryWrapper() + .eq(WaylineJobEntity::getWorkspaceId, workspaceId) + .eq(WaylineJobEntity::getJobId, jobId)); + return Optional.ofNullable(entity2Dto(jobEntity)); + } + + @Override + public Boolean updateJob(WaylineJobDTO dto) { + return mapper.update(this.dto2Entity(dto), + new LambdaUpdateWrapper() + .eq(WaylineJobEntity::getJobId, dto.getJobId())) > 0; + } + + @Override + public PaginationData getJobsByWorkspaceId(String workspaceId, long page, long pageSize) { + Page pageData = mapper.selectPage( + new Page(page, pageSize), + new LambdaQueryWrapper() + .eq(WaylineJobEntity::getWorkspaceId, workspaceId) + .orderByDesc(WaylineJobEntity::getId)); + List records = pageData.getRecords() + .stream() + .map(this::entity2Dto) + .collect(Collectors.toList()); + + return new PaginationData(records, new Pagination(pageData.getCurrent(), pageData.getSize(), pageData.getTotal())); + } + + private WaylineJobEntity dto2Entity(WaylineJobDTO dto) { + WaylineJobEntity.WaylineJobEntityBuilder builder = WaylineJobEntity.builder(); + if (dto == null) { + return builder.build(); + } + if (Objects.nonNull(dto.getBeginTime())) { + builder.beginTime(dto.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + } + if (Objects.nonNull(dto.getEndTime())) { + builder.endTime(dto.getEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + } + if (Objects.nonNull(dto.getExecuteTime())) { + builder.executeTime(dto.getExecuteTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + } + if (Objects.nonNull(dto.getCompletedTime())) { + builder.completedTime(dto.getCompletedTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + } + return builder.status(dto.getStatus()) + .mediaCount(dto.getMediaCount()) + .name(dto.getJobName()) + .errorCode(dto.getCode()) + .jobId(dto.getJobId()) + .fileId(dto.getFileId()) + .dockSn(dto.getDockSn()) + .workspaceId(dto.getWorkspaceId()) + .taskType(Optional.ofNullable(dto.getTaskType()).map(TaskTypeEnum::getType).orElse(null)) + .waylineType(Optional.ofNullable(dto.getWaylineType()).map(WaylineTypeEnum::getValue).orElse(null)) + .username(dto.getUsername()) + .rthAltitude(dto.getRthAltitude()) + .outOfControlAction(Optional.ofNullable(dto.getOutOfControlAction()) + .map(OutOfControlActionEnum::getAction).orElse(null)) + .parentId(dto.getParentId()) + .build(); + } + + public WaylineJobStatusEnum getWaylineState(String dockSn) { + Optional dockOpt = deviceRedisService.getDeviceOnline(dockSn); + if (dockOpt.isEmpty() || !StringUtils.hasText(dockOpt.get().getChildDeviceSn())) { + return WaylineJobStatusEnum.UNKNOWN; + } + Optional dockOsdOpt = deviceRedisService.getDeviceOsd(dockSn, OsdDock.class); + Optional deviceOsdOpt = deviceRedisService.getDeviceOsd(dockOpt.get().getChildDeviceSn(), OsdDockDrone.class); + if (dockOsdOpt.isEmpty() || deviceOsdOpt.isEmpty() || DockModeCodeEnum.WORKING != dockOsdOpt.get().getModeCode()) { + return WaylineJobStatusEnum.UNKNOWN; + } + + OsdDockDrone osdDevice = deviceOsdOpt.get(); + if (DroneModeCodeEnum.WAYLINE == osdDevice.getModeCode() + || DroneModeCodeEnum.MANUAL == osdDevice.getModeCode() + || DroneModeCodeEnum.TAKEOFF_AUTO == osdDevice.getModeCode()) { + if (StringUtils.hasText(waylineRedisService.getPausedWaylineJobId(dockSn))) { + return WaylineJobStatusEnum.PAUSED; + } + if (waylineRedisService.getRunningWaylineJob(dockSn).isPresent()) { + return WaylineJobStatusEnum.IN_PROGRESS; + } + } + return WaylineJobStatusEnum.UNKNOWN; + } + + private WaylineJobDTO entity2Dto(WaylineJobEntity entity) { + if (entity == null) { + return null; + } + + WaylineJobDTO.WaylineJobDTOBuilder builder = WaylineJobDTO.builder() + .jobId(entity.getJobId()) + .jobName(entity.getName()) + .fileId(entity.getFileId()) + .fileName(waylineFileService.getWaylineByWaylineId(entity.getWorkspaceId(), entity.getFileId()) + .orElse(new GetWaylineListResponse()).getName()) + .dockSn(entity.getDockSn()) + .dockName(deviceService.getDeviceBySn(entity.getDockSn()) + .orElse(DeviceDTO.builder().build()).getNickname()) + .username(entity.getUsername()) + .workspaceId(entity.getWorkspaceId()) + .status(WaylineJobStatusEnum.IN_PROGRESS.getVal() == entity.getStatus() && + entity.getJobId().equals(waylineRedisService.getPausedWaylineJobId(entity.getDockSn())) ? + WaylineJobStatusEnum.PAUSED.getVal() : entity.getStatus()) + .code(entity.getErrorCode()) + .beginTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getBeginTime()), ZoneId.systemDefault())) + .endTime(Objects.nonNull(entity.getEndTime()) ? + LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getEndTime()), ZoneId.systemDefault()) : null) + .executeTime(Objects.nonNull(entity.getExecuteTime()) ? + LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getExecuteTime()), ZoneId.systemDefault()) : null) + .completedTime(WaylineJobStatusEnum.find(entity.getStatus()).getEnd() ? + LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getUpdateTime()), ZoneId.systemDefault()) : null) + .taskType(TaskTypeEnum.find(entity.getTaskType())) + .waylineType(WaylineTypeEnum.find(entity.getWaylineType())) + .rthAltitude(entity.getRthAltitude()) + .outOfControlAction(OutOfControlActionEnum.find(entity.getOutOfControlAction())) + .mediaCount(entity.getMediaCount()) + .breakPoint(entity.getBreakPoint()); + + + if (Objects.nonNull(entity.getEndTime())) { + builder.endTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(entity.getEndTime()), ZoneId.systemDefault())); + } + if (WaylineJobStatusEnum.IN_PROGRESS.getVal() == entity.getStatus()) { + builder.progress(waylineRedisService.getRunningWaylineJob(entity.getDockSn()) + .map(EventsReceiver::getOutput) + .map(FlighttaskProgress::getProgress) + .map(FlighttaskProgressData::getPercent) + .orElse(null)); + } + + if (entity.getMediaCount() == 0) { + return builder.build(); + } + + // sync the number of media files + String key = RedisConst.MEDIA_HIGHEST_PRIORITY_PREFIX + entity.getDockSn(); + String countKey = RedisConst.MEDIA_FILE_PREFIX + entity.getDockSn(); + Object mediaFileCount = RedisOpsUtils.hashGet(countKey, entity.getJobId()); + if (Objects.nonNull(mediaFileCount)) { + builder.uploadedCount(((MediaFileCountDTO) mediaFileCount).getUploadedCount()) + .uploading(RedisOpsUtils.checkExist(key) && entity.getJobId().equals(((MediaFileCountDTO)RedisOpsUtils.get(key)).getJobId())); + return builder.build(); + } + + int uploadedSize = fileService.getFilesByWorkspaceAndJobId(entity.getWorkspaceId(), entity.getJobId()).size(); + // All media for this job have been uploaded. + if (uploadedSize >= entity.getMediaCount()) { + return builder.uploadedCount(uploadedSize).build(); + } + RedisOpsUtils.hashSet(countKey, entity.getJobId(), + MediaFileCountDTO.builder() + .jobId(entity.getJobId()) + .mediaCount(entity.getMediaCount()) + .uploadedCount(uploadedSize).build()); + return builder.build(); + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineRedisServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineRedisServiceImpl.java new file mode 100644 index 0000000..fc62020 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineRedisServiceImpl.java @@ -0,0 +1,112 @@ +package com.dji.sample.wayline.service.impl; + +import com.dji.sample.component.mqtt.model.EventsReceiver; +import com.dji.sample.component.redis.RedisConst; +import com.dji.sample.component.redis.RedisOpsUtils; +import com.dji.sample.wayline.model.dto.ConditionalWaylineJobKey; +import com.dji.sample.wayline.model.dto.WaylineJobDTO; +import com.dji.sample.wayline.service.IWaylineRedisService; +import com.dji.sdk.cloudapi.wayline.FlighttaskProgress; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Objects; +import java.util.Optional; + +/** + * @author sean + * @version 1.4 + * @date 2023/3/24 + */ +@Service +public class WaylineRedisServiceImpl implements IWaylineRedisService { + + @Override + public void setRunningWaylineJob(String dockSn, EventsReceiver data) { + RedisOpsUtils.setWithExpire(RedisConst.WAYLINE_JOB_RUNNING_PREFIX + dockSn, data, RedisConst.DRC_MODE_ALIVE_SECOND); + } + + @Override + public Optional> getRunningWaylineJob(String dockSn) { + return Optional.ofNullable((EventsReceiver) RedisOpsUtils.get(RedisConst.WAYLINE_JOB_RUNNING_PREFIX + dockSn)); + } + + @Override + public Boolean delRunningWaylineJob(String dockSn) { + return RedisOpsUtils.del(RedisConst.WAYLINE_JOB_RUNNING_PREFIX + dockSn); + } + + @Override + public void setPausedWaylineJob(String dockSn, String jobId) { + RedisOpsUtils.setWithExpire(RedisConst.WAYLINE_JOB_PAUSED_PREFIX + dockSn, jobId, RedisConst.DRC_MODE_ALIVE_SECOND); + } + + @Override + public String getPausedWaylineJobId(String dockSn) { + return (String) RedisOpsUtils.get(RedisConst.WAYLINE_JOB_PAUSED_PREFIX + dockSn); + } + + @Override + public Boolean delPausedWaylineJob(String dockSn) { + return RedisOpsUtils.del(RedisConst.WAYLINE_JOB_PAUSED_PREFIX + dockSn); + } + + @Override + public void setBlockedWaylineJob(String dockSn, String jobId) { + RedisOpsUtils.setWithExpire(RedisConst.WAYLINE_JOB_BLOCK_PREFIX + dockSn, jobId, RedisConst.WAYLINE_JOB_BLOCK_TIME); + } + + @Override + public String getBlockedWaylineJobId(String dockSn) { + return (String) RedisOpsUtils.get(RedisConst.WAYLINE_JOB_BLOCK_PREFIX + dockSn); + } + + @Override + public void setConditionalWaylineJob(WaylineJobDTO waylineJob) { + if (!StringUtils.hasText(waylineJob.getJobId())) { + throw new RuntimeException("作业id不能为null。"); + } + RedisOpsUtils.setWithExpire(RedisConst.WAYLINE_JOB_CONDITION_PREFIX + waylineJob.getJobId(), waylineJob, + (Duration.between(waylineJob.getEndTime(), LocalDateTime.now()).getSeconds())); + } + + @Override + public Optional getConditionalWaylineJob(String jobId) { + return Optional.ofNullable((WaylineJobDTO) RedisOpsUtils.get(RedisConst.WAYLINE_JOB_CONDITION_PREFIX + jobId)); + } + + @Override + public Boolean delConditionalWaylineJob(String jobId) { + return RedisOpsUtils.del(RedisConst.WAYLINE_JOB_CONDITION_PREFIX + jobId); + } + + @Override + public Boolean addPrepareConditionalWaylineJob(WaylineJobDTO waylineJob) { + if (Objects.isNull(waylineJob.getBeginTime())) { + return false; + } + // value: {workspace_id}:{dock_sn}:{job_id} + return RedisOpsUtils.zAdd(RedisConst.WAYLINE_JOB_CONDITION_PREPARE, + waylineJob.getWorkspaceId() + RedisConst.DELIMITER + waylineJob.getDockSn() + RedisConst.DELIMITER + waylineJob.getJobId(), + waylineJob.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + } + + @Override + public Optional getNearestConditionalWaylineJob() { + return Optional.ofNullable(RedisOpsUtils.zGetMin(RedisConst.WAYLINE_JOB_CONDITION_PREPARE)) + .map(Object::toString).map(ConditionalWaylineJobKey::new); + } + + @Override + public Double getConditionalWaylineJobTime(ConditionalWaylineJobKey jobKey) { + return RedisOpsUtils.zScore(RedisConst.WAYLINE_JOB_CONDITION_PREPARE, jobKey.getKey()); + } + + @Override + public Boolean removePrepareConditionalWaylineJob(ConditionalWaylineJobKey jobKey) { + return RedisOpsUtils.zRemove(RedisConst.WAYLINE_JOB_CONDITION_PREPARE, jobKey.getKey()); + } +} diff --git a/dk-modules/sample/src/main/resources/application.yml b/dk-modules/sample/src/main/resources/application.yml new file mode 100644 index 0000000..d8b94d5 --- /dev/null +++ b/dk-modules/sample/src/main/resources/application.yml @@ -0,0 +1,173 @@ +server: + port: 6789 +spring: + main: + allow-bean-definition-overriding: true + application: + name: cloud-api-sample + datasource: + druid: + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3307/cloud_sample?useSSL=false&allowPublicKeyRetrieval=true + username: root + password: 123456 + initial-size: 10 + min-idle: 10 + max-active: 20 + max-wait: 60000 + + redis: + host: 127.0.0.1 + port: 6379 + database: 5 + username: # if you enable + password: 123456 + lettuce: + pool: + max-active: 8 + max-idle: 8 + min-idle: 0 + + servlet: + multipart: + max-file-size: 2GB + max-request-size: 2GB + +jwt: + issuer: DJI + subject: CloudApiSample + secret: CloudApiSample + age: 86400 + +mqtt: + # @see com.dji.sample.component.mqtt.model.MqttUseEnum + # BASIC parameters are required. + BASIC: + protocol: MQTT # @see com.dji.sample.component.mqtt.model.MqttProtocolEnum + host: 114.235.183.162 + port: 1883 + username: adminPCBASIC + password: yongqiang666 + client-id: gengbao1 + # If the protocol is ws/wss, this value is required. + path: + DRC: + protocol: WS # @see com.dji.sample.component.mqtt.model.MqttProtocolEnum + host: 114.235.183.162 + port: 8083 + path: /mqtt + username: adminPCDRC + password: yongqiang666 + +cloud-sdk: + mqtt: + # Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",". + inbound-topic: sys/product/+/status,thing/product/+/requests + +url: + manage: + prefix: manage + version: /api/v1 + map: + prefix: map + version: /api/v1 + media: + prefix: media + version: /api/v1 + wayline: + prefix: wayline + version: /api/v1 + storage: + prefix: storage + version: /api/v1 + control: + prefix: control + version: /api/v1 + +# Tutorial: https://www.alibabacloud.com/help/en/object-storage-service/latest/use-a-temporary-credential-provided-by-sts-to-access-oss +#oss: +# enable: true +# provider: ALIYUN # @see com.dji.sample.component.OssConfiguration.model.enums.OssTypeEnum +# endpoint: http://oss-cn-hangzhou.aliyuncs.com +# access-key: LTAI5tMDFvYZRvrJfK7HeuEm +# secret-key: kP7ueRlhLbM9mvkaLtHfcje3GxgawH +# expire: 3600 +# region: oss-cn-hangzhou # cn-hangzhou +# role-session-name: ossRam +# role-arn: acs:ram::1454407249617199:role/ossram # acs:ram::123456789:role/stsrole +# bucket: yq-dajiang +# object-dir-prefix: goucong + +#oss: +# enable: true +# provider: aws +# endpoint: http://eos-wuxi-1.cmecloud.cn +# access-key: LHJPESZYDZ3ZMC79SZ6V +# secret-key: DnIBjpaBotuO9TD0izb9GbyLFt5jf2F3VQqOje5f +# expire: 3600 +# region: eos-wuxi-1 +# role-session-name: goucong +# role-arn: arn:aws:s3:::dikongtyx/goucong +# bucket: dikongtyx +# object-dir-prefix: goucong + +oss: + enable: true + provider: MINIO + endpoint: http://eos-wuxi-1.cmecloud.cn + access-key: B4E9TC3WUV2DAXZ4P625 + secret-key: Px3VINH6TghgSg11gX5Z59AxxxASB8y9tEsNACNh + bucket: dikongtyx + expire: 3600 + region: wuxi1 + object-dir-prefix: goucong + + + +logging: + level: + com.dji: debug + file: + name: logs/cloud-api-sample.log + +ntp: + server: + host: ntp.aliyun.com + +# To create a license for an application: https://developer.dji.com/user/apps/#all +cloud-api: + app: + id: 125297 + key: 182ae1ca69d9ba5103c0148bf16d68b + license: FixRisR747uGMZwaNbgCAWZojgrcUgZB1qhRyMTtptyKPKI/uETVwMK41HikhP+wbCjSKODdaQH4JIGAvzxdN/4HMrsEj3srLyGXi+BeJyFNyi94mpprv1Cx59fknCrBexAxLoc3f9GcgojEWrB0wCYxGp7l8mulwSDMP5yl++w= + +livestream: + url: + # It is recommended to use a program to create Token. https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/java/src/main/java/io/agora/media/RtcTokenBuilder2.java + agora: + channel: cloud + token: 007eJxTYBBinhSg416uaGdw6G9J4bSDxYZ/mTm5HErajtq2+j09r6bAYGpinGKUkphokmYMxBZJiebJqWYGaanJyUnG5haGyda/RNMaAhkZNp5YxcrIAIEgPitDck5+aQoDAwC1CB6R + uid: 65432 + + # RTMP Note: This IP is the address of the streaming server. If you want to see livestream on web page, you need to convert the RTMP stream to WebRTC stream. + rtmp: + url: rtmp://114.235.183.163/live/livesteam/ # Example: 'rtmp://192.168.1.1/live/' + rtsp: + username: Please enter the username. + password: Please enter the password. + port: 8554 + + # GB28181 Note:If you don't know what these parameters mean, you can go to Pilot2 and select the GB28181 page in the cloud platform. Where the parameters same as these parameters. + gb28181: + serverIP: Please enter the server ip. + serverPort: 7788 + serverID: Please enter the server id. + agentID: Please enter the agent id. + agentPassword: Please enter the agent password. + localPort: 7788 + channel: Please enter the channel. + + # Webrtc: Only supports using whip standard + whip: + url: http://114.235.183.163:1985/rtc/v1/whip/?app=live/livesteam&stream= # Example:http://192.168.1.1:1985/rtc/v1/whip/?app=live&stream= diff --git a/dk-modules/sample/src/main/resources/hms.json b/dk-modules/sample/src/main/resources/hms.json new file mode 100644 index 0000000..5e4598b --- /dev/null +++ b/dk-modules/sample/src/main/resources/hms.json @@ -0,0 +1,28644 @@ +{ + "dock_tip_0x12040000": { + "en": "Dock RTK device disconnected", + "zh": "机场RTK设备断连" + }, + "dock_tip_0x12040001": { + "en": "Dock moved", + "zh": "机场位置被移动" + }, + "dock_tip_0x12040002": { + "en": "Dock RTK error", + "zh": "机场RTK工作异常" + }, + "dock_tip_0x12040003": { + "en": "Location calibrated by RTK device far from current dock location", + "zh": "机场RTK标定位置距离机场位置过远" + }, + "dock_tip_0x12040004": { + "en": "Dock RTK initialization error", + "zh": "机场RTK初始化收敛失败" + }, + "dock_tip_0x160900BF": { + "en": "Wind speed too high (≥9 m/s). Unable to perform task", + "zh": "风速过大(≥9 m/s),无法执行飞行任务" + }, + "dock_tip_0x17000001": { + "en": "No image transmission signal", + "zh": "无图传信号" + }, + "dock_tip_0x17000004": { + "en": "Image transmission signal weak", + "zh": "图传信号弱" + }, + "dock_tip_0x17000005": { + "en": "Strong signal interference in dock location. Fly with caution", + "zh": "机场所在位置信号干扰较强,请注意飞行安全" + }, + "dock_tip_0x17110041": { + "en": "Dock working status error. Aircraft may perform signal lost action", + "zh": "机场工作状态异常,飞行器可能执行航线失联行为" + }, + "dock_tip_0x1910F003": { + "en": "Dock external security camera not installed or disconnected", + "zh": "机场舱外监控摄像头未安装或断连" + }, + "dock_tip_0x19110000": { + "en": "Dock %1$s cover motor stalled", + "zh": "%1$s舱盖电机堵转" + }, + "dock_tip_0x19110002": { + "en": "Dock %1$s cover excessive position error", + "zh": "%1$s舱盖位置误差过大" + }, + "dock_tip_0x19110003": { + "en": "Dock %1$s cover motor overspeed", + "zh": "%1$s舱盖电机运动超速" + }, + "dock_tip_0x19110004": { + "en": "Dock %1$s cover motor out of control", + "zh": "%1$s舱盖电机无法控制" + }, + "dock_tip_0x19110005": { + "en": "Dock %1$s cover motor voltage too low", + "zh": "%1$s舱盖电机电压过低" + }, + "dock_tip_0x19110006": { + "en": "Dock %1$s cover motor voltage too high", + "zh": "%1$s舱盖电机电压过高" + }, + "dock_tip_0x1911000F": { + "en": "Dock %1$s cover motor driver communication error", + "zh": "%1$s舱盖驱动器通讯异常" + }, + "dock_tip_0x19110011": { + "en": "Dock %1$s cover unknown error", + "zh": "%1$s舱盖运行未知错误" + }, + "dock_tip_0x19110012": { + "en": "Dock %1$s cover position calibration data error", + "zh": "%1$s舱盖位置校准数据错误" + }, + "dock_tip_0x19110013": { + "en": "Dock %1$s cover not properly open or closed", + "zh": "%1$s舱盖开启或关闭时位置不到位" + }, + "dock_tip_0x19110014": { + "en": "Opening dock %1$s cover timed out", + "zh": "%1$s舱盖开启超时" + }, + "dock_tip_0x19110015": { + "en": "Closing dock %1$s cover timed out", + "zh": "%1$s舱盖关闭超时" + }, + "dock_tip_0x19110016": { + "en": "Dock %1$s cover stalled. Failed to close", + "zh": "%1$s舱盖关闭时触发防夹,未成功关闭" + }, + "dock_tip_0x19110017": { + "en": "Dock %1$s cover stalled. Failed to open", + "zh": "%1$s舱盖开启时触发防夹,未成功开启" + }, + "dock_tip_0x19110020": { + "en": "%s dock cover Hall sensor error", + "zh": "%s舱盖霍尔传感器故障" + }, + "dock_tip_0x19110021": { + "en": "Opening or closing %s dock cover timed out", + "zh": "%s舱盖开启或关闭超时" + }, + "dock_tip_0x19110022": { + "en": "Opening or closing %s dock cover triggered pinch protection", + "zh": "%s舱盖打开或关闭时触发防夹" + }, + "dock_tip_0x19110023": { + "en": "Driving rod of %s dock cover voltage too low", + "zh": "%s舱盖推杆电压过低" + }, + "dock_tip_0x19110024": { + "en": "Driving rod of %s dock cover disconnected", + "zh": "%s舱盖推杆断线" + }, + "dock_tip_0x19110025": { + "en": "%s driving rod short-circuited", + "zh": "%s推杆短路" + }, + "dock_tip_0x19110026": { + "en": "%s driving rod temperature too high", + "zh": "%s推杆温度过高" + }, + "dock_tip_0x19110027": { + "en": "%s dock cover error", + "zh": "%s舱盖异常" + }, + "dock_tip_0x19110028": { + "en": "%s flight pause button error", + "zh": "%s急停按钮故障" + }, + "dock_tip_0x19110029": { + "en": "%s dock cover command execution failed", + "zh": "%s舱盖命令执行失败" + }, + "dock_tip_0x1911002A": { + "en": "%s dock cover not sealed", + "zh": "%s舱盖未处于密封状态" + }, + "dock_tip_0x19110400": { + "en": "Dock %1$s driving rod position calibration data error", + "zh": "%1$s推杆位置标定数据错误" + }, + "dock_tip_0x19110401": { + "en": "Dock %1$s driving rod steering gear stalled", + "zh": "%1$s推杆舵机堵转" + }, + "dock_tip_0x19110402": { + "en": "Excessive resistance in steering %1$s driving rod", + "zh": "%1$s推杆舵机阻力过大" + }, + "dock_tip_0x19110403": { + "en": "Dock %1$s driving rod steering gear overheated", + "zh": "%1$s推杆舵机温度过高" + }, + "dock_tip_0x19110404": { + "en": "Dock %1$s driving rod steering gear communication error", + "zh": "%1$s推杆舵机通讯异常" + }, + "dock_tip_0x19110405": { + "en": "Dock %1$s driving rod steering gear internal error", + "zh": "%1$s推杆舵机内部错误" + }, + "dock_tip_0x19110406": { + "en": "Dock %1$s driving rod internal limit switch error", + "zh": "%1$s推杆内侧限位开关工作异常" + }, + "dock_tip_0x19110407": { + "en": "Dock %1$s driving rod internal limit switch error", + "zh": "%1$s推杆内侧限位开关工作异常" + }, + "dock_tip_0x19110408": { + "en": "Dock %1$s driving rod external limit switch error", + "zh": "%1$s推杆外侧限位开关工作异常" + }, + "dock_tip_0x19110409": { + "en": "Dock %1$s driving rod external limit switch error", + "zh": "%1$s推杆外侧限位开关工作异常" + }, + "dock_tip_0x1911040B": { + "en": "Pushing %1$s driving rod timed out", + "zh": "%1$s推杆闭合超时" + }, + "dock_tip_0x1911040C": { + "en": "Pulling %1$s driving rod timed out", + "zh": "%1$s推杆展开超时" + }, + "dock_tip_0x19110800": { + "en": "Failed to charge dock backup battery", + "zh": "机场蓄电池无法充电" + }, + "dock_tip_0x19110801": { + "en": "Dock backup battery level low", + "zh": "机场蓄电池电量低" + }, + "dock_tip_0x19110802": { + "en": "Dock backup battery overheated", + "zh": "机场蓄电池温度过高" + }, + "dock_tip_0x19110803": { + "en": "Dock backup battery temperature too low", + "zh": "机场蓄电池温度过低" + }, + "dock_tip_0x19110804": { + "en": "Dock backup battery switch not turned on", + "zh": "机场蓄电池开关未开启" + }, + "dock_tip_0x19110805": { + "en": "Dock backup battery completely depleted. Unable to work properly", + "zh": "机场蓄电池过度放电,已无法正常工作" + }, + "dock_tip_0x19110806": { + "en": "Dock backup battery charging function error", + "zh": "机场蓄电池充电功能异常" + }, + "dock_tip_0x19110807": { + "en": "Dock backup battery charging function error", + "zh": "机场蓄电池充电功能异常" + }, + "dock_tip_0x19110C00": { + "en": "Dock security camera not installed or disconnected", + "zh": "机场监控摄像头未安装或断连" + }, + "dock_tip_0x19111400": { + "en": "Dock electrical cabinet cover open", + "zh": "机场配电柜柜门被打开" + }, + "dock_tip_0x19111401": { + "en": "Door sensor of dock electrical cabinet error", + "zh": "机场配电柜柜门传感器异常" + }, + "dock_tip_0x19111402": { + "en": "Door sensor of dock electrical cabinet error", + "zh": "机场配电柜柜门传感器异常" + }, + "dock_tip_0x19111800": { + "en": "Emergency stop button pressed down", + "zh": "急停按钮被按下" + }, + "dock_tip_0x19111D01": { + "en": "Aircraft inside dock is not linked. Linked aircraft is outside of dock", + "zh": "舱内飞行器未对频,已对频飞行器在舱外" + }, + "dock_tip_0x19112C01": { + "en": "Temperature sensor of dock control module damaged", + "zh": "机场主控模块温度传感器损坏" + }, + "dock_tip_0x19112C02": { + "en": "Temperature sensor of dock control module damaged", + "zh": "机场主控模块温度传感器损坏" + }, + "dock_tip_0x19112C03": { + "en": "Dock environment temperature sensor damaged", + "zh": "机场环境温度传感器损坏" + }, + "dock_tip_0x19112C04": { + "en": "Temperature sensor of dock control module damaged", + "zh": "机场主控模块温度传感器损坏" + }, + "dock_tip_0x19112C05": { + "en": "Temperature sensor of dock control module damaged", + "zh": "机场主控模块温度传感器损坏" + }, + "dock_tip_0x19112C06": { + "en": "Temperature sensor of dock left charging connector damaged", + "zh": "机场左侧充电连接器温度传感器损坏" + }, + "dock_tip_0x19112C07": { + "en": "Temperature sensor of dock right charging connector damaged", + "zh": "机场右侧充电连接器温度传感器损坏" + }, + "dock_tip_0x19112C08": { + "en": "Temperature sensor of landing pad interface board damaged", + "zh": "停机坪接口板温度传感器损坏" + }, + "dock_tip_0x19112C09": { + "en": "Temperature sensor of landing pad interface board damaged", + "zh": "停机坪接口板温度传感器损坏" + }, + "dock_tip_0x19112C0A": { + "en": "Temperature sensor of landing pad interface board damaged", + "zh": "停机坪接口板温度传感器损坏" + }, + "dock_tip_0x19112C0B": { + "en": "Temperature sensor of dock control module damaged", + "zh": "机场主控模块温度传感器损坏" + }, + "dock_tip_0x19112C0C": { + "en": "Temperature sensor of dock control module not connected", + "zh": "机场主控模块温度传感器未连接" + }, + "dock_tip_0x19112C0D": { + "en": "Temperature sensor of dock charging module damaged", + "zh": "机场充电电源模块温度传感器损坏" + }, + "dock_tip_0x19112C0E": { + "en": "Temperature sensor of dock charging module not connected", + "zh": "机场充电电源模块温度传感器未连接" + }, + "dock_tip_0x19112C0F": { + "en": "Temperature sensor of dock battery module damaged", + "zh": "机场电源模块温度传感器损坏" + }, + "dock_tip_0x19112C10": { + "en": "Temperature sensor of dock power module not connected", + "zh": "机场电源模块温度传感器未连接" + }, + "dock_tip_0x19112C11": { + "en": "Temperature sensor of dock battery module connector damaged", + "zh": "机场电源模块连接器温度传感器损坏" + }, + "dock_tip_0x19112C12": { + "en": "Temperature sensor of dock battery module connector not connected", + "zh": "机场电源模块连接器温度传感器未连接" + }, + "dock_tip_0x19112C13": { + "en": "Temperature sensor of dock charging module connector damaged", + "zh": "机场充电模块连接器温度传感器损坏" + }, + "dock_tip_0x19112C14": { + "en": "Temperature sensor of dock charging module connector not connected", + "zh": "机场充电模块连接器温度传感器未连接" + }, + "dock_tip_0x19112C15": { + "en": "Temperature sensor of dock AC battery module damaged", + "zh": "机场空调电源模块温度传感器损坏" + }, + "dock_tip_0x19112C16": { + "en": "Temperature sensor of dock AC battery module not connected", + "zh": "机场空调电源模块温度传感器未连接" + }, + "dock_tip_0x19112C17": { + "en": "Temperature sensor of dock AC battery module connector damaged", + "zh": "机场空调电源模块连接器温度传感器损坏" + }, + "dock_tip_0x19112C18": { + "en": "Temperature sensor of dock AC battery module connector not connected", + "zh": "机场空调电源模块连接器温度传感器未连接" + }, + "dock_tip_0x19112C19": { + "en": "Temperature sensor of dock backup battery damaged", + "zh": "机场蓄电池温度传感器损坏" + }, + "dock_tip_0x19112C1A": { + "en": "Temperature sensor of dock backup battery not connected", + "zh": "机场蓄电池温度传感器未连接" + }, + "dock_tip_0x19113000": { + "en": "Dock vibration sensor error", + "zh": "机场振动传感器工作异常" + }, + "dock_tip_0x19113001": { + "en": "Dock vibration detected. Dock may be moved or damaged", + "zh": "机场产生振动,可能被移动或遭到破坏" + }, + "dock_tip_0x19113401": { + "en": "Aircraft battery charge voltage error", + "zh": "飞行器电池充电电压异常" + }, + "dock_tip_0x19113403": { + "en": "Aircraft battery not properly installed, or battery level too low and battery enters hibernation mode", + "zh": "飞行器电池不在位,或电量极低已进入休眠模式" + }, + "dock_tip_0x19113404": { + "en": "Failed to charge aircraft battery", + "zh": "飞行器电池充电失败" + }, + "dock_tip_0x19113406": { + "en": "Aircraft battery error", + "zh": "飞行器电池异常" + }, + "dock_tip_0x19113407": { + "en": "Dock power supply module error. Unable to charge aircraft", + "zh": "机场供电电源模块异常,无法给飞行器电池充电" + }, + "dock_tip_0x19113414": { + "en": "Battery overheated (≥44° C). Unable to start charging", + "zh": "电池温度过高(≥44℃)无法开始充电" + }, + "dock_tip_0x19113800": { + "en": "Dock internal power module error", + "zh": "机场内部电源模块工作异常" + }, + "dock_tip_0x19113802": { + "en": "Dock electronic module power supply error", + "zh": "机场弱电模块供电异常" + }, + "dock_tip_0x19113803": { + "en": "Dock power supply disconnected", + "zh": "机场供电电源断开" + }, + "dock_tip_0x19113806": { + "en": "Dock battery module error", + "zh": "机场电源模块故障" + }, + "dock_tip_0x19113807": { + "en": "Output voltage of dock battery module too high", + "zh": "机场电源模块输出电压过高" + }, + "dock_tip_0x19113808": { + "en": "Output voltage of dock battery module too low", + "zh": "机场电源模块输出电压过低" + }, + "dock_tip_0x19113809": { + "en": "Dock battery module temperature too high", + "zh": "机场电源模块温度过高" + }, + "dock_tip_0x1911380A": { + "en": "Dock battery module temperature too low", + "zh": "机场电源模块温度过低" + }, + "dock_tip_0x1911380B": { + "en": "Dock battery module connector temperature too high", + "zh": "机场电源模块连接器温度过高" + }, + "dock_tip_0x1911380C": { + "en": "Dock battery module connector temperature too low", + "zh": "机场电源模块连接器温度过低" + }, + "dock_tip_0x19113901": { + "en": "Battery voltage of dock system too high", + "zh": "机场系统电源电压过高" + }, + "dock_tip_0x19113902": { + "en": "Battery voltage of dock system too low", + "zh": "机场系统电源电压过低" + }, + "dock_tip_0x19113903": { + "en": "Dock control module powered off abnormally", + "zh": "机场主控模块异常掉电" + }, + "dock_tip_0x19113C00": { + "ar": "", + "de": "", + "en": "Surge protector circuit breaker not turned on, or surge protector device damaged", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "防雷器后备保护器开关未开启,或防雷器损坏", + "zh-Hant": "" + }, + "dock_tip_0x19113C01": { + "en": "Landing pad connection error", + "zh": "停机坪连接异常" + }, + "dock_tip_0x19113C02": { + "en": "Rainfall gauge connection error", + "zh": "雨量计连接异常" + }, + "dock_tip_0x19113C03": { + "en": "AC connection error", + "zh": "空调连接异常" + }, + "dock_tip_0x19113C04": { + "en": "Dock charging module connection error", + "zh": "机场充电模块连接异常" + }, + "dock_tip_0x19113D00": { + "en": "AC cooler damaged", + "zh": "空调制冷片损坏" + }, + "dock_tip_0x19113D01": { + "en": "AC cooler damaged", + "zh": "空调制冷片损坏" + }, + "dock_tip_0x19113D02": { + "en": "AC cooler damaged", + "zh": "空调制冷片损坏" + }, + "dock_tip_0x19113D03": { + "en": "AC heater damaged", + "zh": "空调加热器损坏" + }, + "dock_tip_0x19113D04": { + "en": "AC heater damaged", + "zh": "空调加热器损坏" + }, + "dock_tip_0x19113D05": { + "en": "AC internal circulation fan damaged", + "zh": "空调内循环风扇损坏" + }, + "dock_tip_0x19113D06": { + "en": "AC external circulation fan damaged", + "zh": "空调外循环风扇损坏" + }, + "dock_tip_0x19113D07": { + "en": "Temperature sensor of AC external circulation supply vent damaged", + "zh": "空调外循环出风口温度传感器损坏" + }, + "dock_tip_0x19113D08": { + "en": "Temperature sensor of AC internal circulation return vent damaged", + "zh": "空调内循环进风口温度传感器损坏" + }, + "dock_tip_0x19113D09": { + "en": "Temperature sensor on the right of AC internal circulation supply vent damaged", + "zh": "空调内循环出风口右侧温度传感器损坏" + }, + "dock_tip_0x19113D0A": { + "en": "Temperature sensor on the left of AC internal circulation supply vent damaged", + "zh": "空调内循环出风口左侧温度传感器损坏" + }, + "dock_tip_0x19113D0B": { + "en": "AC cooler temperature sensor damaged", + "zh": "空调制冷片温度传感器损坏" + }, + "dock_tip_0x19113D0C": { + "en": "Temperature sensor of AC internal circulation tube damaged", + "zh": "空调内循环风道温度传感器损坏" + }, + "dock_tip_0x19113D0D": { + "en": "Dock cover damaged, or unable to close cover properly", + "zh": "舱盖破损或无法完全关闭" + }, + "dock_tip_0x19113D0E": { + "en": "AC internal circulation return vent blocked", + "zh": "空调内循环进风口堵塞" + }, + "dock_tip_0x19113D0F": { + "en": "AC internal circulation supply vent blocked", + "zh": "空调内循环出风口堵塞" + }, + "dock_tip_0x19113D10": { + "en": "Large temperature difference (≥20° C) between AC internal circulation supply and return vents", + "zh": "空调外循环出风口与进风口温差过大(≥20℃)" + }, + "dock_tip_0x19113D11": { + "en": "AC cooler power supply error", + "zh": "空调制冷片供电异常" + }, + "dock_tip_0x19113D12": { + "en": "AC heater power supply error", + "zh": "空调加热器供电异常" + }, + "dock_tip_0x19113D13": { + "en": "AC external circulation fan power supply error", + "zh": "空调外循环风扇供电异常" + }, + "dock_tip_0x19113D14": { + "en": "AC internal circulation fan power supply error", + "zh": "空调内循环风扇供电异常" + }, + "dock_tip_0x19113D15": { + "en": "AC power supply error", + "zh": "空调供电异常" + }, + "dock_tip_0x19113D16": { + "en": "", + "es": "", + "ja": "", + "ko": "", + "zh": "空调外循环进风口堵塞" + }, + "dock_tip_0x19113D20": { + "en": "Temperature sensor of return vent of AC external circulation damaged", + "zh": "空调外循环进风口温度传感器损坏" + }, + "dock_tip_0x19113D21": { + "en": "Temperature sensor of supply vent of AC internal circulation damaged", + "zh": "空调内循环出风口温度传感器损坏" + }, + "dock_tip_0x19113D22": { + "en": "Temperature sensor of AC TEC cold side damaged", + "zh": "空调TEC冷端温度传感器损坏" + }, + "dock_tip_0x19113D23": { + "en": "Large temperature difference between AC external circulation supply vent and return vent (≥10° C)", + "zh": "空调外循环出风口与进风口温差过大(≥10℃)" + }, + "dock_tip_0x19113D24": { + "en": "NTC temperature sensor of left driving rod damaged", + "zh": "左推杆温感NTC温度传感器损坏" + }, + "dock_tip_0x19113D25": { + "en": "NTC temperature sensor of right driving rod damaged", + "zh": "右推杆温感NTC温度传感器损坏" + }, + "dock_tip_0x19113D26": { + "en": "High temperature warning (≥45℃)", + "zh": "高温预警(≥45℃)" + }, + "dock_tip_0x19113D27": { + "en": "Low temperature warning (≤-20℃)", + "zh": "低温预警(≤-20℃)" + }, + "dock_tip_0x19113D28": { + "en": "Temperature sensor of AC external circulation supply vent short-circuited", + "zh": "空调外循环出风口温度传感器短路" + }, + "dock_tip_0x19113D29": { + "en": "Temperature sensor of AC internal circulation return vent short-circuited", + "zh": "空调内循环进风口温度传感器短路" + }, + "dock_tip_0x19113D2A": { + "en": "AC cooler temperature sensor short-circuited", + "zh": "空调制冷片温度传感器短路" + }, + "dock_tip_0x19113D2B": { + "en": "Temperature sensor of AC TEC cold side short-circuited", + "zh": "空调TEC冷端温度传感器短路" + }, + "dock_tip_0x19113D2C": { + "en": "Temperature sensor of AC external circulation return vent short-circuited", + "zh": "空调外循环进风口温度传感器短路" + }, + "dock_tip_0x19113D2D": { + "en": "Temperature sensor of AC internal circulation supply vent short-circuited", + "zh": "空调内循环出风口温度传感器短路" + }, + "dock_tip_0x19113D2E": { + "en": "NTC temperature sensor of left driving rod short-circuited", + "zh": "左推杆温感NTC温度传感器短路" + }, + "dock_tip_0x19113D2F": { + "en": "NTC temperature sensor of right driving rod short-circuited", + "zh": "右推杆温感NTC温度传感器短路" + }, + "dock_tip_0x19114000": { + "en": "Wind speed too high (≥ 9 m/s). Unable to perform task", + "zh": "风速过大(≥9 m/s),无法执行飞行任务" + }, + "dock_tip_0x19114800": { + "en": "Heavy rainfall. Unable to perform task", + "zh": "雨量过大,无法执行飞行任务" + }, + "dock_tip_0x19114801": { + "en": "Dock security camera power supply error", + "zh": "机场监控摄像头供电异常" + }, + "dock_tip_0x19114802": { + "en": "DJI Cellular Dongle power supply error", + "zh": "DJI Cellular 模块供电异常" + }, + "dock_tip_0x19114803": { + "en": "Power supply error in status indicator on dock cover", + "zh": "舱盖告警灯供电异常" + }, + "dock_tip_0x19114804": { + "en": "Wind speed gauge heating module power supply error", + "zh": "风速计加热供电异常" + }, + "dock_tip_0x19114805": { + "en": "Temperature and humidity sensor connection error", + "zh": "舱内温湿度传感器连接异常" + }, + "dock_tip_0x19114806": { + "en": "Rainfall gauge connection error", + "zh": "雨量计连接异常" + }, + "dock_tip_0x19114807": { + "en": "Rainfall gauge heating module power supply error", + "zh": "雨量计加热模块供电异常" + }, + "dock_tip_0x19114808": { + "en": "Temperature sensor of rainfall gauge heating module connection error", + "zh": "雨量计加热模块温度传感器连接异常" + }, + "dock_tip_0x19114809": { + "en": "Temperature sensor of rainfall gauge heating module overheated", + "zh": "雨量计加热模块温度传感器温度过高" + }, + "dock_tip_0x1911480A": { + "en": "Temperature sensor of wind speed gauge heating module damaged", + "zh": "风速计加热模块温度传感器损坏" + }, + "dock_tip_0x1911480B": { + "en": "Temperature sensor of wind speed gauge heating module overheated", + "zh": "风速计加热模块温度传感器温度过高" + }, + "dock_tip_0x1911480C": { + "en": "Dock cover temperature sensor damaged. Heating module unable to work properly in low-temperature environments", + "zh": "舱盖除冰加热温度传感器损坏" + }, + "dock_tip_0x1911480D": { + "en": "Dock cover temperature sensor overheated. Heating module failed to work properly", + "zh": "舱盖除冰加热温度传感器温度过高" + }, + "dock_tip_0x1911480E": { + "en": "Rainfall gauge connection error", + "zh": "雨量计连接异常" + }, + "dock_tip_0x1911480F": { + "en": "Rainfall gauge short-circuited", + "zh": "雨量计短路" + }, + "dock_tip_0x19114810": { + "en": "", + "es": "", + "ja": "", + "ko": "", + "zh": "风速计模块连接异常" + }, + "dock_tip_0x19114811": { + "en": "Hall temperature sensor of wind speed gauge damaged", + "zh": "风速计霍尔温度传感器损坏" + }, + "dock_tip_0x19114812": { + "en": "Hall temperature sensor of wind speed gauge damaged", + "zh": "风速计霍尔温度传感器损坏" + }, + "dock_tip_0x19114813": { + "en": "Temperature and humidity sensor self-heating time too long", + "zh": "温湿度传感器自加热时间过久" + }, + "dock_tip_0x19114814": { + "en": "Rainfall gauge damaged", + "zh": "雨量计检测部件损坏" + }, + "dock_tip_0x19114815": { + "en": "Rainfall gauge damaged", + "zh": "雨量计检测部件损坏" + }, + "dock_tip_0x19114C00": { + "en": "Water immersion detected", + "zh": "机场浸水" + }, + "dock_tip_0x19115000": { + "en": "Error occurred and dock restarted", + "zh": "机场异常重启" + }, + "dock_tip_0x19116000": { + "en": "Battery of dock charging module error", + "zh": "机场充电模块电源故障" + }, + "dock_tip_0x19116001": { + "en": "Battery voltage of dock charging module too high", + "zh": "机场充电模块电源电压过高" + }, + "dock_tip_0x19116002": { + "en": "Battery voltage of dock charging module too low", + "zh": "机场充电模块电源电压过低" + }, + "dock_tip_0x19116003": { + "en": "Electric current of dock charging module too large", + "zh": "机场充电模块电源电流过大" + }, + "dock_tip_0x19116004": { + "en": "Electric current of dock charging module too small", + "zh": "机场充电模块电源电流过小" + }, + "dock_tip_0x19116005": { + "en": "Battery MOS of dock charging module temperature too high", + "zh": "机场充电模块电源MOS温度过高" + }, + "dock_tip_0x19116006": { + "en": "Battery MOS of dock charging module temperature too low", + "zh": "机场充电模块电源MOS温度过低" + }, + "dock_tip_0x19116007": { + "en": "Controller battery of dock charging module error", + "zh": "机场充电模块控制器电源异常" + }, + "dock_tip_0x19116008": { + "en": "Dock charging module connector temperature too high", + "zh": "机场充电模块连接器温度过高" + }, + "dock_tip_0x19116009": { + "en": "Dock charging module connector temperature too low", + "zh": "机场充电模块连接器温度过低" + }, + "dock_tip_0x1911600A": { + "en": "Dock AC battery power supply error", + "zh": "机场空调电源模块供电异常" + }, + "dock_tip_0x1911600B": { + "en": "Dock AC battery voltage too high", + "zh": "机场空调电源模块电压过高" + }, + "dock_tip_0x1911600C": { + "en": "Dock AC battery voltage too low", + "zh": "机场空调电源模块电压过低" + }, + "dock_tip_0x1911600D": { + "en": "Electric current of dock AC power module too large", + "zh": "机场空调电源模块电流过大" + }, + "dock_tip_0x1911600E": { + "en": "Electric current of dock AC power module too small", + "zh": "机场空调电源模块电流过小" + }, + "dock_tip_0x1911600F": { + "en": "Dock AC controller module battery error", + "zh": "机场空调控制器模块电源故障" + }, + "dock_tip_0x19116010": { + "en": "Electric current of dock AC controller module too large", + "zh": "机场空调控制器模块电流过大" + }, + "dock_tip_0x19116011": { + "en": "Electric current of dock AC controller module too small", + "zh": "机场空调控制器模块电流过小" + }, + "dock_tip_0x19116012": { + "en": "Battery MOS of dock AC module temperature too high", + "zh": "机场空调模块电源MOS温度过高" + }, + "dock_tip_0x19116013": { + "en": "Battery MOS of dock AC module temperature too low", + "zh": "机场空调模块电源MOS温度过低" + }, + "dock_tip_0x19116014": { + "en": "AC module connector temperature too high", + "zh": "空调模块连接器温度过高" + }, + "dock_tip_0x19116015": { + "en": "AC module connector temperature too low", + "zh": "空调模块连接器温度过低" + }, + "dock_tip_0x19116016": { + "en": "Battery of weather station module error", + "zh": "气象站模块电源故障" + }, + "dock_tip_0x19116017": { + "en": "Electric current of weather station module too large", + "zh": "气象站模块电源电流过大" + }, + "dock_tip_0x19116018": { + "en": "Electric current of weather station module too small", + "zh": "气象站模块电源电流过小" + }, + "dock_tip_0x1911601B": { + "en": "Battery of dock image transmission module error", + "zh": "机场图传模块电源异常" + }, + "dock_tip_0x1911601F": { + "en": "Battery voltage of dock internal security camera too high", + "zh": "机场舱内监控摄像头电压过高" + }, + "dock_tip_0x19116020": { + "en": "Battery voltage of dock internal security camera too low", + "zh": "机场舱内监控摄像头电压过低" + }, + "dock_tip_0x19116021": { + "en": "Battery voltage of right dock cover too high", + "zh": "右舱盖电源电压过高" + }, + "dock_tip_0x19116022": { + "en": "Battery voltage of right dock cover too low", + "zh": "右舱盖电源电压过低" + }, + "dock_tip_0x19116023": { + "en": "Dock control module temperature too high", + "zh": "机场主控模块温度过高" + }, + "dock_tip_0x19116024": { + "en": "Dock control module temperature too low", + "zh": "机场主控模块温度过低" + }, + "dock_tip_0x19117000": { + "en": "Failed to recharge aircraft battery", + "zh": "飞行器电池充电失败" + }, + "dock_tip_0x19117021": { + "en": "Dock cover moving. Charging aircraft battery failed", + "zh": "舱盖运动中,飞行器电池充电失败" + }, + "dock_tip_0x19117022": { + "en": "Updating dock. Charging aircraft battery failed", + "zh": "机场升级中,飞行器电池充电失败" + }, + "dock_tip_0x19117023": { + "en": "No aircraft found", + "zh": "未检测到飞行器" + }, + "dock_tip_0x19117024": { + "en": "Metal foreign objects detected in dock charging module. Charging aircraft battery failed", + "zh": "机场充电模块检测到金属异物,飞行器电池充电失败" + }, + "dock_tip_0x19117025": { + "en": "Dock cover opened. Charging aircraft battery failed", + "zh": "检测到机场舱盖已打开,飞行器充电失败" + }, + "dock_tip_0x19117041": { + "en": "Aircraft not connected", + "zh": "飞行器未连接" + }, + "dock_tip_0x19117043": { + "en": "Aircraft battery level critically low. Unable to power on aircraft", + "zh": "飞行器严重低电量,无法开机" + }, + "dock_tip_0x19117045": { + "en": "Aircraft battery error. Unable to charge battery or power on aircraft", + "zh": "飞行器电池故障,无法充电或开机" + }, + "dock_tip_0x19117046": { + "en": "Aircraft battery communication error", + "zh": "飞行器电池通信异常" + }, + "dock_tip_0x19117047": { + "en": "Aircraft battery level high. No battery charging required", + "zh": "飞行器电量较高,无需充电" + }, + "dock_tip_0x19117048": { + "en": "Aircraft wireless charging module error", + "zh": "飞行器无线充电模块异常" + }, + "dock_tip_0x19117061": { + "en": "Waking aircraft charging module failed", + "zh": "飞行器充电模块唤醒失败" + }, + "dock_tip_0x19117202": { + "en": "Powering on aircraft timed out", + "zh": "飞行器开机超时" + }, + "dock_tip_0x19117221": { + "en": "Failed to connect dock to aircraft Bluetooth", + "zh": "机场连接飞行器蓝牙失败" + }, + "dock_tip_0x19117222": { + "en": "Dock Bluetooth link error", + "zh": "机场蓝牙模块链路故障" + }, + "dock_tip_0x19117223": { + "en": "Aircraft Bluetooth signal weak", + "zh": "飞行器蓝牙模块信号弱" + }, + "dock_tip_0x19117321": { + "en": "Aircraft image transmission link error. Powering off failed", + "zh": "飞行器图传链路异常,关机失败" + }, + "dock_tip_0x19117322": { + "en": "Powering off aircraft timed out", + "zh": "飞行器关机超时" + }, + "dock_tip_0x19117460": { + "en": "Battery voltage of dock charging module too low", + "zh": "机场充电电源模块电压过低" + }, + "dock_tip_0x19117461": { + "en": "Electric current of dock charging module too large", + "zh": "机场充电电源模块电流过大" + }, + "dock_tip_0x19117462": { + "en": "Electric current of aircraft charging module coil too large", + "zh": "飞行器充电模块线圈电流过大" + }, + "dock_tip_0x19117463": { + "en": "Aircraft charging module error", + "zh": "飞行器充电电源故障" + }, + "dock_tip_0x19117464": { + "en": "Battery voltage of aircraft charging module too high", + "zh": "飞行器充电电源过压" + }, + "dock_tip_0x19117465": { + "en": "Battery voltage of dock charging module too high", + "zh": "机场充电电源过压" + }, + "dock_tip_0x19117470": { + "en": "Aircraft charging module error", + "zh": "飞行器充电电源故障" + }, + "dock_tip_0x19117480": { + "en": "Dock charging module temperature too high", + "zh": "机场充电模块温度过高" + }, + "dock_tip_0x19117481": { + "en": "Electric current of dock charging module too large", + "zh": "机场充电模块充电电流过大" + }, + "dock_tip_0x191174A0": { + "en": "Temperature of dock charging module coil too high", + "zh": "机场充电模块线圈温度过高" + }, + "dock_tip_0x191174B0": { + "en": "Temperature of dock wireless charging module error", + "zh": "机场无线充电模块温度检测异常" + }, + "dock_tip_0x191174B1": { + "en": "Temperature sensor of dock charging module coil not connected", + "zh": "机场充电模块线圈温度传感器未连接" + }, + "dock_tip_0x191174B2": { + "en": "Temperature sensor of dock charging module coil error", + "zh": "机场充电模块线圈温度传感器异常" + }, + "dock_tip_0x191174C0": { + "en": "Temperature of aircraft charging module coil too high", + "zh": "飞行器充电模块线圈温度过高" + }, + "dock_tip_0x191174D0": { + "en": "Temperature of aircraft wireless charging module error", + "zh": "飞行器无线充电模块温度检测异常" + }, + "dock_tip_0x191174D1": { + "en": "Temperature sensor of aircraft charging module coil not connected", + "zh": "飞行器充电模块线圈温度传感器未连接" + }, + "dock_tip_0x191174D2": { + "en": "Temperature sensor of aircraft charging module coil error", + "zh": "飞行器充电模块线圈温度传感器异常" + }, + "fpv_tip_0x11000002": { + "en": "Aircraft power distribution board 1 overheated. Return to home or land promptly", + "zh": "飞行器分电板1温度过高,请尽快返航或降落" + }, + "fpv_tip_0x11000003": { + "en": "Aircraft Power Distribution Board 2 overheated. Return to home or land promptly", + "zh": "飞行器分电板2温度过高,请尽快返航或降落" + }, + "fpv_tip_0x11000020": { + "de": "Spannung von Gimbal %index zu hoch (%alarmid)", + "en": "Gimbal %index payload voltage too high", + "es": "Voltaje de instrumento en el estabilizador %index demasiado alto", + "fr": "Tension de la nacelle %index trop élevée", + "ja": "ジンバル%indexペイロード高電圧", + "ko": "짐벌 %index 페이로드 전압 너무 높음", + "ru": "Слишком высокое напряжение оборудования стабилизатора %index", + "tr": "Gimbal %index yük voltajı çok yüksek", + "zh": "%index号云台位负载电压过高" + }, + "fpv_tip_0x11000021": { + "de": "Spannung von Gimbal %index zu niedrig (%alarmid)", + "en": "Gimbal %index payload voltage too low", + "es": "Voltaje de instrumento en el estabilizador %index demasiado bajo", + "fr": "Tension de la nacelle %index trop basse", + "ja": "ジンバル%indexペイロード低電圧", + "ko": "짐벌 %index 페이로드 전압 너무 낮음", + "ru": "Слишком низкое напряжение оборудования стабилизатора %index", + "tr": "Gimbal %index yük voltajı çok düşük", + "zh": "%index号云台位负载电压过低" + }, + "fpv_tip_0x11000022": { + "de": "Akkumodul von Gimbal %index überhitzt (%alarmid)", + "en": "Gimbal %index battery module overheated", + "es": "Módulo de batería del estabilizador %index sobrecalentado", + "fr": "Module de la batterie de la nacelle %index en surchauffe", + "ja": "ジンバル%indexバッテリーモジュール高温", + "ko": "짐벌 %index 배터리 모듈 과열", + "ru": "Перегрев модуля батареи стабилизатора %index", + "tr": "Gimbal %index pil modülü aşırı ısındı", + "zh": "%index号云台位电源温度过高" + }, + "fpv_tip_0x11000023": { + "de": "Akkutemperatur von Gimbal %index zu niedrig (%alarmid)", + "en": "Gimbal %index battery module temperature too low", + "es": "Temperatura del módulo de batería del estabilizador %index demasiado baja", + "fr": "Température du module de la batterie de la nacelle %index trop basse", + "ja": "ジンバル%indexバッテリーモジュール低温", + "ko": "짐벌 %index 배터리 모듈 온도 너무 낮음", + "ru": "Слишком низкая температура модуля батареи стабилизатора %index", + "tr": "Gimbal %index pil modülü sıcaklığı çok düşük", + "zh": "%index号云台位电源温度过低" + }, + "fpv_tip_0x11000024": { + "de": "Leistung aller Nutzlasten zu hoch", + "en": "Total payload power too high", + "es": "Potencia total de instrumento demasiado alta", + "fr": "Puissance totale de la charge utile trop élevée", + "ja": "合計ペイロード高電力", + "ko": "총 페이로드 전력 너무 높음", + "ru": "Слишком высокая мощность оборудования", + "tr": "Toplam yük gücü çok yüksek", + "zh": "负载总功率过载" + }, + "fpv_tip_0x11000025": { + "de": "Übertragungsfehler: Gimbal %index (%alarmid)", + "en": "Gimbal %index payload transmission error", + "es": "Error de transmisión del instrumento en el estabilizador %index", + "fr": "Erreur de transmission de la charge utile de la nacelle %index", + "ja": "ジンバル%indexペイロード伝送エラー", + "ko": "짐벌 %index 페이로드 전송 오류", + "ru": "Ошибка передачи оборудования стабилизатора %index", + "tr": "Gimbal %index yük iletim hatası", + "zh": "%index号云台负载链路异常" + }, + "fpv_tip_0x11000029": { + "de": "PSDK-Spannung zu hoch", + "en": "PSDK voltage too high", + "es": "Voltaje de PSDK demasiado alto", + "fr": "Tension PSDK trop élevée", + "it": "", + "ja": "PSDK高電圧", + "ko": "PSDK 전압 너무 높음", + "pt": "", + "ru": "Слишком высокое напряжение PSDK", + "tr": "PSDK voltajı çok yüksek", + "zh": "PSDK 设备电压过高" + }, + "fpv_tip_0x1100002A": { + "de": "PSDK-Spannung zu niedrig", + "en": "PSDK voltage too low", + "es": "Voltaje de PSDK demasiado bajo", + "fr": "Tension PSDK trop basse", + "it": "", + "ja": "PSDK低電圧", + "ko": "PSDK 전압 너무 낮음", + "pt": "", + "ru": "Слишком низкое напряжение PSDK", + "tr": "PSDK voltajı çok düşük", + "zh": "PSDK 设备电压过低" + }, + "fpv_tip_0x1100002B": { + "de": "PSDK %index Akkumodul überhitzt (%alarmid)", + "en": "PSDK battery module overheated", + "es": "Módulo de batería de PSDK sobrecalentado", + "fr": "Module de batterie du PSDK %index en surchauffe", + "it": "", + "ja": "PSDKバッテリーモジュール高温", + "ko": "PSDK %index 배터리 모듈 과열", + "pt": "", + "ru": "Перегрев модуля батареи %index PSDK", + "tr": "PSDK pil modülü aşırı ısındı", + "zh": "PSDK电源温度过高" + }, + "fpv_tip_0x1100002C": { + "de": "PSDK %index Akkutemperatur zu niedrig (%alarmid)", + "en": "PSDK battery module temperature too low", + "es": "Temperatura del módulo de batería PSDK demasiado baja", + "fr": "Température du module de batterie du PSDK %index trop basse", + "it": "", + "ja": "PSDKバッテリーモジュール低温", + "ko": "PSDK %index 배터리 모듈 온도 너무 낮음", + "pt": "", + "ru": "Слишком низкая температура модуля батареи %index PSDK", + "tr": "PSDK pil modülü sıcaklığı çok düşük", + "zh": "PSDK电源温度过低" + }, + "fpv_tip_0x1100002D": { + "de": "PSDK-Gerätenennleistung wurde überschritten. Wird neu gestartet...", + "en": "PSDK device rated power exceeded. Restarting...", + "es": "Se superó la potencia nominal del dispositivo PSDK. Reiniciando...", + "fr": "Puissance nominale de l'appareil PSDK dépassée. Redémarrage...", + "it": "", + "ja": "PSDK機器の定格出力を超えました。再起動しています", + "ko": "PSDK 기기 정격 출력이 초과됨. 재시동 중...", + "pt": "", + "ru": "Превышена номинальная мощность устройства PSDK. Выполняется перезапуск...", + "tr": "PSDK cihazı nominal gücü aşıldı. Yeniden başlatılıyor...", + "zh": "PSDK 设备功率过载,重启中" + }, + "fpv_tip_0x1100002E": { + "de": "PSDK-Gerätenennleistung wurde überschritten. Fehler beim Neustart", + "en": "PSDK device rated power exceeded. Failed to restart", + "es": "Se superó la potencia nominal del dispositivo PSDK. No se pudo reiniciar.", + "fr": "Puissance nominale de l'appareil PSDK dépassée. Échec du redémarrage", + "it": "", + "ja": "PSDK機器の定格出力を超えました。再起動に失敗しました", + "ko": "PSDK 기기 정격 출력이 초과됨. 재시동하지 못했습니다.", + "pt": "", + "ru": "Превышена номинальная мощность устройства PSDK. Не удалось выполнить перезапуск", + "tr": "PSDK cihazı nominal gücü aşıldı. Yeniden başlatılamadı", + "zh": "PSDK 设备功率过载,重启失败" + }, + "fpv_tip_0x11000034": { + "de": "Fehler in der Stromversorgung des Landegestellmotors. Fluggerät neu starten", + "en": "Landing gear motor power supply error. Restart aircraft", + "es": "Error de la fuente de alimentación del motor del tren de aterrizaje. Reinicia la aeronave", + "fr": "Erreur d’alimentation du moteur du train d’atterrissage. Redémarrer l’appareil", + "ja": "ランディングギアモーターの電源エラー。機体を再起動してください", + "ko": "랜딩 기어 모터 전력 공급 오류. 기체를 재시작하세요", + "ru": "Ошибка питания двигателя шасси. Перезапустите дрон", + "tr": "İniş takımı motoru güç kaynağı hatası. Hava aracını yeniden başlatın", + "zh": "起落架舵机供电异常,请尝试重启飞行器" + }, + "fpv_tip_0x11000035": { + "de": "Fehler in der Stromversorgung des Radars. Neustart des Radars empfohlen", + "en": "Radar power supply error. Restarting radar recommended", + "es": "Error de la fuente de alimentación del radar. Se recomienda reiniciar el radar", + "fr": "Erreur d’alimentation du radar. Redémarrage du radar recommandé", + "ja": "レーダーの電源エラー。レーダーの再起動をお勧めします", + "ko": "레이더 전력 공급 오류. 레이더 재시작 권장", + "ru": "Ошибка питания радара. Рекомендуется перезапустить радар", + "tr": "Radar güç kaynağı hatası. Radarın yeniden başlatılması önerilir", + "zh": "雷达供电异常,请尝试重启雷达" + }, + "fpv_tip_0x11000036": { + "de": "Fehler in der Stromversorgung des 4G-Moduls. Modul entfernen und wieder einsetzen", + "en": "4G module power supply error. Remove and insert module again", + "es": "Error de la fuente de alimentación del módulo 4G. Retira el módulo e insértalo de nuevo", + "fr": "Erreur d’alimentation du module 4G. Retirer et réinsérer le module", + "ja": "4Gモジュールの電源エラー。モジュールを取り付け直してください", + "ko": "4G 모듈 전력 공급 오류. 모듈을 제거했다가 다시 삽입하세요", + "ru": "Ошибка питания модуля 4G. Удалите и снова вставьте модуль", + "tr": "4G modül güç kaynağı hatası. Modülü çıkarın ve tekrar takın", + "zh": "4G 模块供电异常,请尝试拔插" + }, + "fpv_tip_0x11000037": { + "de": "Fehler in der Stromversorgung des Gimbals. Den Gimbal lösen und wieder montieren", + "en": "Gimbal power supply error. Detach and remount gimbal", + "es": "Error de la fuente de alimentación del estabilizador. Retira el estabilizador y vuélvelo a montar", + "fr": "Erreur d’alimentation de la nacelle. Détacher et remonter la nacelle", + "ja": "ジンバルの電源エラー。ジンバルを取り付け直してください", + "ko": "짐벌 전력 공급 오류. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Ошибка питания гиростабилизатора. Отсоедините и переустановите гиростабилизатор", + "tr": "Gimbal güç kaynağı hatası. Gimbalı çıkarın ve yeniden takın", + "zh": "云台供电异常,请尝试拔插云台" + }, + "fpv_tip_0x11000038": { + "de": "Der linke Akkuanschluss ist überhitzt. Zum Startpunkt zurückkehren oder umgehend landen", + "en": "Left battery connector overheated. Return to home or land promptly", + "es": "Conector de batería izquierdo sobrecalentado. Regresa al punto de origen o aterriza cuando antes.", + "fr": "Connecteur de batterie gauche en surchauffe. Retourner au point de départ ou atterrir rapidement", + "ja": "左バッテリーコネクターが高温。直ちに帰還するか、着陸してください", + "ko": "왼쪽 배터리 커넥터가 과열 상태입니다. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Разъем аккумуляторной батареи слева перегрелся. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Sol pil konektörü aşırı ısındı. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "左电池连接器温度过高,请尽快返航或降落" + }, + "fpv_tip_0x11000039": { + "de": "Der rechte Akkuanschluss ist überhitzt. Zum Startpunkt zurückkehren oder umgehend landen", + "en": "Right battery connector overheated. Return to home or land promptly", + "es": "Conector de batería derecho sobrecalentado. Regresa al punto de origen o aterriza cuando antes.", + "fr": "Connecteur de batterie droite en surchauffe. Retourner au point de départ ou atterrir rapidement", + "ja": "右バッテリーコネクターが高温。直ちに帰還するか、着陸してください", + "ko": "오른쪽 배터리 커넥터가 과열 상태입니다. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Разъем аккумуляторной батареи справа перегрелся. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Sağ pil konektörü aşırı ısındı. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "右电池连接器温度过高,请尽快返航或降落" + }, + "fpv_tip_0x1100003A": { + "de": "Der linke Akku ist nicht ordnungsgemäß eingesetzt. Akku entfernen und wieder einsetzen.", + "en": "Left battery not properly installed. Remove and reinstall battery", + "es": "La batería izquierda no está instalada correctamente. Retira la batería y vuelve a instalarla", + "fr": "La batterie gauche n’est pas correctement installée. Retirer et réinstaller la batterie", + "ja": "左バッテリーが正しく取り付けられていません。バッテリーを取り付け直してください", + "ko": "왼쪽 배터리가 올바로 설치되지 않았습니다. 배터리를 제거했다가 다시 설치하세요", + "ru": "Левая аккумуляторная батарея установлена неправильно. Извлеките и переустановите аккумуляторную батарею", + "tr": "Sol pil düzgün takılmamış. Pili çıkarın ve yeniden takın", + "zh": "左电池安装不到位,请重新安装电池" + }, + "fpv_tip_0x1100003B": { + "de": "Der rechte Akku ist nicht ordnungsgemäß eingesetzt. Akku entfernen und wieder einsetzen", + "en": "Right battery not properly installed. Remove and reinstall battery", + "es": "La batería derecha no está instalada correctamente. Retira la batería y vuelve a instalarla", + "fr": "La batterie droite n’est pas correctement installée. Retirer et réinstaller la batterie", + "ja": "右バッテリーが正しく取り付けられていません。バッテリーを取り付け直してください", + "ko": "오른쪽 배터리가 올바로 설치되지 않았습니다. 배터리를 제거했다가 다시 설치하세요", + "ru": "Правая аккумуляторная батарея установлена неправильно. Извлеките и переустановите аккумуляторную батарею", + "tr": "Sağ pil düzgün takılmamış. Pili çıkarın ve yeniden takın", + "zh": "右电池安装不到位,请重新安装电池" + }, + "fpv_tip_0x1100003C": { + "de": "Der Gimbal ist nicht ordnungsgemäß installiert. Den Gimbal lösen und wieder montieren", + "en": "Gimbal not properly installed. Detach and remount gimbal", + "es": "El estabilizador no se ha instalado correctamente. Retira el estabilizador y vuélvelo a montar", + "fr": "La nacelle n’est pas correctement installée. Détacher et remonter la nacelle", + "ja": "ジンバルが正しく取り付けられていません。ジンバルを取り付け直してください", + "ko": "짐벌이 올바로 설치되지 않았습니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Неправильно установлен гиростабилизатор. Отсоедините и переустановите гиростабилизатор", + "tr": "Gimbal düzgün takılmamış. Gimbalı çıkarın ve yeniden takın", + "zh": "云台安装不到位,请重新安装云台" + }, + "fpv_tip_0x1100003D": { + "de": "Die Mittelplatine des Fluggeräts ist überhitzt. Zum Startpunkt zurückkehren oder umgehend landen", + "en": "Aircraft center board overheated. Return to home or land promptly", + "es": "Placa central de la aeronave sobrecalentada. Regresa al punto de origen o aterriza cuando antes.", + "fr": "Carte principale de l’appareil en surchauffe. Retourner au point de départ ou atterrir rapidement", + "ja": "機体のセンターボードが高温。直ちに帰還するか、着陸してください", + "ko": "기체 중앙 보드가 과열 상태입니다. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Борт дрона перегрелся. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Uçak merkez panosu aşırı ısındı. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "飞行器中心板温度过高,请尽快返航或降落" + }, + "fpv_tip_0x1100003E": { + "de": "Radar nicht angeschlossen. Mit Vorsicht fliegen und zum Startpunkt zurückkehren oder umgehend landen", + "en": "Radar disconnected. Fly with caution and return to home or land promptly", + "es": "Radar desconectado. Vuela con cuidado y regresa al punto de origen o aterriza cuanto antes", + "fr": "Radar déconnecté. Pilotez avec précaution et revenez au point de départ ou atterrissez rapidement", + "ja": "レーダーの接続切断。慎重に飛行し、直ちに帰還するか着陸してください", + "ko": "레이더 연결이 끊어졌습니다. 비행 시 주의하고 즉시 RTH를 실행하거나 착륙하세요", + "ru": "Радар отключен. Соблюдайте осторожность при полете; как можно скорее вернитесь на базу или приземлитесь", + "tr": "Radar bağlantısı kesildi. Dikkatli uçun ve başlangıç noktasına dönün veya derhal iniş yapın.", + "zh": "雷达连接断开,请谨慎飞行并尽快返航或降落" + }, + "fpv_tip_0x1100003F": { + "de": "Verbindungsfehler bei den abwärts gerichteten Infrarotsensoren. Fluggerät neu starten", + "en": "Downward infrared sensing system connection error. Restart aircraft", + "es": "Error de conexión del sistema de detección por infrarrojos inferior Reinicia la aeronave", + "fr": "Erreur de connexion du système de détection infrarouge inférieur. Redémarrer l’appareil", + "ja": "下方赤外線検知システムの接続エラー。機体を再起動してください", + "ko": "하향 적외선 감지 시스템 연결 오류. 기체를 재시작하세요", + "ru": "Ошибка подключения системы нижнего ИК датчика. Перезапустите дрон", + "tr": "Aşağıya doğru kızılötesi algılama sistemi bağlantı hatası. Hava aracını yeniden başlatın", + "zh": "飞行器TOF模块连接异常,请尝试重启飞行器" + }, + "fpv_tip_0x11000040": { + "de": "Kommunikationsfehler des Landegestellmotors. Fluggerät neu starten", + "en": "Landing gear motor communication error. Restart aircraft", + "es": "Error de comunicación del motor del tren de aterrizaje. Reinicia la aeronave", + "fr": "Erreur de communication du moteur du train d’atterrissage. Redémarrer l’appareil", + "ja": "ランディングギアモーターの通信エラー。機体を再起動してください", + "ko": "랜딩 기어 모터 통신 오류. 기체를 재시작하세요", + "ru": "Ошибка связи двигателя шасси. Перезапустите дрон", + "tr": "İniş takımı motoru bağlantı hatası. Hava aracını yeniden başlatın", + "zh": "起落架舵机通信异常,请尝试重启飞行器" + }, + "fpv_tip_0x11000041": { + "de": "Landegestellmotor blockiert. Darauf achten, dass sich keine Hindernisse am Motor befinden, und das Fluggerät neu starten.", + "en": "Landing gear motor stalled. Make sure motor is clear of obstacles and restart aircraft", + "es": "Motor del tren de aterrizaje atascado. Asegúrate de que el motor esté libre de obstáculos y reinicia la aeronave.", + "fr": "Moteur du train d’atterrissage bloqué. Assurez-vous que le moteur est exempt d’obstacles et redémarrez l’appareil", + "ja": "ランディングギアモーターが停止しました。モーターに障害物がないことを確認し、機体を再起動してください", + "ko": "랜딩 기어 모터가 멈췄습니다. 모터에 장애물이 없는지 확인 후 기체를 재시작하세요", + "ru": "Двигатель шасси заглох. Убедитесь, что работе двигателя ничего не мешает, и перезапустите дрон", + "tr": "İniş takımı motoru durdu. Motorun önünde engel olmadığından emin olun ve uçağı yeniden başlatın", + "zh": "起落架舵机堵转,请检查是否有异物并重启飞行器" + }, + "fpv_tip_0x11000042": { + "de": "Große Stromdifferenz zwischen den Akkus. Für einen reibungslosen Flug sorgen und umgehend landen", + "en": "Large current difference between batteries. Maintain smooth flight and land promptly", + "es": "Gran diferencia de corriente entre las baterías. Mantén un vuelo fluido y aterriza cuanto antes", + "fr": "Forte différence d’intensité entre les batteries. Maintenez un vol fluide et atterrissez rapidement", + "ja": "バッテリー間の電流差が大きくなっています。スムーズな飛行を維持し、直ちに着陸してください", + "ko": "배터리 간 큰 전류 차이. 비행을 매끄럽게 유지하고 즉시 착륙합니다", + "ru": "Большая разница тока между аккумуляторами. Поддерживайте плавный полет и как можно скорее приземлитесь", + "tr": "Piller arasında büyük akım farkı var. Sorunsuz uçuşu sürdürün ve derhal iniş yapın", + "zh": "电池电流差异大,请保持平稳飞行并尽快降落" + }, + "fpv_tip_0x11000043": { + "de": "Motor überhitzt. Fluggerät nicht häufig überführen", + "en": "Motor overheated. Do not transform aircraft frequently", + "es": "Motor sobrecalentado. No transforme la aeronave con frecuencia", + "fr": "Moteur en surchauffe. Ne transformez pas fréquemment l'appareil", + "ja": "モーターが過熱。機体を頻繁に変形させないでください", + "ko": "모터 과열 상태. 기체를 자주 변속하지 마세요", + "ru": "Мотор перегрелся. Не трансформируйте дрон слишком часто", + "tr": "Motor aşırı ısındı. Hava araçlarını sık sık değiştirmeyin", + "zh": "舵机温度高,请避免频繁变形" + }, + "fpv_tip_0x11000044": { + "de": "Motor überhitzt. Überführung des Fluggeräts gestoppt. Warten, bis der Motor sich abgekühlt hat", + "en": "Motor overheated. Transforming aircraft stopped. Wait until motor cools down", + "es": "Motor sobrecalentado. Se ha detenido la transformación de la aeronave. Espere a que se enfríe el motor", + "fr": "Moteur en surchauffe. La transformation de l'appareil s'est arrêtée. Attendez que le moteur refroidisse", + "ja": "モーターが過熱。機体の変形が停止しました。モーターが冷えるまでお待ちください", + "ko": "모터 과열 상태. 기체 변속이 중지되었습니다. 모터가 식을 때까지 기다리세요", + "ru": "Мотор перегрелся. Трансформация дрона прервана. Подождите, пока мотор остынет", + "tr": "Motor aşırı ısındı. Değişen hava aracı durdu. Motor soğuyana kadar bekleyin", + "zh": "舵机温度过高,已经停止变形,请等待舵机温度降低" + }, + "fpv_tip_0x11000045": { + "de": "Temperatur zu niedrig. Landegestell klemmt", + "en": "Temperature too low. Landing gear stuck", + "es": "Temperatura demasiado baja Tren de aterrizaje atascado", + "fr": "Température trop basse. Train d'atterrissage bloqué", + "ja": "温度が低すぎます。ランディングギアが動かなくなっています", + "ko": "온도 너무 낮음. 랜딩 기어가 막혔습니다", + "ru": "Слишком низкая температура. Заедание посадочного механизма", + "tr": "Sıcaklık çok düşük. İniş takımı sıkıştı", + "zh": "温度过低起落架运动受阻" + }, + "fpv_tip_0x11000046": { + "de": "Die Gewindestange des Fluggeräts hat die maximale Lebensdauer erreicht. Um die Flugsicherheit zu gewährleisten, wende dich an den DJI-Support und sende das Fluggerät zur Wartung zurück an DJI", + "en": "Aircraft screw rod reaching maximum life span. To ensure flight safety, contact DJI Support and send aircraft back to DJI for maintenance", + "es": "El vástago del tornillo de la aeronave está llegando al fin de su vida útil. Para garantizar la seguridad de vuelo, ponte en contacto con la Asistencia técnica de DJI y envía la aeronave de vuelta a DJI para su mantenimiento", + "fr": "La tige de vis de l'appareil a atteint sa durée de vie maximale. Pour garantir la sécurité pendant le vol, contactez le Service client DJI et renvoyez l'appareil à DJI à des fins de maintenance", + "ja": "機体のスクリューロッドの耐用寿命に達しました。飛行安全性を確保するため、DJIサポートに連絡し、機体をDJIに返送してメンテナンスを受けてください", + "ko": "기체 나사 로드가 최대 수명에 도달했습니다. 비행 안전을 보장하려면 DJI 고객지원에 연락하여 유지 보수를 위해 기체를 DJI로 다시 보내세요.", + "ru": "Достигнут максимальный срок службы резьбового стержня дрона. Чтобы обеспечить безопасность полетов, обратитесь в службу поддержки DJI и отправьте дрон обратно в DJI для технического обслуживания", + "tr": "Hava aracı vida çubuğu, maksimum kullanım ömrüne ulaşıyor. Uçuş güvenliğini sağlamak için DJI Destek birimiyle iletişime geçin ve bakım için hava aracını DJI'a gönderin", + "zh": "飞行器丝杆即将达到设计使用寿命,为确保飞行安全,请您及时联系 DJI 技术支持并寄回处理" + }, + "fpv_tip_0x11000047": { + "de": "Die Gewindestange des Fluggeräts hat die maximale Lebensdauer überschritten. Um die Flugsicherheit zu gewährleisten, wende dich schnellstmöglich an den DJI-Support und sende das Fluggerät zur Wartung zurück an DJI. Sollte bei weiterer Nutzung des Fluggeräts ein Unfall passieren, bist du für die Wartungskosten selbst verantwortlich", + "en": "Aircraft screw rod exceeded maximum life span. To ensure flight safety, contact DJI Support immediately and send aircraft back to DJI for maintenance. You are responsible for the maintenance cost for the flight accident caused by continued use of the aircraft", + "es": "El vástago del tornillo de la aeronave ha superado su vida útil. Para garantizar la seguridad de vuelo, ponte en contacto inmediatamente con la Asistencia técnica de DJI y envía la aeronave de vuelta a DJI para su mantenimiento. Los gastos de mantenimiento derivados de un posible accidente de vuelo causado por el uso continuado de la aeronave correrán a cuenta del usuario", + "fr": "La tige de vis de l'appareil a dépassé sa durée de vie maximale. Pour garantir la sécurité pendant le vol, contactez le Service client DJI immédiatement et renvoyez l'appareil à DJI à des fins de maintenance. Vous devrez assumer les frais de maintenance liés à tout accident de vol qui serait causé par la poursuite de l'utilisation de l'appareil", + "ja": "機体のスクリューロッドが耐用寿命を超えました。飛行安全性を確保するため、DJIサポートに直ちに連絡し、機体をDJIに返送してメンテナンスを受けてください。お客様は、機体の連続使用に起因する飛行事故のメンテナンス費用を負担するものとします", + "ko": "기체 나사 로드가 최대 수명을 초과했습니다. 비행 안전을 보장하려면 DJI 고객지원에 즉시 연락하여 유지 보수를 위해 기체를 DJI로 다시 보내세요. 기체를 계속 사용하여 발생한 비행 사고에 대한 유지 보수 비용은 사용자가 부담합니다.", + "ru": "Превышен максимальный срок службы резьбового стержня дрона. Чтобы обеспечить безопасность полетов, незамедлительно обратитесь в службу поддержки DJI и отправьте дрон обратно в DJI для технического обслуживания. Вы оплачиваете техническое обслуживание в случае авиационного происшествия, вызванного длительной эксплуатацией дрона", + "tr": "Hava aracı vida çubuğu, maksimum kullanım ömrünü aştı. Uçuş güvenliğini sağlamak için hemen DJI Destek birimiyle iletişime geçin ve bakım için hava aracını DJI'a gönderin. Hava aracının sürekli kullanımından kaynaklanan uçuş kazasının bakım maliyetinden siz sorumlusunuz", + "zh": "飞行器丝杆已超出设计使用寿命,为确保飞行安全,请您立刻联系 DJI 技术支持并寄回处理,继续使用导致的飞行事故,需要您承担维修费用" + }, + "fpv_tip_0x11000048": { + "de": "Fehler: Landegestell. Hindernisvermeidung beeinträchtigt. Mit Vorsicht fliegen. Beim Landen des Fluggeräts auf das Objektiv achten. DJI Support kontaktieren.", + "en": "Landing gear error. Obstacle avoidance performance degraded. Fly with caution. Pay attention to lens when aircraft is landing. Contact DJI Support", + "es": "Error del tren de aterrizaje. Rendimiento del sistema anticolisión degradado. Vuele con cuidado. Preste atención al objetivo cuando la aeronave esté aterrizando. Póngase en contacto con la Asistencia técnica de DJI", + "fr": "Erreur du train d’atterrissage. Performances d'évitement d'obstacle dégradées. Piloter avec précaution. Prêter attention à l'objectif lorsque l'appareil atterrit. Contacter le service client DJI", + "ja": "ランディングギアのエラー。障害物回避性能が低下しています。慎重に飛行してください。着陸時にはレンズに注意してください。DJIサポートまでお問い合わせください", + "ko": "랜딩 기어 오류. 장애물 회피 성능이 저하됨. 비행 시 주의 필요. 기체가 착륙할 때 렌즈에 주의하세요. DJI 고객지원으로 문의하세요.", + "ru": "Ошибка статуса шасси. Характеристики уклонения от препятствий ухудшились. Соблюдайте осторожность при полете. Обратите внимание на объектив при посадке дрона. Свяжитесь со службой поддержки DJI", + "tr": "İniş takımı hatası. Engellerden kaçınma performansı düştü. Dikkatlice uçurun. Hava aracı iniş yaparken lense dikkat edin. DJI Destek birimiyle iletişime geçin", + "zh": "起落架异常,避障性能降低,请谨慎飞行,注意降落镜头保护,请联系售后" + }, + "fpv_tip_0x11020030": { + "ar": "", + "de": "", + "en": "%battery_index battery cover temperature error. Switched to single-battery flight. Return to home or land promptly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%battery_index电池上盖温度异常,转为单电池飞行,请尽快返航或降落", + "zh-Hant": "" + }, + "fpv_tip_0x11020031": { + "ar": "", + "de": "", + "en": "%battery_index battery connector temperature error. Switched to single-battery flight. Return to home or land promptly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%battery_index电池连接器温度异常,转为单电池飞行,请尽快返航或降落", + "zh-Hant": "" + }, + "fpv_tip_0x11020032": { + "ar": "", + "de": "", + "en": "%battery_index battery temperature error. Switched to single-battery flight. Return to home or land promptly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%battery_index电池温度异常,转为单电池飞行,请尽快返航或降落", + "zh-Hant": "" + }, + "fpv_tip_0x11020033": { + "ar": "", + "de": "", + "en": "%battery_index battery error. Switched to single-battery flight. Return to home or land promptly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%battery_index电池异常,转为单电池飞行,请尽快返航或降落", + "zh-Hant": "" + }, + "fpv_tip_0x110B0001": { + "de": "%battery_index Akku: Überstrom beim Entladen. Für einen reibungslosen Flug sorgen und überprüfen, ob das Fluggerät überladen ist", + "en": "%battery_index Battery overcurrent when discharging. Maintain smooth flight and check if aircraft is overloaded", + "es": "Sobrecorriente de la batería %battery_index durante la descarga. Mantenga un vuelo fluido y compruebe si la aeronave está sobrecargada", + "fr": "Surintensité de la batterie %battery_index lors de la décharge. Maintenir un vol fluide et vérifier si l'appareil est surchargé", + "ja": "放電時の %battery_index バッテリーの過電流。 スムーズな飛行を維持し、機体が過負荷になっていないかどうかを確認します", + "ko": "방전 중 %battery_index 배터리 과전류 발생. 원활한 비행을 유지한 상태로 기체 과부하 여부를 확인하세요.", + "ru": "%battery_index АКБ: перегрузка по току при разрядке. Поддерживайте плавный полет и проверяйте, не перегружен ли дрон", + "tr": "Deşarj olurken %battery_index Pil aşırı akımı. Sorunsuz uçuşu sürdürün ve aracın aşırı yüklenip yüklenmediğini kontrol edin", + "zh": "%battery_index电池放电过流,请保持平稳飞行并检查是否有负重" + }, + "fpv_tip_0x110B0002": { + "de": "%battery_index Akku: Überhitzt. Zum Startpunkt zurückkehren und warten, bis der Akku abgekühlt ist", + "en": "%battery_index Battery overheated. Return to home promptly and wait until battery cools down", + "es": "Batería %battery_index sobrecalentada. Regrese al punto de origen de inmediato y espere hasta que la batería se enfríe.", + "fr": "Surchauffe batterie %battery_index. Retourner rapidement au point de départ et attendre que la batterie refroidisse", + "ja": "%battery_index バッテリー高温。 直ちに帰還し、バッテリーが冷えるまで待ちます", + "ko": "%battery_index 배터리 과열됨. 즉시 리턴 투 홈을 실행하여 배터리가 식을 때까지 기다려 주세요.", + "ru": "Перегрев %battery_index АКБ. Немедленно вернитесь в домашнюю точку и подождите, пока батарея остынет", + "tr": "%battery_index Pil aşırı ısındı. Hemen başlangıç noktasına dönün ve pil soğuyana kadar bekleyin", + "zh": "%battery_index电池温度过高,请尽快返航,待电池冷却到常温再使用" + }, + "fpv_tip_0x110B0003": { + "de": "%battery_index Akku: Temperatur zu niedrig. Akku auf mindestens 5 °C erwärmen", + "en": "%battery_index Battery temperature too low. Warm up battery to 5°C or higher", + "es": "Temperatura de la batería %battery_index demasiado baja. La batería necesita calentarse hasta 5 °C o más", + "fr": "Température de la batterie %battery_index trop basse. Réchauffer la batterie à 5 °C ou plus", + "ja": "%battery_index バッテリー温度が低すぎます。 バッテリーを5℃以上に温めてください", + "ko": "%battery_index 배터리 온도가 너무 낮음. 배터리를 5°C 이상으로 예열하세요.", + "ru": "%battery_index АКБ: слишком низкая температура. Прогрейте АКБ до 5 °C или выше", + "tr": "%battery_index Pil sıcaklığı çok düşük. Pili 5°C veya daha yüksek sıcaklığa kadar ısıtın", + "zh": "%battery_index电池温度过低,请预热电池至5摄氏度以上" + }, + "fpv_tip_0x110B0004": { + "de": "%battery_index Akku: Kurzschluss beim Entladen. Akku austauschen", + "en": "%battery_index Battery short-circuited during discharge. Replace battery", + "es": "Cortocircuito de la batería %battery_index durante la descarga. Reemplace la batería.", + "fr": "Court-circuit sur la batterie %battery_index pendant la décharge. Remplacer la batterie", + "ja": "放電中の %battery_index バッテリー短絡。 バッテリーを交換してください", + "ko": "%battery_index 배터리 방전 중 합선 발생. 배터리를 교체하세요.", + "ru": "%battery_index АКБ: короткое замыкание при разрядке батареи. Замените АКБ", + "tr": "%battery_index Pil deşarj sırasında kısa devre yaptı. Pili değiştirin", + "zh": "%battery_index电池放电出现短路,请更换电池" + }, + "fpv_tip_0x110B0005": { + "de": "Spannung der Akkuzelle gering. Bitte Akku ersetzen", + "en": "Battery %index cell voltage low. Replace battery", + "es": "Voltaje bajo de la célula de batería %index. Reemplaza la batería", + "fr": "Tension de la cellule de batterie faible. Remplacez la batterie", + "ja": "低バッテリー%indexセル電圧。バッテリーを交換してください", + "ko": "배터리 셀 전압 낮음. 배터리 교체 필요", + "ru": "Низкое напряжение ячейки. Замените батарею", + "tr": "Pil %index hücre voltajı düşük. Pili değiştirin", + "zh": "电芯%index欠压,请更换电池" + }, + "fpv_tip_0x110B0006": { + "de": "%battery_index Akku: Zelle beschädigt. Akku nicht mehr verwenden, DJI Support kontaktieren", + "en": "%battery_index Battery cell damaged. Stop using battery and contact DJI Support", + "es": "Célula de batería %battery_index dañada. Deje de usar la batería y contacte con DJI Support", + "fr": "Cellule de batterie %battery_index endommagée. Ne plus utiliser la batterie et contacter le service client DJI", + "ja": "%battery_index バッテリーセル損傷。 バッテリーの使用を止めて DJI サポートにお問い合わせください", + "ko": "%battery_index 배터리 셀 손상됨. 배터리 사용을 중지하고 DJI 고객지원으로 문의해주세요.", + "ru": "%battery_index АКБ: ячейка повреждена. Прекратите использование АКБ и обратитесь в службу поддержки DJI", + "tr": "%battery_index Pil hücresi hasarlı. Pili kullanmayı bırakın ve DJI Destek ile iletişime geçin", + "zh": "%battery_index电池电芯损坏,请停止使用该电池,并联系售后服务" + }, + "fpv_tip_0x110B0007": { + "de": "%battery_index Akku: Selbsttest fehlgeschlagen. Akku nicht mehr verwenden, DJI Support kontaktieren", + "en": "%battery_index Battery auto-check failed. Stop using battery and contact DJI Support", + "es": "Error de comprobación automática de la batería %battery_index. Deje de usar la batería y contacte con DJI Support", + "fr": "La vérification automatique de la batterie %battery_index a échoué. Ne plus utiliser la batterie et contacter le service client DJI", + "ja": "%battery_index バッテリーの自動確認に失敗しました。 バッテリーの使用を止めて DJI サポートにお問い合わせください", + "ko": "%battery_index 배터리 자체 점검 실패. 배터리 사용을 중지하고 DJI 고객지원으로 문의해주세요.", + "ru": "%battery_index АКБ: не удалось выполнить автоматическую проверку. Прекратите использование АКБ и обратитесь в службу поддержки DJI", + "tr": "%battery_index Pil otomatik denetimi başarısız oldu. Pili kullanmayı bırakın ve DJI Destek ile iletişime geçin", + "zh": "%battery_index电池自检失败,请更换电池,并联系售后服务" + }, + "fpv_tip_0x110B0008": { + "de": "%battery_index Akku: Selbsttest fehlgeschlagen. Akku nicht mehr verwenden, DJI Support kontaktieren", + "en": "%battery_index Battery auto-check failed. Stop using battery and contact DJI Support", + "es": "Error de comprobación automática de la batería %battery_index. Deje de usar la batería y contacte con DJI Support", + "fr": "La vérification automatique de la batterie %battery_index a échoué. Ne plus utiliser la batterie et contacter le service client DJI", + "ja": "%battery_index バッテリーの自動確認に失敗しました。 バッテリーの使用を止めて DJI サポートにお問い合わせください", + "ko": "%battery_index 배터리 자체 점검 실패. 배터리 사용을 중지하고 DJI 고객지원으로 문의해주세요.", + "ru": "%battery_index АКБ: не удалось выполнить автоматическую проверку. Прекратите использование АКБ и обратитесь в службу поддержки DJI", + "tr": "%battery_index Pil otomatik denetimi başarısız oldu. Pili kullanmayı bırakın ve DJI Destek ile iletişime geçin", + "zh": "%battery_index电池自检失败,请更换电池,并联系售后服务" + }, + "fpv_tip_0x110B0009": { + "de": "%battery_index Akku: Selbsttest fehlgeschlagen. Akku nicht mehr verwenden, DJI Support kontaktieren", + "en": "%battery_index Battery auto-check failed. Stop using battery and contact DJI Support", + "es": "Error de comprobación automática de la batería %battery_index. Deje de usar la batería y contacte con DJI Support", + "fr": "La vérification automatique de la batterie %battery_index a échoué. Ne plus utiliser la batterie et contacter le service client DJI", + "ja": "%battery_index バッテリーの自動確認に失敗しました。 バッテリーの使用を止めて DJI サポートにお問い合わせください", + "ko": "%battery_index 배터리 자체 점검 실패. 배터리 사용을 중지하고 DJI 고객지원으로 문의해주세요.", + "ru": "%battery_index АКБ: не удалось выполнить автоматическую проверку. Прекратите использование АКБ и обратитесь в службу поддержки DJI", + "tr": "%battery_index Pil otomatik denetimi başarısız oldu. Pili kullanmayı bırakın ve DJI Destek ile iletişime geçin", + "zh": "%battery_index电池自检失败,请更换电池,并联系售后服务" + }, + "fpv_tip_0x110B000A": { + "de": "%battery_index Akku: Selbsttest fehlgeschlagen. Akku nicht mehr verwenden, DJI Support kontaktieren", + "en": "%battery_index Battery auto-check failed. Stop using battery and contact DJI Support", + "es": "Error de comprobación automática de la batería %battery_index. Deje de usar la batería y contacte con DJI Support", + "fr": "La vérification automatique de la batterie %battery_index a échoué. Ne plus utiliser la batterie et contacter le service client DJI", + "ja": "%battery_index バッテリーの自動確認に失敗しました。 バッテリーの使用を止めて DJI サポートにお問い合わせください", + "ko": "%battery_index 배터리 자체 점검 실패. 배터리 사용을 중지하고 DJI 고객지원으로 문의해주세요.", + "ru": "%battery_index АКБ: не удалось выполнить автоматическую проверку. Прекратите использование АКБ и обратитесь в службу поддержки DJI", + "tr": "%battery_index Pil otomatik denetimi başarısız oldu. Pili kullanmayı bırakın ve DJI Destek ile iletişime geçin", + "zh": "%battery_index电池自检失败,请更换电池,并联系售后服务" + }, + "fpv_tip_0x110B000B": { + "de": "%battery_index Akku: Beschädigt. Akku nicht mehr verwenden, DJI Support kontaktieren", + "en": "%battery_index Battery damaged. Stop using battery and contact DJI Support", + "es": "Batería %battery_index dañada. Deje de usar la batería y contacte con DJI Support", + "fr": "Batterie %battery_index endommagée. Ne plus utiliser la batterie et contacter le service client DJI", + "ja": "%battery_index バッテリー損傷。 バッテリーの使用を止めて DJI サポートにお問い合わせください", + "ko": "%battery_index 배터리 손상됨. 배터리 사용을 중지하고 DJI 고객지원으로 문의해주세요.", + "ru": "%battery_index АКБ: повреждение. Прекратите использование АКБ и обратитесь в службу поддержки DJI", + "tr": "%battery_index Pil hasarlı. Pili kullanmayı bırakın ve DJI Destek ile iletişime geçin", + "zh": "%battery_index电池已损坏,请停止使用该电池,并联系售后服务" + }, + "fpv_tip_0x110B000C": { + "de": "%battery_index Akku: Wartung erforderlich", + "en": "%battery_index Battery maintenance required", + "es": "La batería %battery_index requiere mantenimiento.", + "fr": "Maintenance de la batterie %battery_index requise", + "ja": "%battery_index バッテリーのメンテナンスが必要です", + "ko": "%battery_index 배터리 점검 필요", + "ru": "%battery_index АКБ: требуется обслуживание", + "tr": "%battery_index Pil bakımı gerekiyor", + "zh": "%battery_index电池需要保养" + }, + "fpv_tip_0x110B000D": { + "de": "%battery_index Akku: Beschädigt. Akku nicht mehr verwenden, DJI Support kontaktieren", + "en": "%battery_index Battery damaged. Stop using battery and contact DJI Support", + "es": "Batería %battery_index dañada. Deje de usar la batería y contacte con DJI Support", + "fr": "Batterie %battery_index endommagée. Ne plus utiliser la batterie et contacter le service client DJI", + "ja": "%battery_index バッテリー損傷。 バッテリーの使用を止めて DJI サポートにお問い合わせください", + "ko": "%battery_index 배터리 손상됨. 배터리 사용을 중지하고 DJI 고객지원으로 문의해주세요.", + "ru": "%battery_index АКБ: повреждение. Прекратите использование АКБ и обратитесь в службу поддержки DJI", + "tr": "%battery_index Pil hasarlı. Pili kullanmayı bırakın ve DJI Destek ile iletişime geçin", + "zh": "%battery_index电池已损坏,请停止使用该电池,并联系售后服务" + }, + "fpv_tip_0x110B000E": { + "de": "Selbstentladung während Einlagerung bei Akku %index", + "en": "Battery %index self-discharged during storage", + "es": "La batería %index se ha autodescargado durante el almacenamiento", + "fr": "Décharge automatique de la batterie %index pendant le stockage", + "ja": "保管中にバッテリー%index自己放電発生", + "ko": "배터리 %index 보관 중 자동 방전", + "ru": "Саморазряд батареи %index при хранении", + "tr": "Pil %index saklama sırasında kendiliğinden boşaldı", + "zh": "%index电池发生存储自放电" + }, + "fpv_tip_0x110B000F": { + "de": "%battery_index Akku: Kapazität signifikant verringert. Weitere Verwendung des Akkus kann zu Sicherheitsrisiken führen", + "en": "%battery_index Battery capacity significantly reduced. Continue using battery may cause safety risks", + "es": "Capacidad de la batería %battery_index significativamente reducida. Si continúa usando la batería se pueden producir riesgos de seguridad.", + "fr": "Capacité de la batterie %battery_index considérablement réduite. La poursuite de l'utilisation de la batterie peut entraîner des risques pour la sécurité", + "ja": "%battery_index バッテリー容量が大幅に減少しました。 バッテリーを使い続けると、安全上のリスクが発生する可能性があります", + "ko": "%battery_index 배터리 용량 현저하게 감소됨. 배터리를 계속 사용하면 안전상의 위험이 발생할 수 있습니다.", + "ru": "%battery_index АКБ: емкость батареи значительно уменьшена. Дальнейшее использования батареи может привести к угрозе безопасности", + "tr": "%battery_index Pil kapasitesi önemli ölçüde azaldı. Pili kullanmaya devam etmek güvenlik risklerine neden olabilir", + "zh": "%battery_index电池性能严重下降,继续使用有安全风险" + }, + "fpv_tip_0x110B0010": { + "de": "%battery_index Akku: Sicherheitsanforderungen nicht erfüllt. Akku ordnungsgemäß entsorgen", + "en": "Safety requirements not met. Dispose of %battery_index Battery properly", + "es": "No se cumplen los requisitos de seguridad. Elimine la batería %battery_index correctamente", + "fr": "Exigences de sécurité non respectées. Jeter correctement la batterie %battery_index", + "ja": "安全性要件が満たされていません。 %battery_index バッテリーを適切に廃棄してください", + "ko": "안전 요구사항 충족하지 않음. 올바른 방법으로 %battery_index 배터리를 폐기하세요.", + "ru": "Требования безопасности не соблюдены. Утилизируйте %battery_index АКБ надлежащим образом", + "tr": "Güvenlik gereksinimleri karşılanmadı. %battery_index Pili doğru şekilde atın", + "zh": "超出安全条件使用,请报废%battery_index电池" + }, + "fpv_tip_0x110B0011": { + "de": "%battery_index Akku: Kommunikationsfehler. Akku neu einsetzen. Akku ersetzen, wenn das Problem weiterhin besteht", + "en": "%battery_index Battery data communication error. Reinstall battery. Replace battery if issue persists", + "es": "Error de comunicación de la batería %battery_index. Vuelva a instalar la batería. Si el problema continúa, reemplace la batería.", + "fr": "Erreur de communication des données de la batterie %battery_index. Réinstaller la batterie. Remplacer la batterie si le problème persiste", + "ja": "%battery_index バッテリーデータ通信エラー。 バッテリーを再度取り付けてください。 問題が解決しない場合は、バッテリーを交換してください", + "ko": "%battery_index 배터리 데이터 통신 오류. 배터리를 다시 장착하세요. 문제가 지속되면 배터리를 교체하세요.", + "ru": "%battery_index АКБ: ошибка передачи данных. Заново установите АКБ. Замените батарею, если проблема не устранена", + "tr": "%battery_index Pil verileri iletişim hatası. Pili yeniden takın. Sorun devam ederse pili değiştirin", + "zh": "%battery_index电池数据通信异常,请重新安装电池,如果未解决请更换电池" + }, + "fpv_tip_0x110B0012": { + "de": "%battery_index Akku: Wartung erforderlich", + "en": "%battery_index Battery maintenance required", + "es": "La batería %battery_index requiere mantenimiento.", + "fr": "Maintenance de la batterie %battery_index requise", + "ja": "%battery_index バッテリーのメンテナンスが必要です", + "ko": "%battery_index 배터리 점검 필요", + "ru": "%battery_index АКБ: требуется обслуживание", + "tr": "%battery_index Pil bakımı gerekiyor", + "zh": "%battery_index电池需要保养" + }, + "fpv_tip_0x110B0013": { + "de": "%battery_index Akkuschacht: Kein Akku erkannt. Akku einsetzen oder ersetzen", + "en": "Battery not detected in %battery_index Battery slot. Insert or replace battery", + "es": "No se ha detectado la batería en la ranura de la batería %battery_index. Instale o reemplace la batería.", + "fr": "Batterie non détectée dans le logement de batterie %battery_index. Insérer ou remplacer la batterie", + "ja": "%battery_index バッテリースロットでバッテリーが検出されませんでした。 バッテリーを挿入または交換します", + "ko": "%battery_index 배터리 슬롯에서 배터리가 감지되지 않음. 배터리를 삽입하거나 교체하세요.", + "ru": "Батарея не обнаружена в слоте %battery_index АКБ. Вставьте или замените АКБ", + "tr": "Pil %battery_index Pil yuvasında algılanmadı. Pili takın veya değiştirin", + "zh": "%battery_index电池槽没有电池,请插入电池或者更换电池" + }, + "fpv_tip_0x110B0013_in_the_sky": { + "de": "%battery_index Akkuschacht: Kein Akku erkannt. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Battery not detected in %battery_index Battery slot. Return to home or land promptly", + "es": "No se ha detectado la batería en la ranura de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Batterie non détectée dans le logement de batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリースロットでバッテリーが検出されませんでした。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 슬롯에서 배터리가 감지되지 않음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "Батарея не обнаружена в слоте %battery_index АКБ. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil yuvasında algılanmadı. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池槽检测不到电池,请尽快返航或降落" + }, + "fpv_tip_0x110B0014": { + "de": "%battery_index Akku: Selbsterwärmung", + "en": "%battery_index Battery self-heating", + "es": "Autocalentamiento de la batería %battery_index.", + "fr": "Auto-chauffe de la batterie %battery_index", + "it": "", + "ja": "%battery_index バッテリーの自己発熱", + "ko": "%battery_index 배터리 자체 발열", + "pt": "", + "ru": "%battery_index АКБ: самонагрев", + "tr": "%battery_index Pil kendi kendine ısınıyor", + "zh": "%battery_index电池在自加热" + }, + "fpv_tip_0x110B0015": { + "de": "%battery_index Akku: Wartung zur Sicherstellung der Flugsicherheit notwendig", + "en": "%battery_index Battery maintenance required to ensure flight safety", + "es": "La batería %battery_index requiere mantenimiento para garantizar la seguridad de vuelo.", + "fr": "Maintenance batterie %battery_index requise pour la sécurité en vol", + "ja": "飛行安全性を確保するために %battery_index バッテリーのメンテナンスが必要です", + "ko": "비행 안전을 위해 %battery_index 배터리 점검 필요", + "ru": "%battery_index АКБ: для безопасности полета требуется техобслуживание", + "tr": "Uçuş güvenliğini sağlamak için %battery_index Pil bakımı gerekli", + "zh": "%battery_index电池需要保养才能正常飞行" + }, + "fpv_tip_0x110B0016": { + "de": "%battery_index Akku: Wartung zur Sicherstellung der Flugsicherheit notwendig", + "en": "%battery_index Battery maintenance required to ensure flight safety", + "es": "La batería %battery_index requiere mantenimiento para garantizar la seguridad de vuelo.", + "fr": "Maintenance batterie %battery_index requise pour la sécurité en vol", + "ja": "飛行安全性を確保するために %battery_index バッテリーのメンテナンスが必要です", + "ko": "비행 안전을 위해 %battery_index 배터리 점검 필요", + "ru": "%battery_index АКБ: для безопасности полета требуется техобслуживание", + "tr": "Uçuş güvenliğini sağlamak için %battery_index Pil bakımı gerekli", + "zh": "%battery_index电池需要保养才能正常飞行" + }, + "fpv_tip_0x110B0017": { + "de": "%battery_index Akku: Wartung zur Sicherstellung der Flugsicherheit notwendig", + "en": "%battery_index Battery maintenance required to ensure flight safety", + "es": "La batería %battery_index requiere mantenimiento para garantizar la seguridad de vuelo.", + "fr": "Maintenance batterie %battery_index requise pour la sécurité en vol", + "ja": "飛行安全性を確保するために %battery_index バッテリーのメンテナンスが必要です", + "ko": "비행 안전을 위해 %battery_index 배터리 점검 필요", + "ru": "%battery_index АКБ: для безопасности полета требуется техобслуживание", + "tr": "Uçuş güvenliğini sağlamak için %battery_index Pil bakımı gerekli", + "zh": "%battery_index电池需要保养才能正常飞行" + }, + "fpv_tip_0x110B0018": { + "de": "%battery_index Akku: Wartung zur Sicherstellung der Flugsicherheit notwendig", + "en": "%battery_index Battery maintenance required to ensure flight safety", + "es": "La batería %battery_index requiere mantenimiento para garantizar la seguridad de vuelo.", + "fr": "Maintenance batterie %battery_index requise pour la sécurité en vol", + "ja": "飛行安全性を確保するために %battery_index バッテリーのメンテナンスが必要です", + "ko": "비행 안전을 위해 %battery_index 배터리 점검 필요", + "ru": "%battery_index АКБ: для безопасности полета требуется техобслуживание", + "tr": "Uçuş güvenliğini sağlamak için %battery_index Pil bakımı gerekli", + "zh": "%battery_index电池需要保养才能正常飞行" + }, + "fpv_tip_0x110B0019": { + "de": "%battery_index Akku: Wartung zur Sicherstellung der Flugsicherheit notwendig", + "en": "%battery_index Battery maintenance required to ensure flight safety", + "es": "La batería %battery_index requiere mantenimiento para garantizar la seguridad de vuelo.", + "fr": "Maintenance batterie %battery_index requise pour la sécurité en vol", + "ja": "飛行安全性を確保するために %battery_index バッテリーのメンテナンスが必要です", + "ko": "비행 안전을 위해 %battery_index 배터리 점검 필요", + "ru": "%battery_index АКБ: для безопасности полета требуется техобслуживание", + "tr": "Uçuş güvenliğini sağlamak için %battery_index Pil bakımı gerekli", + "zh": "%battery_index电池需要保养才能正常飞行" + }, + "fpv_tip_0x110B001A": { + "de": "%battery_index Akku: Wartung zur Sicherstellung der Flugsicherheit notwendig", + "en": "%battery_index Battery maintenance required to ensure flight safety", + "es": "La batería %battery_index requiere mantenimiento para garantizar la seguridad de vuelo.", + "fr": "Maintenance batterie %battery_index requise pour la sécurité en vol", + "ja": "飛行安全性を確保するために %battery_index バッテリーのメンテナンスが必要です", + "ko": "비행 안전을 위해 %battery_index 배터리 점검 필요", + "ru": "%battery_index АКБ: для безопасности полета требуется техобслуживание", + "tr": "Uçuş güvenliğini sağlamak için %battery_index Pil bakımı gerekli", + "zh": "%battery_index电池需要保养才能正常飞行" + }, + "fpv_tip_0x110B001B": { + "de": "%battery_index Akku: Wartung zur Sicherstellung der Flugsicherheit notwendig", + "en": "%battery_index Battery maintenance required to ensure flight safety", + "es": "La batería %battery_index requiere mantenimiento para garantizar la seguridad de vuelo.", + "fr": "Maintenance batterie %battery_index requise pour la sécurité en vol", + "ja": "飛行安全性を確保するために %battery_index バッテリーのメンテナンスが必要です", + "ko": "비행 안전을 위해 %battery_index 배터리 점검 필요", + "ru": "%battery_index АКБ: для безопасности полета требуется техобслуживание", + "tr": "Uçuş güvenliğini sağlamak için %battery_index Pil bakımı gerekli", + "zh": "%battery_index电池需要保养才能正常飞行" + }, + "fpv_tip_0x110B001C": { + "de": "Akkus stimmen nicht überein. Passende Akkus einsetzen", + "en": "Batteries do not match. Replace with matching batteries", + "es": "Las baterías no coinciden. Reemplázalas por baterías iguales", + "fr": "Les batteries ne correspondent pas. Remplacez-les par des batteries qui se correspondent", + "ja": "バッテリーが一致しません。一致するバッテリーと交換してください", + "ko": "배터리가 일치하지 않습니다. 일치하는 배터리로 교체하세요", + "ru": "Аккумуляторы не подходят. Замените их на соответствующие", + "tr": "Piller eşleşmiyor. Eşleşen pillerle değiştirin", + "zh": "电池不匹配,建议更换匹配电池" + }, + "fpv_tip_0x110B001D": { + "de": "%battery_index Akku: Entladefehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery discharge error. Return to home or land promptly", + "es": "Error de descarga de batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur de décharge de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー放電エラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 방전 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: ошибка разрядки. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil deşarj hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "电池槽%battery_index电池放电异常,请尽快返航或降落" + }, + "fpv_tip_0x110B001E": { + "de": "%battery_index Akku: Verbindungsfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery connection error. Return to home or land promptly", + "es": "Error de conexión de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur de connexion de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "it": "", + "ja": "%battery_index バッテリー接続エラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 연결 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "pt": "", + "ru": "%battery_index АКБ: ошибка подключения. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil bağlantı hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "电池槽%battery_index电池接触不良,请尽快返航或降落" + }, + "fpv_tip_0x110B007": { + "de": "", + "en": "Battery %d% auto check failed. Replace battery and contact DJI Support", + "es": "", + "fr": "Vérification auto de batterie %d% impossible. Remplacez la batterie et contactez l'assistance technique DJI", + "ja": "", + "ko": "", + "ru": "", + "tr": "", + "zh": "电池%d%自检失败,请更换电池,并联系售后服务" + }, + "fpv_tip_0x110B0403": { + "ar": "", + "de": "", + "en": "Incompatible battery firmware versions. Update firmware", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "双电池版本不一致,请更新电池固件版本", + "zh-Hant": "" + }, + "fpv_tip_0x110b001e": { + "de": "%battery_index Akku: Verbindungsfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery connection error. Return to home or land promptly", + "es": "Error de conexión de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur de connexion de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "it": "", + "ja": "%battery_index バッテリー接続エラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 연결 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "pt": "", + "ru": "%battery_index АКБ: ошибка подключения. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil bağlantı hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "电池槽%battery_index电池接触不良,请尽快返航或降落" + }, + "fpv_tip_0x12000000": { + "de": "Battery Station nicht aktiviert", + "en": "Battery Station not activated", + "es": "Estación de Baterías no activada", + "fr": "Station de batteries non activée", + "ja": "バッテリーステーションが有効化されていません", + "ko": "배터리 스테이션이 활성화되지 않음", + "ru": "Зарядная станция не активирована", + "tr": "Pil İstasyonu etkin değil", + "zh": "电池箱未激活" + }, + "fpv_tip_0x12000001": { + "de": "Fehler: Battery Station-Selbsttest", + "en": "Battery Station auto check error", + "es": "Error de comprobación automática de la Estación de Baterías", + "fr": "Erreur de vérification automatique de la station de batteries", + "ja": "バッテリーステーション自動確認エラー", + "ko": "배터리 스테이션 자동 점검 오류", + "ru": "Ошибка автоматической проверки зарядной станции", + "tr": "Pil İstasyonu otomatik kontrol hatası", + "zh": "电池箱自检异常" + }, + "fpv_tip_0x12000002": { + "de": "Kommunikationsfehler: Battery Station-Erweiterungskarte", + "en": "Battery Station expansion card communication error", + "es": "Error de comunicación de la tarjeta de expansión de la Estación de Baterías", + "fr": "Erreur de communication avec la carte d'extension de la station de batteries", + "ja": "バッテリーステーション拡張カード通信エラー", + "ko": "배터리 스테이션 확장 카드 통신 오류", + "ru": "Ошибка связи карты расширения зарядной станции", + "tr": "Pil İstasyonu genişletme kartı iletişim hatası", + "zh": "电池箱拓展板通信异常" + }, + "fpv_tip_0x12010000": { + "de": "Stromversorgungsmodul nicht erkannt", + "en": "Power Supply Module Not Recognized", + "es": "Módulo de fuente de alimentación no reconocido", + "fr": "Module d'alimentation non reconnu", + "ja": "電源モジュールが認識されていません", + "ko": "전력 공급 모듈이 인식되지 않음", + "ru": "Модуль питания не распознан", + "tr": "Güç Kaynağı Modülü Tanınmıyor", + "zh": "电源模块无法识别" + }, + "fpv_tip_0x12010001": { + "de": "Akkumodul-Eingangsspannung zu hoch", + "en": "Battery module input voltage too high", + "es": "Voltaje de entrada del módulo de batería demasiado alto", + "fr": "Tension d'entrée du module de batterie excessive", + "ja": "バッテリーモジュール入力高電圧", + "ko": "배터리 모듈 입력 전압이 너무 높음", + "ru": "Слишком высокое входное напряжение модуля аккумулятора", + "tr": "Pil modülü giriş gerilimi çok yüksek", + "zh": "电源模块输入电压过高" + }, + "fpv_tip_0x12010002": { + "de": "Akkumodul-Eingangsspannung zu niedrig", + "en": "Battery module input voltage too low", + "es": "Voltaje de entrada del módulo de batería demasiado bajo", + "fr": "Tension d'entrée du module de batterie insuffisante", + "ja": "バッテリーモジュール入力低電圧", + "ko": "배터리 모듈 입력 전압이 너무 낮음", + "ru": "Слишком низкое входное напряжение модуля аккумулятора", + "tr": "Pil modülü giriş gerilimi çok düşük", + "zh": "电源模块输入电压过低" + }, + "fpv_tip_0x12010003": { + "de": "Fehler: Akkumodul-Ausgangsspannung", + "en": "Battery module output voltage error", + "es": "Error de voltaje de salida del módulo de batería", + "fr": "Erreur de tension de sortie du module de batterie", + "ja": "バッテリーモジュール出力電圧エラー", + "ko": "배터리 모듈 출력 전압 오류", + "ru": "Ошибка выходного напряжения модуля аккумулятора", + "tr": "Pil modülü çıkış gerilimi hatası", + "zh": "电源模块输出电压异常" + }, + "fpv_tip_0x12010004": { + "de": "Fehler: Akkumodul-Ausgangsstrom", + "en": "Battery module output current error", + "es": "Error de corriente de salida del módulo de batería", + "fr": "Erreur de courant de sortie du module de batterie", + "ja": "バッテリーモジュール出力電流エラー", + "ko": "배터리 모듈 출력 전류 오류", + "ru": "Ошибка выходного тока модуля аккумулятора", + "tr": "Pil modülü çıkış akımı hatası", + "zh": "电源模块输出电流异常" + }, + "fpv_tip_0x12010005": { + "de": "Kurzschluss am Akkumodul", + "en": "Battery module short-circuited", + "es": "Módulo de batería cortocircuitado", + "fr": "Module de batterie court-circuité", + "ja": "バッテリーモジュールがショート", + "ko": "배터리 모듈 단락", + "ru": "Короткое замыкание модуля аккумулятора", + "tr": "Pil modülü kısa devre yaptı", + "zh": "电源模块发生短路" + }, + "fpv_tip_0x12010006": { + "de": "Kommunikationsfehler: Akkumodul", + "en": "Battery module communication error", + "es": "Error de comunicación del módulo de batería", + "fr": "Erreur de communication avec le module de batterie", + "ja": "バッテリーモジュール通信エラー", + "ko": "배터리 모듈 통신 오류", + "ru": "Ошибка связи модуля аккумулятора", + "tr": "Pil modülü iletişim hatası", + "zh": "电源模块通信异常" + }, + "fpv_tip_0x12010007": { + "de": "Fehlfunktion: Akkumodul-Lüfter", + "en": "Battery module fan malfunctioned", + "es": "Error de funcionamiento del ventilador del módulo de batería", + "fr": "Dysfonctionnement du ventilateur du module de batterie", + "ja": "バッテリーモジュールファン不良", + "ko": "배터리 모듈 팬 오작동", + "ru": "Неисправность вентилятора модуля аккумулятора", + "tr": "Pil modülü fanı arızalı", + "zh": "电源模块风扇故障" + }, + "fpv_tip_0x12010008": { + "de": "Akkumodul-Temperatur zu hoch", + "en": "Battery module temperature too high", + "es": "Temperatura del módulo de batería demasiado alta", + "fr": "Température du module de batterie excessive", + "ja": "バッテリーモジュールの温度が高すぎます", + "ko": "배터리 모듈 온도가 너무 높음", + "ru": "Слишком высокая температура модуля аккумулятора", + "tr": "Pil modülü sıcaklığı çok yüksek", + "zh": "电源模块温度过高" + }, + "fpv_tip_0x12020000": { + "de": "Kommunikationsfehler: Akku in Akkuschacht %index", + "en": "Battery port %index battery communication error", + "es": "Error de comunicación de la batería en el puerto de batería %index", + "fr": "Erreur de communication avec la batterie du port de batterie %index", + "ja": "バッテリーポート %index バッテリー通信エラー", + "ko": "배터리 포트 %index 배터리 통신 오류", + "ru": "Ошибка связи с аккумулятором (порт аккумулятора %index)", + "tr": "Pil portu %index pilinde iletişim hatası", + "zh": "%index槽位电池通讯异常" + }, + "fpv_tip_0x12020001": { + "de": "Temperatur von Akku in Akkuschacht %index zu niedrig", + "en": "Battery port %index battery temperature too low", + "es": "Temperatura de la batería en el puerto de batería %index demasiado baja", + "fr": "Température de batterie insuffisante dans le port de batterie %index", + "ja": "バッテリーポート %index バッテリー低温", + "ko": "배터리 포트 %index 배터리 온도가 너무 낮음", + "ru": "Слишком низкая температура аккумулятора (порт аккумулятора %index)", + "tr": "Pil portu %index pilinin sıcaklığı çok düşük", + "zh": "%index槽位电池温度过低" + }, + "fpv_tip_0x12020002": { + "de": "Akku in Akkuschacht %index überhitzt", + "en": "Battery port %index battery overheated", + "es": "Batería en el puerto de batería %index sobrecalentada", + "fr": "Surchauffe batterie dans le port de batterie %index", + "ja": "バッテリーポート %index バッテリー高温", + "ko": "배터리 포트 %index 배터리 과열", + "ru": "Аккумулятор перегрелся (порт аккумулятора %index)", + "tr": "Pil portu %index pili aşırı ısındı", + "zh": "%index槽位电池温度过高" + }, + "fpv_tip_0x12020003": { + "de": "Spannung von Akkuzelle in Akkuschacht %index zu hoch", + "en": "Battery port %index battery cell voltage too high", + "es": "Voltaje de la célula de la batería en el puerto de batería %index demasiado alto", + "fr": "Tension de cellule de batterie excessive dans le port de batterie %index", + "ja": "バッテリーポート %index バッテリーセル高電圧", + "ko": "배터리 포트 %index 배터리 셀 전압이 너무 높음", + "ru": "Слишком высокое напряжение элемента аккумулятора (порт аккумулятора %index)", + "tr": "Pil portu %index pil hücresi gerilimi çok yüksek", + "zh": "%index槽位电池电芯过压" + }, + "fpv_tip_0x12020004": { + "de": "Systemfehler: Akku in Akkuschacht %index", + "en": "Battery port %index battery system error", + "es": "Error del sistema de la batería en el puerto de batería %index", + "fr": "Erreur système batterie dans le port de batterie %index", + "ja": "バッテリーポート %index バッテリーシステムエラー", + "ko": "배터리 포트 %index 배터리 시스템 오류", + "ru": "Ошибка системы аккумулятора (порт аккумулятора %index)", + "tr": "Pil portu %index pilinde sistem hatası", + "zh": "%index槽位电池系统异常" + }, + "fpv_tip_0x12020005": { + "de": "Überstrom beim Aufladen des Akkus in Akkuschacht %index", + "en": "Battery port %index battery overcurrent during charging", + "es": "Sobreintensidad en la batería en el puerto de batería %index durante la carga", + "fr": "Surtension de la batterie en charge dans le port de batterie %index", + "ja": "バッテリーポート %index 充電中のバッテリー過電流", + "ko": "충전 중 배터리 포트 %index 배터리 과전류", + "ru": "Перегрузка аккумулятора по току во время зарядки (порт аккумулятора %index)", + "tr": "Pil portu %index pilinde şarj sırasında aşırı akım", + "zh": "%index槽位电池充电过流" + }, + "fpv_tip_0x12020006": { + "de": "Spannung von Akku in Akkuschacht %index zu hoch", + "en": "Battery port %index battery voltage too high", + "es": "Voltaje de la batería en el puerto de batería %index demasiado alto", + "fr": "Tension de batterie excessive dans le port de batterie %index", + "ja": "バッテリーポート %index バッテリー高電圧", + "ko": "배터리 포트 %index 배터리 전압이 너무 높음", + "ru": "Слишком высокое напряжение аккумулятора (порт аккумулятора %index)", + "tr": "Pil portu %index pilinin gerilimi çok yüksek", + "zh": "%index槽位电池电压过高" + }, + "fpv_tip_0x12020007": { + "de": "Spannung beim Aufladen von Akku in Akkuschacht %index zu hoch", + "en": "Battery port %index battery voltage too high during charging", + "es": "Voltaje de la batería en el puerto de batería %index demasiado alto durante la carga", + "fr": "Tension excessive de la batterie en charge dans le port de batterie %index", + "ja": "バッテリーポート %index 充電中のバッテリー高電圧", + "ko": "충전 중 배터리 포트 %index 배터리 전압이 너무 높음", + "ru": "Слишком высокое напряжение аккумулятора во время зарядки (порт аккумулятора %index)", + "tr": "Pil portu %index pilinin gerilimi şarj sırasında çok yüksek", + "zh": "%index槽位电池充电过压" + }, + "fpv_tip_0x12020008": { + "de": "Spannung beim Aufladen von Akku in Akkuschacht %index zu niedrig", + "en": "Battery port %index battery voltage too low during charging", + "es": "Voltaje de la batería en el puerto de batería %index demasiado bajo durante la carga", + "fr": "Tension insuffisante de la batterie en charge dans le port de batterie %index", + "ja": "バッテリーポート %index 充電中のバッテリー低電圧", + "ko": "충전 중 배터리 포트 %index 배터리 전압이 너무 낮음", + "ru": "Слишком низкое напряжение аккумулятора во время зарядки (порт аккумулятора %index)", + "tr": "Pil portu %index pilinin gerilimi şarj sırasında çok düşük", + "zh": "%index槽位电池充电欠压" + }, + "fpv_tip_0x12020009": { + "de": "Akku in Akkuschacht %index dauerhaft beschädigt", + "en": "Battery port %index battery permanently damaged", + "es": "Batería en el puerto de batería %index dañada de forma permanente", + "fr": "Batterie endommagée de manière permanente dans le port de batterie %index", + "ja": "バッテリーポート %index バッテリーが恒久的に損傷", + "ko": "배터리 포트 %index 배터리가 영구 손상됨", + "ru": "Аккумулятор поврежден без возможности восстановления (порт аккумулятора %index)", + "tr": "Pil portu %index pili kalıcı hasar gördü", + "zh": "%index槽位电池永久损坏" + }, + "fpv_tip_0x1202000A": { + "de": "Kurzschluss am Akku in Akkuschacht %index", + "en": "Battery port %index battery short-circuited", + "es": "Batería en el puerto de batería %index cortocircuitada", + "fr": "Batterie court-circuitée dans le port de batterie %index", + "ja": "バッテリーポート %index バッテリーがショート", + "ko": "배터리 포트 %index 배터리 단락", + "ru": "Короткое замыкание аккумулятора (порт аккумулятора %index)", + "tr": "Pil portu %index pili kısa devre yaptı", + "zh": "%index槽位电池短路" + }, + "fpv_tip_0x1202000B": { + "de": "Aufladen des Akkus in Akkuschacht %index dauert zu lange", + "en": "Battery port %index battery charging taking too long", + "es": "La carga de la batería en el puerto de batería %index está tardando demasiado", + "fr": "Charge trop lente dans le port de batterie %index", + "ja": "バッテリーポート %index バッテリー充電が長すぎます", + "ko": "배터리 포트 %index 배터리 충전이 너무 오래 걸림", + "ru": "Зарядка аккумулятора занимает слишком долго (порт аккумулятора %index)", + "tr": "Pil portu %index pilinin şarj olması çok uzun sürüyor", + "zh": "%index槽位电池充电时间过长" + }, + "fpv_tip_0x1202000C": { + "de": "Beim Aufladen kein Strom für Akku in Akkuschacht %index erkannt", + "en": "No current detected for battery port %index battery during charging", + "es": "No se ha detectado corriente en la batería en el puerto de batería %index durante la carga", + "fr": "Aucun courant détecté pour la batterie en charge dans le port de batterie %index", + "ja": "バッテリーポート %index バッテリーの充電中に電流が検出されません", + "ko": "충전 중 배터리 포트 %index 배터리에 대한 전류가 감지되지 않음", + "ru": "На порте аккумулятора %index не обнаружен ток во время зарядки аккумулятора", + "tr": "Pil portu %index pili için şarj sırasında tespit edilen akım yok", + "zh": "%index槽位电池无充电电流" + }, + "fpv_tip_0x1202000D": { + "de": "Akkutyp in Akkuschacht %index nicht erkannt", + "en": "Battery port %index battery type not recognized", + "es": "Tipo de la batería en el puerto de batería %index no reconocido", + "fr": "Type de batterie non reconnu dans le port de batterie %index", + "ja": "バッテリーポート %index バッテリータイプが認識されません", + "ko": "배터리 포트 %index 배터리 유형이 인식되지 않음", + "ru": "Тип аккумулятора не распознан (порт аккумулятора %index)", + "tr": "Pil portu %index pilinin tipi tanınmadı", + "zh": "%index槽位电池类型无法识别" + }, + "fpv_tip_0x12030000": { + "de": "Battery Station-Motherboard überhitzt", + "en": "Battery Station motherboard overheated", + "es": "Placa base de la Estación de Baterías sobrecalentada", + "fr": "Surchauffe de la carte mère de la station de batteries", + "ja": "バッテリーステーションマザーボード高温", + "ko": "배터리 스테이션 마더보드 과열", + "ru": "Перегрев материнской платы зарядной станции", + "tr": "Pil İstasyonu ana kartı aşırı ısındı", + "zh": "电池箱主板温度过高" + }, + "fpv_tip_0x12030001": { + "de": "Spannung von Battery Station-Motherboard zu hoch", + "en": "Battery Station motherboard voltage too high", + "es": "Voltaje de la placa base de la Estación de Baterías demasiado alto", + "fr": "Tension de la carte mère de la station de batteries excessive", + "ja": "バッテリーステーションマザーボード高電圧", + "ko": "배터리 스테이션 마더보드 전압이 너무 높음", + "ru": "Слишком высокое напряжение на материнской плате зарядной станции", + "tr": "Pil İstasyonu ana kartı gerilimi çok yüksek", + "zh": "电池箱主板电压过高" + }, + "fpv_tip_0x12030002": { + "de": "Spannung von Battery Station-Motherboard zu niedrig", + "en": "Battery Station motherboard voltage too low", + "es": "Voltaje de la placa base de la Estación de Baterías demasiado bajo", + "fr": "Tension de la carte mère de la station de batteries insuffisante", + "ja": "バッテリーステーションマザーボード低電圧", + "ko": "배터리 스테이션 마더보드 전압이 너무 낮음", + "ru": "Слишком низкое напряжение на материнской плате зарядной станции", + "tr": "Pil İstasyonu ana kartı gerilimi çok düşük", + "zh": "电池箱主板电压过低" + }, + "fpv_tip_0x12030003": { + "de": "Fehler: Battery Station-Schacht %index", + "en": "Battery Station port %index error", + "es": "Error del puerto %index de la Estación de Baterías", + "fr": "Erreur liée au port %index de la station de batteries", + "ja": "バッテリーステーションポート %index エラー", + "ko": "배터리 스테이션 포트 %index 오류", + "ru": "Ошибка порта %index зарядной станции", + "tr": "Pil İstasyonu portu %index hatası", + "zh": "电池箱%index槽位充电通道异常" + }, + "fpv_tip_0x12030004": { + "ar": "", + "de": "", + "en": "AC Input Voltage Drop Too Large", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "交流输入压降过大", + "zh-Hant": "" + }, + "fpv_tip_0x12030005": { + "ar": "", + "de": "", + "en": "Oil Maintenance Tips", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "机油保养提示", + "zh-Hant": "" + }, + "fpv_tip_0x12030006": { + "ar": "", + "de": "", + "en": "Charging Device Controller Board Output Voltage Error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "管家板输出电压异常", + "zh-Hant": "" + }, + "fpv_tip_0x12030007": { + "ar": "", + "de": "", + "en": "Controller Board of Charging Device Input Voltage Error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "管家板输入电压异常", + "zh-Hant": "" + }, + "fpv_tip_0x12120000": { + "de": "Kommunikationsfehler: Fernsteuerungs-Akku in Akkuschacht %index", + "en": "Battery port %index remote controller battery communication error", + "es": "Error de comunicación de la batería del control remoto en el puerto de batería %index", + "fr": "Erreur de communication avec la batterie de la radiocommande dans le port de batterie %index", + "ja": "バッテリーポート %index 送信機バッテリー通信エラー", + "ko": "배터리 포트 %index 조종기 배터리 통신 오류", + "ru": "Ошибка связи с аккумулятором пульта управления (порт аккумулятора %index)", + "tr": "Pil portu %index uzaktan kumanda pilinde iletişim hatası", + "zh": "%index槽位遥控器电池通信异常" + }, + "fpv_tip_0x12120001": { + "de": "Temperaturfehler: Fernsteuerungs-Akku in Akkuschacht %index", + "en": "Battery port %index remote controller battery temperature error", + "es": "Error de temperatura de la batería del control remoto en el puerto de batería %index", + "fr": "Erreur de température de la batterie de la radiocommande dans le port de batterie %index", + "ja": "バッテリーポート %index 送信機バッテリー温度エラー", + "ko": "배터리 포트 %index 조종기 배터리 온도 오류", + "ru": "Ошибка температуры аккумулятора пульта управления (порт аккумулятора %index)", + "tr": "Pil portu %index uzaktan kumanda pilinde sıcaklık hatası", + "zh": "%index槽位遥控器电池温度异常" + }, + "fpv_tip_0x12120002": { + "de": "Ladefehler: Fernsteuerungs-Akku in Akkuschacht %index", + "en": "Battery port %index remote controller battery charging error", + "es": "Error de carga de la batería del control remoto en el puerto de batería %index", + "fr": "Erreur de charge de la batterie de la radiocommande dans le port de batterie %index", + "ja": "バッテリーポート %index 送信機バッテリー充電エラー", + "ko": "배터리 포트 %index 조종기 배터리 충전 오류", + "ru": "Ошибка зарядки аккумулятора пульта управления (порт аккумулятора %index)", + "tr": "Pil portu %index uzaktan kumanda pilinde şarj hatası", + "zh": "%index槽位遥控器电池充电异常" + }, + "fpv_tip_0x14010031": { + "de": "Nutzlast-Datenkonsolidierungsfehler. Nutzlast neu starten", + "en": "Payload infusion data error. Restart payload", + "es": "Error de datos de infusión del instrumento. Reinicia el instrumento", + "fr": "Erreur de données d\\'infusion charge utile. Redémarrer la charge utile", + "ja": "ペイロード融合データエラー。ペイロードを再起動してください", + "ko": "페이로드 인퓨전 데이터 오류. 페이로드 재시작 필요", + "ru": "Предупреждение о жизненном цикле лидара", + "tr": "Yük infüzyon verisi hatası. Yükü yeniden başlatın", + "zh": "负载融合数据异常,请重启负载" + }, + "fpv_tip_0x14010032": { + "de": "Nutzlast-Datenkonsolidierung kann nicht abgeschlossen werden", + "en": "Unable to converge payload infusion data", + "es": "No se pueden juntar los datos de infusión del instrumento", + "fr": "Impossible de rassembler les données d\\'infusion de la charge utile", + "ja": "ペイロード融合データを収束できません", + "ko": "페이로드 인퓨전 데이터 수렴 불가", + "ru": "Не удалось объединить данные полезной нагрузки", + "tr": "Yük infüzyon verisi yakınsanamadı", + "zh": "负载融合数据未收敛" + }, + "fpv_tip_0x14010033": { + "de": "Nutzlast-Systemzeitfehler. Fluggerät neu starten", + "en": "Payload system time error. Restart aircraft", + "es": "Error de la hora del sistema del instrumento. Reinicia la aeronave", + "fr": "Erreur de temps du système de charge utile. Redémarrer l\\'appareil", + "ja": "ペイロードシステム タイムエラー。機体を再起動してください", + "ko": "페이로드 시스템 시간 오류. 기체 재시작 필요", + "ru": "Ошибка времени системы полезной нагрузки. Перезапустите дрон", + "tr": "Yük sistem saati hatası. Aracı yeniden başlatın", + "zh": "负载系统时间异常,请重启飞行器" + }, + "fpv_tip_0x14010034": { + "de": "Nutzlast-Geschwindigkeitsdaten ungültig. Nutzlast neu starten", + "en": "Payload tachometer data invalid. Restart payload", + "es": "Datos del tacómetro del instrumento no válidos. Reinicia el instrumento", + "fr": "Données du tachymètre de la charge utile invalides. Redémarrer la charge utile", + "ja": "ペイロードタコメーターデータ無効。ペイロードを再起動してください", + "ko": "유효하지 않은 페이로드 태코미터 데이터. 페이로드 재시작 필요", + "ru": "Недействительные данные тахометра. Перезапустите полезную нагрузку", + "tr": "Yük takometre verisi geçersiz. Yükü yeniden başlatın", + "zh": "负载角速度计数据非法,请重启负载" + }, + "fpv_tip_0x14010035": { + "de": "Nutzlast-Geschwindigkeitsdaten nicht aktualisiert. Nutzlast neu starten", + "en": "Payload tachometer data not updated. Restart payload", + "es": "Datos del tacómetro del instrumento no actualizados. Reinicia el instrumento", + "fr": "Données du tachymètre de la charge utile non mises à jour. Redémarrer la charge utile", + "ja": "ペイロードタコメーターデータ未更新。ペイロードを再起動してください", + "ko": "페이로드 태코미터 데이터 업데이트 안 됨. 페이로드 재시작 필요", + "ru": "Данные тахометра не обновлены. Перезапустите полезную нагрузку", + "tr": "Yük takometre verisi güncel değil. Yükü yeniden başlatın", + "zh": "负载角速度计数据卡死,请重启负载" + }, + "fpv_tip_0x14010036": { + "de": "Keine Nutzlast-Geschwindigkeitsdaten. Nutzlast neu starten", + "en": "No payload tachometer data. Restart payload", + "es": "No hay datos del tacómetro del instrumento. Reinicia el instrumento", + "fr": "Aucune données du tachymètre de la charge utile. Redémarrer la charge utile", + "ja": "ペイロードタコメーターデータなし。ペイロードを再起動してください", + "ko": "페이로드 태코미터 데이터 없음. 페이로드 재시작 필요", + "ru": "Нет данных тахометра полезной нагрузки. Перезапустите полезную нагрузку", + "tr": "Yük takometre verisi yok. Yükü yeniden başlatın", + "zh": "负载无角速度计数据,请重启负载" + }, + "fpv_tip_0x14010037": { + "de": "Nutzlast-Geschwindigkeitsdaten überschreiten das Limit. Nutzlast neu starten", + "en": "Payload tachometer data exceeds limit. Restart payload", + "es": "Los datos del tacómetro del instrumento superan el límite. Reinicia el instrumento", + "fr": "Limite de données du tachymètre de la charge utile dépassée. Redémarrer la charge utile", + "ja": "ペイロードタコメーターデータ制限超過。ペイロードを再起動してください", + "ko": "페이로드 태코미터 데이터 한도 초과. 페이로드 재시작 필요", + "ru": "Данные тахометра полезной нагрузки превышают максимальное значение. Перезапустите полезную нагрузку", + "tr": "Yük takometre verisi sınırı aşıyor. Yükü yeniden başlatın", + "zh": "负载角速度计数据超限,请重启负载" + }, + "fpv_tip_0x14010038": { + "de": "Nutzlast-Geschwindigkeitsdatenfehler. Nutzlast neu starten", + "en": "Payload tachometer data error. Restart payload", + "es": "Error de datos del tacómetro del instrumento. Reinicia el instrumento", + "fr": "Erreur de données du tachymètre de la charge utile. Redémarrer la charge utile", + "ja": "ペイロードタコメーター データエラー。ペイロードを再起動してください", + "ko": "페이로드 태코미터 데이터 오류. 페이로드 재시작 필요", + "ru": "Ошибка данных тахометра. Перезапустите дрон", + "tr": "Yük takometre verisi hatası. Yükü yeniden başlatın", + "zh": "负载角速度计数据异常,请重启负载" + }, + "fpv_tip_0x14010039": { + "de": "Nutzlast-Beschleunigungsdaten ungültig. Nutzlast neu starten", + "en": "Payload accelerometer data invalid. Restart payload", + "es": "Datos del acelerómetro del instrumento no válidos. Reinicia el instrumento", + "fr": "Données de l\\'accéléromètre de la charge utile invalides. Redémarrer la charge utile", + "ja": "ペイロード加速度計データ無効。ペイロードを再起動してください", + "ko": "유효하지 않은 페이로드 가속도계 데이터. 페이로드 재시작 필요", + "ru": "Недействительные данные акселерометра. Перезапустите полезную нагрузку", + "tr": "Yük ivmeölçer verisi geçersiz. Yükü yeniden başlatın", + "zh": "负载加速度计数据非法,请重启负载" + }, + "fpv_tip_0x1401003A": { + "de": "Nutzlast-Beschleunigungsdaten nicht aktualisiert. Nutzlast neu starten", + "en": "Payload accelerometer data not updated. Restart payload", + "es": "Datos del acelerómetro de la carga no actualizados. Reinicia el instrumento", + "fr": "Données de l\\'accéléromètre de la charge utile non mises à jour. Redémarrer la charge utile", + "ja": "ペイロード加速度計データ未更新。ペイロードを再起動してください", + "ko": "페이로드 가속도계 데이터 업데이트 안 됨. 페이로드 재시작 필요", + "ru": "Данные акселерометра не обновлены. Перезапустите полезную нагрузку", + "tr": "Yük ivmeölçer verisi güncel değil. Yükü yeniden başlatın", + "zh": "负载加速度计数据卡死,请重启负载" + }, + "fpv_tip_0x1401003B": { + "de": "Keine Nutzlast-Beschleunigungsdaten. Nutzlast neu starten", + "en": "No payload accelerometer data. Restart payload", + "es": "No hay datos del acelerómetro del instrumento. Reinicia el instrumento", + "fr": "Aucune données de l\\'accéléromètre de a charge utile. Redémarrer la charge utile", + "ja": "ペイロード加速度計データなし。ペイロードを再起動してください", + "ko": "페이로드 가속도계 데이터 없음. 페이로드 재시작 필요", + "ru": "Нет данных акселерометра. Перезапустите полезную нагрузку", + "tr": "Yük ivmeölçer verisi yok. Yükü yeniden başlatın", + "zh": "负载无加速度计数据,请重启负载" + }, + "fpv_tip_0x1401003C": { + "de": "Nutzlast-Beschleunigungsdaten überschreiten das Limit. Nutzlast neu starten", + "en": "Payload accelerometer data exceeds limit. Restart payload", + "es": "Los datos del acelerómetro del instrumento superan el límite. Reinicia el instrumento", + "fr": "Limite de données de l\\'accéléromètre de la charge utile dépassée. Redémarrer la charge utile", + "ja": "ペイロード加速度計データ制限超過。ペイロードを再起動してください", + "ko": "페이로드 가속도계 데이터 한도 초과. 페이로드 재시작 필요", + "ru": "Данные акселерометра превышают максимальное значение. Перезапустите полезную нагрузку", + "tr": "Yük ivmeölçer verisi sınırı aşıyor. Yükü yeniden başlatın", + "zh": "负载加速度计数据超限,请重启负载" + }, + "fpv_tip_0x1401003D": { + "de": "Nutzlast-Beschleunigungsdatenfehler. Nutzlast neu starten", + "en": "Payload accelerometer data error. Restart payload", + "es": "Datos del acelerómetro del instrumento no válidos. Reinicia el instrumento", + "fr": "Erreur de données de l\\'accéléromètre de la charge utile. Redémarrer la charge utile", + "ja": "ペイロード加速度計データエラー。ペイロードを再起動してください", + "ko": "페이로드 가속도계 데이터 오류. 페이로드 재시작 필요", + "ru": "Ошибка данных акселерометра. Перезапустите полезную нагрузку", + "tr": "Yük ivmeölçer verisi hatası. Yükü yeniden başlatın", + "zh": "负载加速度计数据异常,请重启负载" + }, + "fpv_tip_0x1401003E": { + "de": "Nutzlast-RTK-Datenberechnungsfehler. Fluggerät neu starten", + "en": "Payload RTK data calculation error. Restart aircraft", + "es": "Error de cálculo de datos RTK del instrumento. Reinicia la aeronave", + "fr": "Erreur de calcul des données RTK de la charge utile. Redémarrer l\\'appareil", + "ja": "ペイロードRTK データ計算エラー。機体を再起動してください", + "ko": "페이로드 RTK 데이터 계산 오류. 기체 재시작 필요", + "ru": "Ошибка расчета данных RTK. Перезапустите дрон", + "tr": "Yük ivmeölçer verisi hesaplama başarısız. Aracı yeniden başlatın", + "zh": "负载RTK数据解算异常,请重启飞行器" + }, + "fpv_tip_0x1401003F": { + "de": "Nutzlast-Richtungsdatenfehler. Satellitensignal prüfen", + "en": "Payload direction data error. Check satellite signal", + "es": "Error de datos de dirección del instrumento. Compruebe la señal satelital", + "fr": "Erreur de données de direction de nacelles-caméras. Vérifier le signal satellite", + "ja": "ペイロード方向データエラーです。衛星信号を確認してください", + "ko": "페이로드 방향 데이터 오류. 위성 신호를 확인하세요.", + "ru": "Ошибка данных направления полезной нагрузки. Проверьте сигнал спутника", + "tr": "Yük yönü verisi hatası. Uydu sinyalini kontrol edin", + "zh": "负载测向数据异常,请确认飞机搜星质量" + }, + "fpv_tip_0x14010040": { + "de": "Nutzlast-RTK-Datenfehler. Fluggerät neu starten", + "en": "Payload RTK data error. Restart aircraft", + "es": "Error de datos RTK del instrumento. Reinicia la aeronave", + "fr": "Erreur de données RTK de charge utile. Redémarrer l\\'appareil", + "ja": "ペイロードRTK データエラー。機体を再起動してください", + "ko": "페이로드 RTK 데이터 오류. 기체 재시작 필요", + "ru": "Ошибка данных RTK. Перезапустите дрон", + "tr": "Yük RTK verisi hatası. Aracı yeniden başlatın", + "zh": "负载RTK数据异常,请重启飞行器" + }, + "fpv_tip_0x14010041": { + "de": "Nutzlast-RTK-Zeitfehler. Fluggerät neu starten", + "en": "Payload RTK time error. Restart aircraft", + "es": "Error de la hora del RTK del instrumento. Reinicia la aeronave", + "fr": "Erreur de temps du RTK de charge utile. Redémarrer l\\'appareil", + "ja": "ペイロードRTK タイムエラー。機体を再起動してください", + "ko": "페이로드 RTK 시간 오류. 기체 재시작 필요", + "ru": "Ошибка времени RTK. Перезапустите дрон", + "tr": "Yük RTK saati hatası. Aracı yeniden başlatın", + "zh": "负载RTK时间异常,请重启飞行器" + }, + "fpv_tip_0x14010042": { + "ar": "", + "de": "Nutzlast-RTK-Daten ungültig. Fluggerät neu starten", + "en": "Payload RTK data invalid. Restart aircraft", + "es": "Datos RTK del instrumento no válidos. Reinicia la aeronave", + "fr": "Erreur de données RTK de la charge utile. Redémarrer l\\'appareil", + "id": "", + "it": "", + "ja": "ペイロードRTK データ無効。機体を再起動してください", + "ko": "유효하지 않은 페이로드 RTK 데이터. 기체 재시작 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Данные RTK недействительны. Перезапустите дрон", + "th": "", + "tr": "Yük RTK verisi geçersiz. Aracı yeniden başlatın", + "ug": "", + "vi": "", + "zh": "负载RTK数据无效,请重启飞行器", + "zh-Hant": "" + }, + "fpv_tip_0x14010042_in_the_sky": { + "ar": "", + "de": "Nutzlast-RTK-Daten ungültig. Sicherstellen, dass die Suche nach dem Satellitensignal ordnungsgemäß funktioniert, und warten, bis RTK fixiert ist", + "en": "Payload RTK data invalid. Make sure satellite signal searching is normal and wait until RTK is fixed", + "es": "Datos RTK del instrumento no válidos. Asegúrese de que la búsqueda de señal satelital sea normal y espere hasta que RTK esté fijo", + "fr": "Données RTK de nacelles-caméras non valides. Assurez-vous que la recherche du signal satellite est normale et attendez que le RTK soit fixe", + "id": "", + "it": "", + "ja": "搭載RTKデータが無効です。衛星信号捕捉が正常であることを確認し、RTKが修正されるまでお待ちください", + "ko": "페이로드 RTK 데이터가 유효하지 않습니다. 위성 신호 검색이 정상인지 확인하고 RTK가 확정될 때까지 기다려주세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Данные полезной нагрузки RTK недействительны. Убедитесь, что поиск спутникового сигнала работает без сбоев; дождитесь настройки RTK", + "th": "", + "tr": "Yük RTK verisi geçersiz. Uydu sinyali aramasının normal olduğundan emin olun ve RTK sabitleninceye kadar bekleyin", + "ug": "", + "vi": "", + "zh": "负载RTK数据无效,请确认搜星情况良好,等待恢复", + "zh-Hant": "" + }, + "fpv_tip_0x14010043": { + "de": "Nutzlast-IMU wird erwärmt. Bitte warten, bis IMU aufgewärmt ist", + "en": "Payload IMU warming up. Wait until IMU finished warming up to continue", + "es": "Calentando la IMU del instrumento. Espera a que la IMU termine de calentarse antes de continuar", + "fr": "Réchauffage de l'IMU. Veuillez attendre que l'IMU ait chauffé avant de continuer", + "it": "", + "ja": "ペイロードIMUウォームアップ中。温まるまで待って継続してください", + "ko": "페이로드 IMU 예열 중. IMU 예열 완료까지 대기", + "pt": "", + "ru": "Прогрев IMU. Подождите, пока IMU закончит прогрев, чтобы продолжить", + "tr": "Yük IMU'su ısınıyor. Devam etmek için IMU'nun ısınması tamamlanana kadar bekleyin", + "zh": "请等待负载惯导预热完成" + }, + "fpv_tip_0x14010044": { + "de": "Fehler: Temperatursteuerung der Nutzlast-IMU. Nutzlast neu starten", + "en": "Payload IMU temperature control processor error. Restart payload", + "es": "Error del procesador de control de temperatura de la IMU del instrumento. Reinicia el instrumento", + "fr": "Erreur du processeur de contrôle de la température de l'IMU. Redémarrer la charge utile", + "it": "", + "ja": "ペイロードIMU温度制御プロセッサー エラー。ペイロードを再起動してください", + "ko": "페이로드 IMU 온도 제어 프로세서 오류. 페이로드 재시작 필요", + "pt": "", + "ru": "Ошибка процессора контроля температуры IMU. Перезапустите полезную нагрузку", + "tr": "Yük IMU'su sıcaklık denetleyici işlemcisi hatası. Yükü yeniden başlatın", + "zh": "负载惯导温控异常,请重启负载" + }, + "fpv_tip_0x14010045": { + "de": "Nutzlast-IMU überhitzt. Nutzlast neu starten", + "en": "Payload IMU overheated. Restart payload", + "es": "IMU del instrumento sobrecalentada. Reinicia el instrumento", + "fr": "Surchauffe de l'IMU de la charge utile. Redémarrer la charge utile", + "it": "", + "ja": "ペイロードIMU高温。ペイロードを再起動してください", + "ko": "페이로드 IMU 과열. 페이로드 재시작 필요", + "pt": "", + "ru": "Перегрев полезной нагрузки IMU. Перезапустите полезную нагрузку", + "tr": "Yük IMU'su aşırı ısındı. Yükü yeniden başlatın", + "zh": "负载惯导温度过高,请重启负载" + }, + "fpv_tip_0x14010046": { + "de": "Nutzlast-IMU-Temperatur zu niedrig. Nutzlast neu starten", + "en": "Payload IMU temperature too low. Restart payload", + "es": "Temperatura de la IMU del instrumento demasiado baja. Reinicia el instrumento", + "fr": "Température de l'IMU de la charge utile trop basse. Redémarrer la charge utile", + "it": "", + "ja": "ペイロードIMU低温。ペイロードを再起動してください", + "ko": "페이로드 IMU 온도 너무 낮음. 페이로드 재시작 필요", + "pt": "", + "ru": "Слишком низкая температура IMU. Перезапустите полезную нагрузку", + "tr": "Yük IMU'su sıcaklığı çok düşük. Yükü yeniden başlatın", + "zh": "负载惯导温度过低,请重启负载" + }, + "fpv_tip_0x14010047": { + "de": "Nutzlastprozessor überhitzt. Sofort zurückkehren oder landen. Nutzlast entfernen und abwarten, bis diese abgekühlt ist", + "en": "Payload processor overheated. Return to home or land promptly. Remove payload and wait for it to cool down before use", + "es": "Procesador del instrumento sobrecalentado. Regresa al punto de origen o aterriza rápidamente. Quita el instrumento y espera a que se enfríe antes del uso", + "fr": "Surchauffe processeur caméra. Revenez au point de départ ou atterrissez immédiatement. Attendez que la température revienne à la normale avant usage", + "ja": "ペイロードプロセッサー高温。直ちに帰還するか着陸してください。ペイロードを取り外し、プロセッサーが常温に戻るまで待ち 、使用してください", + "ko": "페이로드 프로세서 과열. 즉시 RTH 또는 착륙 필요. 페이로드 분리 후 열이 다 식은 후 사용 가능", + "ru": "Перегрев процессора. Вернитесь в домашнюю точку или приземлитесь как можно скорее. Снимите полезную нагрузку и подождите, пока она остынет, перед повторным использованием", + "tr": "Yük işlemcisi aşırı ısındı. Eve geri dönün veya düzgün iniş yapın. Yükü çıkarın ve kullanmadan önce soğumasını bekleyin", + "zh": "负载芯片温度过高,请尽快返航或降落,移除负载等待冷却后重启使用" + }, + "fpv_tip_0x14010047_in_the_sky": { + "de": "Nutzlastprozessor überhitzt. Sofort zurückkehren oder landen. Nutzlast entfernen und abwarten, bis diese abgekühlt ist", + "en": "Payload processor overheated. Return to home or land promptly. Remove payload and wait for it to cool down before use", + "es": "Procesador del instrumento sobrecalentado. Regresa al punto de origen o aterriza rápidamente. Quita el instrumento y espera a que se enfríe antes del uso", + "fr": "Surchauffe du processeur de la charge utile. Retournez au point de départ ou atterrissez rapidement. Retirer la charge utile et attendez qu\\'elle revienne à une température normale", + "it": "", + "ja": "ペイロードプロセッサー高温。直ちに帰還するか着陸してください。ペイロードを取り外し、プロセッサーが常温に戻るまで待ち\r\r\n、使用してください", + "ko": "페이로드 프로세서 과열. 즉시 RTH 또는 착륙 필요. 페이로드 분리 후 열이 다 식은 후 사용 가능", + "pt": "", + "ru": "Перегрев процессора. Вернитесь в домашнюю точку или приземлитесь как можно скорее. Снимите полезную нагрузку и подождите, пока она остынет, перед повторным использованием", + "tr": "Yük işlemcisi aşırı ısındı. Eve geri dönün veya düzgün iniş yapın. Yükü çıkarın ve kullanmadan önce soğumasını bekleyin", + "zh": "负载芯片温度过高,请尽快返航或降落,移除负载等待冷却后重启使用" + }, + "fpv_tip_0x14010048": { + "ar": "", + "de": "Fehler des Nutzlastlüfters. Überprüfen, ob der Lüfter blockiert ist", + "en": "Payload fan error. Check whether the fan is stalled", + "es": "Error del ventilador del instrumento. Compruebe si el ventilador está atascado", + "fr": "Erreur sur le ventilateur de la nacelle-caméra. Vérifiez si le ventilateur est bloqué", + "id": "", + "it": "", + "ja": "搭載ファンエラー。ファンが停止していないかを確認してください", + "ko": "페이로드 팬 오류. 팬이 멈췄는지 확인하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка полезной нагрузки вентилятора. Проверьте, не заклинило ли вентилятор", + "th": "", + "tr": "Yük fanı hatası. Fanın arızalanarak durup durmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "负载风扇异常,请检查负载风扇是否有堵转", + "zh-Hant": "" + }, + "fpv_tip_0x14010048_in_the_sky": { + "ar": "", + "de": "Fehler des Nutzlastlüfters. Zum Startpunkt zurückkehren oder landen und prüfen, ob der Lüfter blockiert ist", + "en": "Payload fan error. Return to home or land and check whether the fan is stalled", + "es": "Error del ventilador del instrumento. Regrese al punto de origen y compruebe si el ventilador está atascado", + "fr": "Erreur sur le ventilateur de la nacelle-caméra. Revenez au point de départ ou atterrissez et vérifiez si le ventilateur est bloqué", + "id": "", + "it": "", + "ja": "搭載ファンエラー。RTHまたは着陸させ、ファンが停止していないかを確認してください", + "ko": "페이로드 팬 오류. 리턴 투 홈하거나 착륙해 팬이 작동을 멈추었는지 여부를 확인하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка полезной нагрузки вентилятора. Вернитесь домой или приземлитесь. Проверьте, не заклинило ли вентилятор", + "th": "", + "tr": "Yük fanı hatası. Eve dönün veya iniş yapın ve fanın durup durmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "负载风扇异常,请返航或降落,检查负载风扇是否有堵转", + "zh-Hant": "" + }, + "fpv_tip_0x14010049": { + "de": "Nutzlast-PPS-Datenfehler", + "en": "Payload PPS Data Error", + "es": "Error de datos PPS de instrumentos", + "fr": "Erreur de données PPS de nacelles-caméras", + "ja": "ペイロードPPSデータエラー", + "ko": "페이로드 PPS 데이터 오류", + "ru": "Ошибка данных PPS полезной нагрузки", + "tr": "Yük PPS Verisi Hatası", + "zh": "负载PPS数据异常" + }, + "fpv_tip_0x1401004A": { + "de": "Nutzlast-UTC-Zeitfehler", + "en": "Payload UTC Time Error", + "es": "Error de hora UTC de instrumentos", + "fr": "Erreur de temps UTC de nacelles-caméras", + "ja": "ペイロードUTC時刻エラー", + "ko": "페이로드 UTC 시간 오류", + "ru": "Ошибка времени UTC полезной нагрузки", + "tr": "Yük UTC Saati Hatası", + "zh": "负载UTC时间异常" + }, + "fpv_tip_0x14020000": { + "en": "ASIC芯片温度异常", + "zh": "ASIC芯片温度异常" + }, + "fpv_tip_0x14020001": { + "en": "主控芯片温度异常", + "zh": "主控芯片温度异常" + }, + "fpv_tip_0x14020002": { + "en": "看门狗超时", + "zh": "看门狗超时" + }, + "fpv_tip_0x14020003": { + "en": "ASIC芯片错误", + "zh": "ASIC芯片错误" + }, + "fpv_tip_0x14020004": { + "en": "栈溢出", + "zh": "栈溢出" + }, + "fpv_tip_0x14020005": { + "en": "MIPI故障", + "zh": "MIPI故障" + }, + "fpv_tip_0x14020007": { + "en": "脏污预警", + "zh": "脏污预警" + }, + "fpv_tip_0x14020031": { + "de": "Nutzlast-Datenkonsolidierungsfehler. Nutzlast neu starten", + "en": "Payload infusion data error. Restart payload", + "es": "Error de datos de infusión del instrumento. Reinicia el instrumento", + "fr": "Erreur de données d'infusion charge utile. Redémarrer la charge utile", + "it": "", + "ja": "ペイロード融合データエラー。ペイロードを再起動してください", + "ko": "페이로드 인퓨전 데이터 오류. 페이로드 재시작 필요", + "pt": "", + "ru": "Предупреждение о жизненном цикле лидара", + "tr": "Yük infüzyon verisi hatası. Yükü yeniden başlatın", + "zh": "负载融合数据异常,请重启负载" + }, + "fpv_tip_0x14020032": { + "de": "Nutzlast-Datenkonsolidierung kann nicht abgeschlossen werden", + "en": "Unable to converge payload infusion data", + "es": "No se pueden juntar los datos de infusión del instrumento", + "fr": "Impossible de rassembler les données d'infusion de la charge utile", + "it": "", + "ja": "ペイロード融合データを収束できません", + "ko": "페이로드 인퓨전 데이터 수렴 불가", + "pt": "", + "ru": "Не удалось объединить данные полезной нагрузки", + "tr": "Yük infüzyon verisi yakınsanamadı", + "zh": "负载融合数据未收敛" + }, + "fpv_tip_0x14020033": { + "de": "Nutzlast-Systemzeitfehler. Fluggerät neu starten", + "en": "Payload system time error. Restart aircraft", + "es": "Error de la hora del sistema del instrumento. Reinicia la aeronave", + "fr": "Erreur de temps du système de charge utile. Redémarrer l'appareil", + "it": "", + "ja": "ペイロードシステム タイムエラー。機体を再起動してください", + "ko": "페이로드 시스템 시간 오류. 기체 재시작 필요", + "pt": "", + "ru": "Ошибка времени системы полезной нагрузки. Перезапустите дрон", + "tr": "Yük sistem saati hatası. Aracı yeniden başlatın", + "zh": "负载系统时间异常,请重启飞行器" + }, + "fpv_tip_0x14020034": { + "de": "Nutzlast-Geschwindigkeitsdaten ungültig. Nutzlast neu starten", + "en": "Payload tachometer data invalid. Restart payload", + "es": "Datos del tacómetro del instrumento no válidos. Reinicia el instrumento", + "fr": "Données du tachymètre de la charge utile invalides. Redémarrer la charge utile", + "it": "", + "ja": "ペイロードタコメーターデータ無効。ペイロードを再起動してください", + "ko": "유효하지 않은 페이로드 태코미터 데이터. 페이로드 재시작 필요", + "pt": "", + "ru": "Недействительные данные тахометра. Перезапустите полезную нагрузку", + "tr": "Yük takometre verisi geçersiz. Yükü yeniden başlatın", + "zh": "负载角速度计数据非法,请重启负载" + }, + "fpv_tip_0x14020035": { + "de": "Nutzlast-Geschwindigkeitsdaten nicht aktualisiert. Nutzlast neu starten", + "en": "Payload tachometer data not updated. Restart payload", + "es": "Datos del tacómetro del instrumento no actualizados. Reinicia el instrumento", + "fr": "Données du tachymètre de la charge utile non mises à jour. Redémarrer la charge utile", + "it": "", + "ja": "ペイロードタコメーターデータ未更新。ペイロードを再起動してください", + "ko": "페이로드 태코미터 데이터 업데이트 안 됨. 페이로드 재시작 필요", + "pt": "", + "ru": "Данные тахометра не обновлены. Перезапустите полезную нагрузку", + "tr": "Yük takometre verisi güncel değil. Yükü yeniden başlatın", + "zh": "负载角速度计数据卡死,请重启负载" + }, + "fpv_tip_0x14020036": { + "de": "Keine Nutzlast-Geschwindigkeitsdaten. Nutzlast neu starten", + "en": "No payload tachometer data. Restart payload", + "es": "No hay datos del tacómetro del instrumento. Reinicia el instrumento", + "fr": "Aucune données du tachymètre de la charge utile. Redémarrer la charge utile", + "it": "", + "ja": "ペイロードタコメーターデータなし。ペイロードを再起動してください", + "ko": "페이로드 태코미터 데이터 없음. 페이로드 재시작 필요", + "pt": "", + "ru": "Нет данных тахометра полезной нагрузки. Перезапустите полезную нагрузку", + "tr": "Yük takometre verisi yok. Yükü yeniden başlatın", + "zh": "负载无角速度计数据,请重启负载" + }, + "fpv_tip_0x14020037": { + "de": "Nutzlast-Geschwindigkeitsdaten überschreiten das Limit. Nutzlast neu starten", + "en": "Payload tachometer data exceeds limit. Restart payload", + "es": "Los datos del tacómetro del instrumento superan el límite. Reinicia el instrumento", + "fr": "Limite de données du tachymètre de la charge utile dépassée. Redémarrer la charge utile", + "it": "", + "ja": "ペイロードタコメーターデータ制限超過。ペイロードを再起動してください", + "ko": "페이로드 태코미터 데이터 한도 초과. 페이로드 재시작 필요", + "pt": "", + "ru": "Данные тахометра полезной нагрузки превышают максимальное значение. Перезапустите полезную нагрузку", + "tr": "Yük takometre verisi sınırı aşıyor. Yükü yeniden başlatın", + "zh": "负载角速度计数据超限,请重启负载" + }, + "fpv_tip_0x14020038": { + "de": "Nutzlast-Geschwindigkeitsdatenfehler. Nutzlast neu starten", + "en": "Payload tachometer data error. Restart payload", + "es": "Error de datos del tacómetro del instrumento. Reinicia el instrumento", + "fr": "Erreur de données du tachymètre de la charge utile. Redémarrer la charge utile", + "it": "", + "ja": "ペイロードタコメーター データエラー。ペイロードを再起動してください", + "ko": "페이로드 태코미터 데이터 오류. 페이로드 재시작 필요", + "pt": "", + "ru": "Ошибка данных тахометра. Перезапустите дрон", + "tr": "Yük takometre verisi hatası. Yükü yeniden başlatın", + "zh": "负载角速度计数据异常,请重启负载" + }, + "fpv_tip_0x14020039": { + "de": "Nutzlast-Beschleunigungsdaten ungültig. Nutzlast neu starten", + "en": "Payload accelerometer data invalid. Restart payload", + "es": "Datos del acelerómetro del instrumento no válidos. Reinicia el instrumento", + "fr": "Données de l'accéléromètre de la charge utile invalides. Redémarrer la charge utile", + "it": "", + "ja": "ペイロード加速度計データ無効。ペイロードを再起動してください", + "ko": "유효하지 않은 페이로드 가속도계 데이터. 페이로드 재시작 필요", + "pt": "", + "ru": "Недействительные данные акселерометра. Перезапустите полезную нагрузку", + "tr": "Yük ivmeölçer verisi geçersiz. Yükü yeniden başlatın", + "zh": "负载加速度计数据非法,请重启负载" + }, + "fpv_tip_0x1402003A": { + "de": "Nutzlast-Beschleunigungsdaten nicht aktualisiert. Nutzlast neu starten", + "en": "Payload accelerometer data not updated. Restart payload", + "es": "Datos del acelerómetro de la carga no actualizados. Reinicia el instrumento", + "fr": "Données de l'accéléromètre de la charge utile non mises à jour. Redémarrer la charge utile", + "it": "", + "ja": "ペイロード加速度計データ未更新。ペイロードを再起動してください", + "ko": "페이로드 가속도계 데이터 업데이트 안 됨. 페이로드 재시작 필요", + "pt": "", + "ru": "Данные акселерометра не обновлены. Перезапустите полезную нагрузку", + "tr": "Yük ivmeölçer verisi güncel değil. Yükü yeniden başlatın", + "zh": "负载加速度计数据卡死,请重启负载" + }, + "fpv_tip_0x1402003B": { + "de": "Keine Nutzlast-Beschleunigungsdaten. Nutzlast neu starten", + "en": "No payload accelerometer data. Restart payload", + "es": "No hay datos del acelerómetro del instrumento. Reinicia el instrumento", + "fr": "Aucune données de l'accéléromètre de a charge utile. Redémarrer la charge utile", + "it": "", + "ja": "ペイロード加速度計データなし。ペイロードを再起動してください", + "ko": "페이로드 가속도계 데이터 없음. 페이로드 재시작 필요", + "pt": "", + "ru": "Нет данных акселерометра. Перезапустите полезную нагрузку", + "tr": "Yük ivmeölçer verisi yok. Yükü yeniden başlatın", + "zh": "负载无加速度计数据,请重启负载" + }, + "fpv_tip_0x1402003C": { + "de": "Nutzlast-Beschleunigungsdaten überschreiten das Limit. Nutzlast neu starten", + "en": "Payload accelerometer data exceeds limit. Restart payload", + "es": "Los datos del acelerómetro del instrumento superan el límite. Reinicia el instrumento", + "fr": "Limite de données de l'accéléromètre de la charge utile dépassée. Redémarrer la charge utile", + "it": "", + "ja": "ペイロード加速度計データ制限超過。ペイロードを再起動してください", + "ko": "페이로드 가속도계 데이터 한도 초과. 페이로드 재시작 필요", + "pt": "", + "ru": "Данные акселерометра превышают максимальное значение. Перезапустите полезную нагрузку", + "tr": "Yük ivmeölçer verisi sınırı aşıyor. Yükü yeniden başlatın", + "zh": "负载加速度计数据超限,请重启负载" + }, + "fpv_tip_0x1402003D": { + "de": "Nutzlast-Beschleunigungsdatenfehler. Nutzlast neu starten", + "en": "Payload accelerometer data error. Restart payload", + "es": "Datos del acelerómetro del instrumento no válidos. Reinicia el instrumento", + "fr": "Erreur de données de l'accéléromètre de la charge utile. Redémarrer la charge utile", + "it": "", + "ja": "ペイロード加速度計データエラー。ペイロードを再起動してください", + "ko": "페이로드 가속도계 데이터 오류. 페이로드 재시작 필요", + "pt": "", + "ru": "Ошибка данных акселерометра. Перезапустите полезную нагрузку", + "tr": "Yük ivmeölçer verisi hatası. Yükü yeniden başlatın", + "zh": "负载加速度计数据异常,请重启负载" + }, + "fpv_tip_0x1402003E": { + "de": "Nutzlast-RTK-Datenberechnungsfehler. Fluggerät neu starten", + "en": "Payload RTK data calculation error. Restart aircraft", + "es": "Error de cálculo de datos RTK del instrumento. Reinicia la aeronave", + "fr": "Erreur de calcul des données RTK de la charge utile. Redémarrer l'appareil", + "it": "", + "ja": "ペイロードRTK データ計算エラー。機体を再起動してください", + "ko": "페이로드 RTK 데이터 계산 오류. 기체 재시작 필요", + "pt": "", + "ru": "Ошибка расчета данных RTK. Перезапустите дрон", + "tr": "Yük ivmeölçer verisi hesaplama başarısız. Aracı yeniden başlatın", + "zh": "负载RTK数据解算异常,请重启飞行器" + }, + "fpv_tip_0x14020040": { + "de": "Nutzlast-RTK-Datenfehler. Fluggerät neu starten", + "en": "Payload RTK data error. Restart aircraft", + "es": "Error de datos RTK del instrumento. Reinicia la aeronave", + "fr": "Erreur de données RTK de charge utile. Redémarrer l'appareil", + "it": "", + "ja": "ペイロードRTK データエラー。機体を再起動してください", + "ko": "페이로드 RTK 데이터 오류. 기체 재시작 필요", + "pt": "", + "ru": "Ошибка данных RTK. Перезапустите дрон", + "tr": "Yük RTK verisi hatası. Aracı yeniden başlatın", + "zh": "负载RTK数据异常,请重启飞行器" + }, + "fpv_tip_0x14020041": { + "de": "Nutzlast-RTK-Zeitfehler. Fluggerät neu starten", + "en": "Payload RTK time error. Restart aircraft", + "es": "Error de la hora del RTK del instrumento. Reinicia la aeronave", + "fr": "Erreur de temps du RTK de charge utile. Redémarrer l'appareil", + "it": "", + "ja": "ペイロードRTK タイムエラー。機体を再起動してください", + "ko": "페이로드 RTK 시간 오류. 기체 재시작 필요", + "pt": "", + "ru": "Ошибка времени RTK. Перезапустите дрон", + "tr": "Yük RTK saati hatası. Aracı yeniden başlatın", + "zh": "负载RTK时间异常,请重启飞行器" + }, + "fpv_tip_0x14020042": { + "ar": "", + "de": "Nutzlast-RTK-Daten ungültig. Fluggerät neu starten", + "en": "Payload RTK data invalid. Restart aircraft", + "es": "Datos del RTK del instrumento no válidos. Reinicia la aeronave", + "fr": "Erreur de données RTK de la charge utile. Redémarrer l'appareil", + "id": "", + "it": "", + "ja": "ペイロードRTK データ無効。機体を再起動してください", + "ko": "유효하지 않은 페이로드 RTK 데이터. 기체 재시작 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Недействительные данные RTK. Перезапустите дрон", + "th": "", + "tr": "Yük RTK verisi geçersiz. Aracı yeniden başlatın", + "ug": "", + "vi": "", + "zh": "负载RTK数据无效,请重启飞行器", + "zh-Hant": "" + }, + "fpv_tip_0x14020042_in_the_sky": { + "de": "Nutzlast-RTK-Daten ungültig. Sicherstellen, dass die Suche nach dem Satellitensignal ordnungsgemäß funktioniert, und warten, bis RTK fixiert ist", + "en": "Payload RTK data invalid. Make sure satellite signal searching is normal and wait until RTK is fixed", + "es": "Datos RTK del instrumento no válidos. Asegúrese de que la búsqueda de señal satelital sea normal y espere hasta que RTK esté fijo", + "fr": "Données RTK de nacelles-caméras non valides. Assurez-vous que la recherche du signal satellite est normale et attendez que le RTK soit fixe", + "id": "", + "it": "", + "ja": "搭載RTKデータが無効です。衛星信号捕捉が正常であることを確認し、RTKが修正されるまでお待ちください", + "ko": "페이로드 RTK 데이터가 유효하지 않습니다. 위성 신호 검색이 정상인지 확인하고 RTK가 확정될 때까지 기다려주세요", + "nl": "", + "pl": "", + "pt-PT": "", + "ru": "Данные полезной нагрузки RTK недействительны. Убедитесь, что поиск спутникового сигнала работает без сбоев; дождитесь настройки RTK", + "th": "", + "tr": "Yük RTK verisi geçersiz. Uydu sinyali aramasının normal olduğundan emin olun ve RTK sabitleninceye kadar bekleyin", + "ug": "", + "vi": "", + "zh": "负载RTK数据无效,请确认搜星情况良好,等待恢复", + "zh-Hant": "" + }, + "fpv_tip_0x14030000": { + "en": "扫描模块温度异常", + "zh": "扫描模块温度异常" + }, + "fpv_tip_0x14030001": { + "en": "扫描模块电流异常", + "zh": "扫描模块电流异常" + }, + "fpv_tip_0x14030002": { + "de": "Rotationsgeschwindigkeit des LiDAR-Abtastmoduls fehlerhaft. Fluggerät neu starten.", + "en": "Rotation speed error of LiDAR scanning module. Restart aircraft", + "es": "Error de velocidad de rotación del módulo de escaneado LiDAR. Reinicie la aeronave", + "fr": "Erreur de vitesse de rotation du module de numérisation LiDAR. Redémarrez l’appareil", + "it": "", + "ja": "LiDARスキャンモジュールの回転速度エラー。機体を再起動してください", + "ko": "LiDAR 스캐닝 모듈 의 회전 속도 오류입니다. 기체 재시작", + "ru": "Ошибка скорости вращения модуля сканирования LiDAR. Перезапустите дрон", + "tr": "LiDAR tarama modülünün dönüş hızı hatası. Hava aracını yeniden başlatın", + "zh": "激光雷达扫描模块转速异常,请重启飞行器" + }, + "fpv_tip_0x14030003": { + "de": "Fehler bei der Eigenprüfung des LiDAR-Abtastmoduls. Fluggerät neu starten.", + "en": "Auto Check error of LiDAR scanning module. Restart aircraft", + "es": "Error de comprobación automática del módulo de escaneado LiDAR. Reinicie la aeronave", + "fr": "Erreur de vérification automatique du module de numérisation LiDAR. Redémarrez l’appareil", + "it": "", + "ja": "LiDARスキャンモジュールの自動チェックエラー。機体を再起動してください", + "ko": "LiDAR 스캐닝 모듈의 자동 확인 오류입니다. 기체 재시작", + "ru": "Ошибка автоматической проверки модуля сканирования LiDAR. Перезапустите дрон", + "tr": "LiDAR tarama modülünün Otomatik Kontrol hatası. Hava aracını yeniden başlatın", + "zh": "激光雷达扫描模块自检异常,请重启飞行器" + }, + "fpv_tip_0x1403000B": { + "de": "Radarabtastmodul wird kalibriert. Fluggerät nicht bewegen", + "en": "Calibrating radar scanning module. Do not move aircraft", + "es": "Calibrando módulo de escaneado del radar. No mueva la aeronave", + "fr": "Étalonnage du module de balayage radar. Ne déplacez pas l’appareil", + "ja": "レーダースキャンモジュールのキャリブレーション中です。機体を動かさないでください", + "ko": "레이더 스캐닝 모듈 캘리브레이션 중입니다. 기체를 움직이지 마세요", + "ru": "Калибровка модуля радиолокационного сканирования. Не перемещайте дрон", + "tr": "Radar tarama modülünün kalibrasyonu yapılıyor. Hava aracını hareket ettirmeyin", + "zh": "雷达扫描模块校准中,请勿移动飞行器" + }, + "fpv_tip_0x14040000": { + "en": "接收器高压异常", + "zh": "接收器高压异常" + }, + "fpv_tip_0x14040001": { + "en": "接收器温度异常", + "zh": "接收器温度异常" + }, + "fpv_tip_0x14040002": { + "en": "激光器温度异常", + "zh": "激光器温度异常" + }, + "fpv_tip_0x14050000": { + "en": "PPS同步异常", + "zh": "PPS同步异常" + }, + "fpv_tip_0x14050002": { + "en": "PPS同步异常", + "zh": "PPS同步异常" + }, + "fpv_tip_0x14050003": { + "en": "时间同步精度低", + "zh": "时间同步精度低" + }, + "fpv_tip_0x14810040": { + "de": "LiDAR-Temperatur zu hoch/niedrig", + "en": "LiDAR temperature too high/low", + "es": "Temperatura del LiDAR demasiado alta/baja", + "fr": "Température LiDAR trop faible/élevée", + "it": "", + "ja": "LiDAR温度が高温/低温", + "ko": "LiDAR 온도 너무 높음/낮음", + "pt": "", + "ru": "Слишком высокая/низкая температура лидара", + "tr": "LiDAR sıcaklığı çok yüksek/düşük", + "zh": "激光雷达温度过高/过低" + }, + "fpv_tip_0x14810080": { + "de": "LiDAR-Spannung zu hoch/niedrig", + "en": "LiDAR voltage too high/low", + "es": "Voltaje del LiDAR demasiado alto/bajo", + "fr": "Tension LiDAR trop basse/élevée", + "it": "", + "ja": "LiDAR電圧が高圧/低圧", + "ko": "LiDAR 전압 너무 높음/낮음", + "pt": "", + "ru": "Слишком высокое/низкое напряжение лидара", + "tr": "LiDAR gerilimi çok yüksek/düşük", + "zh": "激光雷达电压过高/过低" + }, + "fpv_tip_0x148100C0": { + "es": "Error del motor del LiDAR" + }, + "fpv_tip_0x148100c0": { + "de": "LiDAR-Motorfehler", + "en": "LiDAR motor error", + "es": "Error del motor LiDAR", + "fr": "Erreur du moteur LiDAR", + "it": "", + "ja": "LiDAR モーターエラー", + "ko": "LiDAR 모터 오류", + "pt": "", + "ru": "Ошибка мотора лидара", + "tr": "LiDAR motor hatası", + "zh": "激光雷达电机异常" + }, + "fpv_tip_0x14810100": { + "de": "Warnung: LiDAR-Nutzungsdauer", + "en": "LiDAR lifecycle warning", + "es": "Advertencia del ciclo de vida de LiDAR", + "fr": "Avertissement du cycle de vie LiDAR", + "it": "", + "ja": "LiDAR製品寿命警告", + "ko": "LiDAR 수명 경고", + "pt": "", + "ru": "Предупреждение о жизненном цикле лидара", + "tr": "LiDAR yaşam döngüsü uyarısı", + "zh": "激光雷达寿命预警" + }, + "fpv_tip_0x14810140": { + "de": "LiDAR-Systemfehler", + "en": "LiDAR system error", + "es": "Error del sistema LiDAR", + "fr": "Erreur du système LiDAR", + "it": "", + "ja": "LiDAR システムエラー", + "ko": "LiDAR 시스템 오류", + "pt": "", + "ru": "Ошибка системы лидара", + "tr": "LiDAR sistem hatası", + "zh": "激光雷达系统异常" + }, + "fpv_tip_0x15000020": { + "de": "Radartemperatur zu niedrig. Überprüfen, ob Umgebungstemperatur im normalen Bereich liegt", + "en": "Radar temperature too low. Check and make sure temperature of current environment is within normal range", + "es": "Temperatura del radar demasiado baja. Comprueba la temperatura del entorno actual y asegúrate de que se encuentre dentro del rango normal", + "fr": "Température radar trop faible. Vérifiez que la température de l'environnement se situe dans une plage normale", + "ja": "レーダーが低温。現在の環境が通常の温度範囲内であることを確認してください", + "ko": "레이더 온도 너무 낮음. 현 비행 환경의 온도가 정상 범위 내에 있는지 확인 필요", + "ru": "Слишком низкая температура радара. Убедитесь, что температура окружающей среды находится в пределах нормы", + "tr": "Radar sıcaklığı çok düşük. Mevcut ortam sıcaklığını kontrol edin ve normal aralıkta olduğundan emin olun", + "zh": "雷达温度过低,请确认工作环境温度是否过低" + }, + "fpv_tip_0x15000021": { + "de": "Radar überhitzt. Überprüfen, ob Umgebungstemperatur im normalen Bereich liegt", + "en": "Radar overheated. Check and make sure temperature of current environment is within normal range", + "es": "Radar sobrecalentado. Comprueba la temperatura del entorno actual y asegúrate de que se encuentre dentro del rango normal", + "fr": "Radar en surchauffe. Vérifiez que la température de l'environnement se situe dans une plage normale", + "ja": "レーダーが高温。現在の環境が通常の温度範囲内であることを確認してください", + "ko": "레이더 과열. 현 비행 환경의 온도가 정상 범위 내에 있는지 확인 필요", + "ru": "Перегрев радара. Убедитесь, что температура окружающей среды находится в пределах нормы", + "tr": "Radar aşırı ısındı. Mevcut ortam sıcaklığını kontrol edin ve normal aralıkta olduğundan emin olun", + "zh": "雷达温度过高,请确认工作环境温度是否过高" + }, + "fpv_tip_0x15010020": { + "de": "Fehler: Interne Radar-Energieversorgung. Radar neu starten", + "en": "Radar internal power supply error. Restart radar", + "es": "Error de la fuente de alimentación interna del radar. Reinicia el radar", + "fr": "Erreur d'alimentation interne du radar. Redémarrer le radar", + "ja": "レーダー内部電源供給エラー。レーダーを再起動してください", + "ko": "레이더 내부 전력 공급 오류. 레이더 재시작 필요", + "ru": "Ошибка внутреннего источника питания радара. Перезапустите радар", + "tr": "Radar dahili güç kaynağı hatası. Radarı yeniden başlatın", + "zh": "雷达内部供电异常,请重启雷达负载" + }, + "fpv_tip_0x15010021": { + "de": "Fehler: Interne Radar-Energieversorgung. Radar neu starten", + "en": "Radar internal power supply error. Restart radar", + "es": "Error de la fuente de alimentación interna del radar. Reinicia el radar", + "fr": "Erreur d'alimentation interne du radar. Redémarrer le radar", + "ja": "レーダー内部電源供給エラー。レーダーを再起動してください", + "ko": "레이더 내부 전력 공급 오류. 레이더 재시작 필요", + "ru": "Ошибка внутреннего источника питания радара. Перезапустите радар", + "tr": "Radar dahili güç kaynağı hatası. Radarı yeniden başlatın", + "zh": "雷达内部供电异常,请重启雷达负载" + }, + "fpv_tip_0x15010022": { + "de": "Fehler: Interne Radar-Energieversorgung. Radar neu starten", + "en": "Radar internal power supply error. Restart radar", + "es": "Error de la fuente de alimentación interna del radar. Reinicia el radar", + "fr": "Erreur d'alimentation interne du radar. Redémarrer le radar", + "ja": "レーダー内部電源供給エラー。レーダーを再起動してください", + "ko": "레이더 내부 전력 공급 오류. 레이더 재시작 필요", + "ru": "Ошибка внутреннего источника питания радара. Перезапустите радар", + "tr": "Radar dahili güç kaynağı hatası. Radarı yeniden başlatın", + "zh": "雷达内部供电异常,请重启雷达负载" + }, + "fpv_tip_0x15010023": { + "de": "Fehler: Interne Radar-Energieversorgung. Radar neu starten", + "en": "Radar internal power supply error. Restart radar", + "es": "Error de la fuente de alimentación interna del radar. Reinicia el radar", + "fr": "Erreur d'alimentation interne du radar. Redémarrer le radar", + "ja": "レーダー内部電源供給エラー。レーダーを再起動してください", + "ko": "레이더 내부 전력 공급 오류. 레이더 재시작 필요", + "ru": "Ошибка внутреннего источника питания радара. Перезапустите радар", + "tr": "Radar dahili güç kaynağı hatası. Radarı yeniden başlatın", + "zh": "雷达内部供电异常,请重启雷达负载" + }, + "fpv_tip_0x15020020": { + "de": "Radarmotorfehler. Überprüfen, ob Radarmotor blockiert ist", + "en": "Radar motor error. Check whether radar motor is blocked", + "es": "Error del motor del radar. Comprueba si el motor del radar está bloqueado", + "fr": "Erreur du moteur du radar. Vérifier si le moteur du radar est bloqué", + "ja": "レーダーモーター エラー。レーダーモーターがブロックされていないか確認してください", + "ko": "레이더 모터 오류. 레이더 모터가 막혔는지 확인 필요", + "ru": "Сбой мотора радара. Проверьте, не заблокирован ли мотор радара", + "tr": "Radar motoru hatası. Radar motorunun engellenmediğinden emin olun", + "zh": "雷达电机异常,请检查雷达是否卡转" + }, + "fpv_tip_0x15020021": { + "de": "Radarmotorfehler. Überprüfen, ob Radarmotor blockiert ist", + "en": "Radar motor error. Check whether radar motor is blocked", + "es": "Error del motor del radar. Comprueba si el motor del radar está bloqueado", + "fr": "Erreur du moteur du radar. Vérifier si le moteur du radar est bloqué", + "ja": "レーダーモーター エラー。レーダーモーターがブロックされていないか確認してください", + "ko": "레이더 모터 오류. 레이더 모터가 막혔는지 확인 필요", + "ru": "Сбой мотора радара. Проверьте, не заблокирован ли мотор радара", + "tr": "Radar motoru hatası. Radar motorunun engellenmediğinden emin olun", + "zh": "雷达电机异常,请检查雷达是否卡转" + }, + "fpv_tip_0x15020022": { + "de": "Radarmotorfehler. Überprüfen, ob Radarmotor blockiert ist", + "en": "Radar motor error. Check whether radar motor is blocked", + "es": "Error del motor del radar. Comprueba si el motor del radar está bloqueado", + "fr": "Erreur du moteur du radar. Vérifier si le moteur du radar est bloqué", + "ja": "レーダーモーター エラー。レーダーモーターがブロックされていないか確認してください", + "ko": "레이더 모터 오류. 레이더 모터가 막혔는지 확인 필요", + "ru": "Сбой мотора радара. Проверьте, не заблокирован ли мотор радара", + "tr": "Radar motoru hatası. Radar motorunun engellenmediğinden emin olun", + "zh": "雷达电机异常,请检查雷达是否卡转" + }, + "fpv_tip_0x15020023": { + "de": "Radarerkennungsfehler. Firmware-Version überprüfen", + "en": "Radar detection capability error. Check firmware version", + "es": "Error de la capacidad de detección del radar. Comprueba la versión del firmware", + "fr": "Erreur de capacité de détection du radar. Vérifier la version du firmware", + "ja": "レーダー検知機能エラー。ファームウェアのバージョンを確認してください", + "ko": "레이더 감지 성능 오류. 펌웨어 버전 확인 필요", + "ru": "Ошибка функции обнаружения радара. Проверьте версию прошивки", + "tr": "Radar tespit yeteneği hatası. Yazılım sürümünü kontrol edin", + "zh": "雷达感知功能异常,请检查固件版本" + }, + "fpv_tip_0x15030020": { + "ar": "", + "de": "Radarkommunikationsverbindung instabil. Umgebung auf starke Störungen prüfen", + "en": "Radar communication link unstable. Check for strong interference in the surrounding area", + "es": "Enlace de comunicación del radar inestable. Comprueba si hay fuertes interferencias en el área circundante", + "fr": "Liaison de communication radar instable. Vérifier la présence de fortes interférences dans la zone alentour", + "id": "", + "it": "", + "ja": "レーダー通信リンクが不安定。周囲に強い干渉がないことを確認してください", + "ko": "레이더 통신 링크 불안정. 주변 신호 간섭이 강한지 확인 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Радиолокационная связь нестабильна. Убедитесь, что вокруг нет сильных помех", + "th": "", + "tr": "Radar iletişim bağlantısı istikrarsız. Çevrede güçlü müdahale olup olmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "雷达链路不稳定,请检查周边是否存在强力干扰", + "zh-Hant": "" + }, + "fpv_tip_0x15030021": { + "ar": "", + "de": "Radarkommunikationsverbindung instabil. Umgebung auf starke Störungen prüfen", + "en": "Radar communication link unstable. Check for strong interference in the surrounding area", + "es": "Enlace de comunicación del radar inestable. Comprueba si hay fuertes interferencias en el área circundante", + "fr": "Liaison de communication radar instable. Vérifier la présence de fortes interférences dans la zone alentour", + "id": "", + "it": "", + "ja": "レーダー通信リンクが不安定。周囲に強い干渉がないことを確認してください", + "ko": "레이더 통신 링크 불안정. 주변 신호 간섭이 강한지 확인 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Радиолокационная связь нестабильна. Убедитесь, что вокруг нет сильных помех", + "th": "", + "tr": "Radar iletişim bağlantısı istikrarsız. Çevrede güçlü müdahale olup olmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "雷达链路不稳定,请检查周边是否存在强力干扰", + "zh-Hant": "" + }, + "fpv_tip_0x15030022": { + "ar": "", + "de": "Radarkommunikationsverbindung instabil. Umgebung auf starke Störungen prüfen", + "en": "Radar communication link unstable. Check for strong interference in the surrounding area", + "es": "Enlace de comunicación del radar inestable. Comprueba si hay fuertes interferencias en el área circundante", + "fr": "Liaison de communication radar instable. Vérifier la présence de fortes interférences dans la zone alentour", + "id": "", + "it": "", + "ja": "レーダー通信リンクが不安定。周囲に強い干渉がないことを確認してください", + "ko": "레이더 통신 링크 불안정. 주변 신호 간섭이 강한지 확인 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Радиолокационная связь нестабильна. Убедитесь, что вокруг нет сильных помех", + "th": "", + "tr": "Radar iletişim bağlantısı istikrarsız. Çevrede güçlü müdahale olup olmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "雷达链路不稳定,请检查周边是否存在强力干扰", + "zh-Hant": "" + }, + "fpv_tip_0x15030023": { + "ar": "", + "de": "Zeitüberschreitung beim Starten des Radars. Umgebung auf starke Störungen prüfen", + "en": "Starting radar timed out. Check for strong interference in the surrounding area", + "es": "Tiempo de espera de inicio del radar agotado. Comprueba si hay fuertes interferencias en el área circundante", + "fr": "Délai de démarrage radar expiré. Vérifier la présence de fortes interférences dans la zone alentour", + "id": "", + "it": "", + "ja": "レーダー起動 時間切れ。周囲に強い干渉源がないことを確認してください", + "ko": "레이더 시작 시간 초과. 주변 신호 간섭이 강한지 확인 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Истекло время ожидания запуска радара. Убедитесь, что вокруг нет сильных помех", + "th": "", + "tr": "Radarın başlatılması zaman aşımına uğradı. Çevrede güçlü müdahale olup olmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "雷达启动超时,请检查周边是否存在强力干扰", + "zh-Hant": "" + }, + "fpv_tip_0x15030024": { + "ar": "", + "de": "Radarkommunikationsverbindung instabil. Umgebung auf starke Störungen prüfen", + "en": "Radar communication link unstable. Check for strong interference in the surrounding area", + "es": "Enlace de comunicación del radar inestable. Comprueba si hay fuertes interferencias en el área circundante", + "fr": "Liaison de communication radar instable. Vérifier la présence de fortes interférences dans la zone alentour", + "id": "", + "it": "", + "ja": "レーダー通信リンクが不安定。周囲に強い干渉がないことを確認してください", + "ko": "레이더 통신 링크 불안정. 주변 신호 간섭이 강한지 확인 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Радиолокационная связь нестабильна. Убедитесь, что вокруг нет сильных помех", + "th": "", + "tr": "Radar iletişim bağlantısı istikrarsız. Çevrede güçlü müdahale olup olmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "雷达通信链路不稳定,请检查周边是否存在强力干扰", + "zh-Hant": "" + }, + "fpv_tip_0x15030025": { + "ar": "", + "de": "Radarkommunikationsverbindung instabil. Umgebung auf starke Störungen prüfen", + "en": "Radar communication link unstable. Check for strong interference in the surrounding area", + "es": "Enlace de comunicación del radar inestable. Comprueba si hay fuertes interferencias en el área circundante", + "fr": "Liaison de communication radar instable. Vérifier la présence de fortes interférences dans la zone alentour", + "id": "", + "it": "", + "ja": "レーダー通信リンクが不安定。周囲に強い干渉がないことを確認してください", + "ko": "레이더 통신 링크 불안정. 주변 신호 간섭이 강한지 확인 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Радиолокационная связь нестабильна. Убедитесь, что вокруг нет сильных помех", + "th": "", + "tr": "Radar iletişim bağlantısı istikrarsız. Çevrede güçlü müdahale olup olmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "雷达通信链路不稳定,请检查周边是否存在强力干扰", + "zh-Hant": "" + }, + "fpv_tip_0x15030026": { + "ar": "", + "de": "Radarkommunikationsverbindung instabil. Umgebung auf starke Störungen prüfen", + "en": "Radar communication link unstable. Check for strong interference in the surrounding area", + "es": "Enlace de comunicación del radar inestable. Comprueba si hay fuertes interferencias en el área circundante", + "fr": "Liaison de communication radar instable. Vérifier la présence de fortes interférences dans la zone alentour", + "id": "", + "it": "", + "ja": "レーダー通信リンクが不安定。周囲に強い干渉がないことを確認してください", + "ko": "레이더 통신 링크 불안정. 주변 신호 간섭이 강한지 확인 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Радиолокационная связь нестабильна. Убедитесь, что вокруг нет сильных помех", + "th": "", + "tr": "Radar iletişim bağlantısı istikrarsız. Çevrede güçlü müdahale olup olmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "雷达通信链路不稳定,请检查周边是否存在强力干扰", + "zh-Hant": "" + }, + "fpv_tip_0x15030028": { + "en": "%index radar cable error. Obstacle avoidance and altitude stabilization unavailable", + "zh": "%index雷达线材异常,避障定高功能失效" + }, + "fpv_tip_0x15040020": { + "de": "Radarmotorfehler. Überprüfen, ob Radarmotor blockiert ist", + "en": "Radar motor error. Check whether radar motor is blocked", + "es": "Error del motor del radar. Comprueba si el motor del radar está bloqueado", + "fr": "Erreur du moteur du radar. Vérifier si le moteur du radar est bloqué", + "ja": "レーダーモーター エラー。レーダーモーターがブロックされていないか確認してください", + "ko": "레이더 모터 오류. 레이더 모터가 막혔는지 확인 필요", + "ru": "Сбой мотора радара. Проверьте, не заблокирован ли мотор радара", + "tr": "Radar motoru hatası. Radar motorunun engellenmediğinden emin olun", + "zh": "雷达电机异常,请检查雷达是否卡转" + }, + "fpv_tip_0x15040021": { + "de": "Radarmotorfehler. Überprüfen, ob Radarmotor blockiert ist", + "en": "Radar motor error. Check whether radar motor is blocked", + "es": "Error del motor del radar. Comprueba si el motor del radar está bloqueado", + "fr": "Erreur du moteur du radar. Vérifier si le moteur du radar est bloqué", + "ja": "レーダーモーター エラー。レーダーモーターがブロックされていないか確認してください", + "ko": "레이더 모터 오류. 레이더 모터가 막혔는지 확인 필요", + "ru": "Сбой мотора радара. Проверьте, не заблокирован ли мотор радара", + "tr": "Radar motoru hatası. Radar motorunun engellenmediğinden emin olun", + "zh": "雷达电机异常,请检查雷达是否卡转" + }, + "fpv_tip_0x15060020": { + "de": "Radarmotorfehler. Überprüfen, ob Radarmotor blockiert ist", + "en": "Radar motor error. Check whether radar motor is blocked", + "es": "Error del motor del radar. Comprueba si el motor del radar está bloqueado", + "fr": "Erreur du moteur du radar. Vérifier si le moteur du radar est bloqué", + "ja": "レーダーモーター エラー。レーダーモーターがブロックされていないか確認してください", + "ko": "레이더 모터 오류. 레이더 모터가 막혔는지 확인 필요", + "ru": "Сбой мотора радара. Проверьте, не заблокирован ли мотор радара", + "tr": "Radar motoru hatası. Radar motorunun engellenmediğinden emin olun", + "zh": "雷达电机异常,请检查雷达是否卡转" + }, + "fpv_tip_0x15070020": { + "ar": "", + "de": "Radarkommunikationsverbindung instabil. Umgebung auf starke Störungen prüfen", + "en": "Radar communication link unstable. Check for strong interference in the surrounding area", + "es": "Enlace de comunicación del radar inestable. Comprueba si hay fuertes interferencias en el área circundante", + "fr": "Liaison de communication radar instable. Vérifier la présence de fortes interférences dans la zone alentour", + "id": "", + "it": "", + "ja": "レーダー通信リンクが不安定。周囲に強い干渉がないことを確認してください", + "ko": "레이더 통신 링크 불안정. 주변 신호 간섭이 강한지 확인 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Радиолокационная связь нестабильна. Убедитесь, что вокруг нет сильных помех", + "th": "", + "tr": "Radar iletişim bağlantısı istikrarsız. Çevrede güçlü müdahale olup olmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "雷达通信链路不稳定,请检查周边是否存在强力干扰", + "zh-Hant": "" + }, + "fpv_tip_0x15080020": { + "de": "Radar überhitzt. Überprüfen, ob Umgebungstemperatur im normalen Bereich liegt", + "en": "Radar overheated. Check and make sure temperature of current environment is within normal range", + "es": "Radar sobrecalentado. Comprueba la temperatura del entorno actual y asegúrate de que se encuentre dentro del rango normal", + "fr": "Radar en surchauffe. Vérifiez que la température de l'environnement se situe dans une plage normale", + "ja": "レーダーが高温。現在の環境が通常の温度範囲内であることを確認してください", + "ko": "레이더 과열. 현 비행 환경의 온도가 정상 범위 내에 있는지 확인 필요", + "ru": "Перегрев радара. Убедитесь, что температура окружающей среды находится в пределах нормы", + "tr": "Radar aşırı ısındı. Mevcut ortam sıcaklığını kontrol edin ve normal aralıkta olduğundan emin olun", + "zh": "雷达温度过高,请确认工作环境温度是否过高" + }, + "fpv_tip_0x15080021": { + "ar": "", + "de": "", + "en": "Radar processor overheated. Obstacle avoidance and altitude stabilization affected", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "雷达芯片温度过高,避障定高性能衰退", + "zh-Hant": "" + }, + "fpv_tip_0x15080022": { + "ar": "", + "de": "", + "en": "Radar processor overheated. Obstacle avoidance and altitude stabilization affected", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "雷达芯片温度过高,避障定高性能衰退", + "zh-Hant": "" + }, + "fpv_tip_0x15090020": { + "de": "Radar überhitzt. Überprüfen, ob Umgebungstemperatur im normalen Bereich liegt", + "en": "Radar overheated. Check and make sure temperature of current environment is within normal range", + "es": "Radar sobrecalentado. Comprueba la temperatura del entorno actual y asegúrate de que se encuentre dentro del rango normal", + "fr": "Radar en surchauffe. Vérifiez que la température de l'environnement se situe dans une plage normale", + "ja": "レーダーが高温。現在の環境が通常の温度範囲内であることを確認してください", + "ko": "레이더 과열. 현 비행 환경의 온도가 정상 범위 내에 있는지 확인 필요", + "ru": "Перегрев радара. Убедитесь, что температура окружающей среды находится в пределах нормы", + "tr": "Radar aşırı ısındı. Mevcut ortam sıcaklığını kontrol edin ve normal aralıkta olduğundan emin olun", + "zh": "雷达温度过高,请确认工作环境温度是否过高" + }, + "fpv_tip_0x15090021": { + "de": "Radarfehler. Hindernisvermeidung nicht verfügbar", + "en": "Radar error. Obstacle avoidance unavailable", + "es": "Error de radar. Sistema anticolisión no disponible", + "fr": "Erreur radar. Évitement d'obstacles non disponible", + "ja": "レーダーエラー。障害物回避を利用できません", + "ko": "레이더 오류. 장애물 회피를 사용할 수 없습니다", + "ru": "Ошибка радара. Обход препятствий недоступен", + "tr": "Radar hatası. Engellerden kaçınma kullanılamıyor", + "zh": "雷达功能异常,避障功能失效" + }, + "fpv_tip_0x15100020": { + "ar": "", + "de": "Radarkommunikationsverbindung instabil. Umgebung auf starke Störungen prüfen", + "en": "Radar communication link unstable. Check for strong interference in the surrounding area", + "es": "Enlace de comunicación del radar inestable. Comprueba si hay fuertes interferencias en el área circundante", + "fr": "Liaison de communication radar instable. Vérifier la présence de fortes interférences dans la zone alentour", + "id": "", + "it": "", + "ja": "レーダー通信リンクが不安定。周囲に強い干渉がないことを確認してください", + "ko": "레이더 통신 링크 불안정. 주변 신호 간섭이 강한지 확인 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Радиолокационная связь нестабильна. Убедитесь, что вокруг нет сильных помех", + "th": "", + "tr": "Radar iletişim bağlantısı istikrarsız. Çevrede güçlü müdahale olup olmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "雷达通信链路不稳定,请检查周边是否存在强力干扰", + "zh-Hant": "" + }, + "fpv_tip_0x15100021": { + "ar": "", + "de": "Radarkommunikationsverbindung instabil. Umgebung auf starke Störungen prüfen", + "en": "Radar communication link unstable. Check for strong interference in the surrounding area", + "es": "Enlace de comunicación del radar inestable. Comprueba si hay fuertes interferencias en el área circundante", + "fr": "Liaison de communication radar instable. Vérifier la présence de fortes interférences dans la zone alentour", + "id": "", + "it": "", + "ja": "レーダー通信リンクが不安定。周囲に強い干渉がないことを確認してください", + "ko": "레이더 통신 링크 불안정. 주변 신호 간섭이 강한지 확인 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Радиолокационная связь нестабильна. Убедитесь, что вокруг нет сильных помех", + "th": "", + "tr": "Radar iletişim bağlantısı istikrarsız. Çevrede güçlü müdahale olup olmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "雷达通信链路不稳定,请检查周边是否存在强力干扰", + "zh-Hant": "" + }, + "fpv_tip_0x15100022": { + "ar": "", + "de": "Radarkommunikationsverbindung instabil. Umgebung auf starke Störungen prüfen", + "en": "Radar communication link unstable. Check for strong interference in the surrounding area", + "es": "Enlace de comunicación del radar inestable. Comprueba si hay fuertes interferencias en el área circundante", + "fr": "Liaison de communication radar instable. Vérifier la présence de fortes interférences dans la zone alentour", + "id": "", + "it": "", + "ja": "レーダー通信リンクが不安定。周囲に強い干渉がないことを確認してください", + "ko": "레이더 통신 링크 불안정. 주변 신호 간섭이 강한지 확인 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Радиолокационная связь нестабильна. Убедитесь, что вокруг нет сильных помех", + "th": "", + "tr": "Radar iletişim bağlantısı istikrarsız. Çevrede güçlü müdahale olup olmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "雷达通信链路不稳定,请检查周边是否存在强力干扰", + "zh-Hant": "" + }, + "fpv_tip_0x15110020": { + "de": "Radarmotorfehler. Überprüfen, ob Radarmotor blockiert ist", + "en": "Radar motor error. Check whether radar motor is blocked", + "es": "Error del motor del radar. Comprueba si el motor del radar está bloqueado", + "fr": "Erreur du moteur du radar. Vérifier si le moteur du radar est bloqué", + "ja": "レーダーモーター エラー。レーダーモーターがブロックされていないか確認してください", + "ko": "레이더 모터 오류. 레이더 모터가 막혔는지 확인 필요", + "ru": "Сбой мотора радара. Проверьте, не заблокирован ли мотор радара", + "tr": "Radar motoru hatası. Radar motorunun engellenmediğinden emin olun", + "zh": "雷达电机异常,请检查雷达是否卡转" + }, + "fpv_tip_0x15130021": { + "de": "Radarerkennungsfehler. Firmware-Version überprüfen", + "en": "Radar detection capability error. Check firmware version", + "es": "Error de la capacidad de detección del radar. Comprueba la versión del firmware", + "fr": "Erreur de capacité de détection du radar. Vérifier la version du firmware", + "ja": "レーダー検知機能エラー。ファームウェアのバージョンを確認してください", + "ko": "레이더 감지 성능 오류. 펌웨어 버전 확인 필요", + "ru": "Ошибка функции обнаружения радара. Проверьте версию прошивки", + "tr": "Radar tespit yeteneği hatası. Yazılım sürümünü kontrol edin", + "zh": "雷达感知功能异常,请检查固件版本" + }, + "fpv_tip_0x15140020": { + "de": "Radar-RF-Taktfehler. Sofort zurückkehren und Radar überprüfen", + "en": "Radar RF clock error. Return to home immediately and check radar", + "es": "Error del reloj de RF del radar. Regresa al punto de origen de inmediato y comprueba el radar", + "fr": "Erreur de l'horloge RF du radar. Retourner au point de départ immédiatement et vérifier le radar", + "ja": "レーダーRFクロック エラー。直ちに帰還して、レーダーを確認してください", + "ko": "레이더 RF 시계 오류. 즉시 RTH 실행 및 레이더 확인 필요", + "ru": "Отклонение температуры РЧ-платы радара. Вернитесь домой и проверьте радар", + "tr": "Radar RF saat hatası. Hemen eve geri dönün ve radarı kontrol edin", + "zh": "雷达射频时钟异常,请立即返航并检查雷达负载" + }, + "fpv_tip_0x15220020": { + "ar": "", + "de": "", + "en": "Backward and downward radar disconnected. Restart aircraft or check and replace radar", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "后下雷达断连,请重启或检查更换", + "zh-Hant": "" + }, + "fpv_tip_0x15300020": { + "de": "Radarerkennungsfehler. Firmware-Version überprüfen", + "en": "Radar detection capability error. Check firmware version", + "es": "Error de capacidad de detección del radar. Comprueba la versión de firmware", + "fr": "Erreur de capacité de détection du radar. Vérifier la version du firmware", + "ja": "レーダー検知機能エラー。ファームウェアのバージョンを確認してください", + "ko": "레이더 감지 성능 오류. 펌웨어 버전 확인 필요", + "ru": "Ошибка функции обнаружения радара. Проверьте версию прошивки", + "tr": "Radar tespit yeteneği hatası. Yazılım sürümünü kontrol edin", + "zh": "雷达感知功能异常,请检查固件版本" + }, + "fpv_tip_0x15300021": { + "de": "Radarerkennungsfehler. Firmware-Version überprüfen", + "en": "Radar detection capability error. Check firmware version", + "es": "Error de capacidad de detección del radar. Comprueba la versión de firmware", + "fr": "Erreur de capacité de détection du radar. Vérifier la version du firmware", + "ja": "レーダー検知機能エラー。ファームウェアのバージョンを確認してください", + "ko": "레이더 감지 성능 오류. 펌웨어 버전 확인 필요", + "ru": "Ошибка функции обнаружения радара. Проверьте версию прошивки", + "tr": "Radar tespit yeteneği hatası. Yazılım sürümünü kontrol edin", + "zh": "雷达感知功能异常,请检查固件版本" + }, + "fpv_tip_0x15300022": { + "de": "Radarerkennungsfehler. Firmware-Version überprüfen", + "en": "Radar detection capability error. Check firmware version", + "es": "Error de capacidad de detección del radar. Comprueba la versión de firmware", + "fr": "Erreur de capacité de détection du radar. Vérifier la version du firmware", + "ja": "レーダー検知機能エラー。ファームウェアのバージョンを確認してください", + "ko": "레이더 감지 성능 오류. 펌웨어 버전 확인 필요", + "ru": "Ошибка функции обнаружения радара. Проверьте версию прошивки", + "tr": "Radar tespit yeteneği hatası. Yazılım sürümünü kontrol edin", + "zh": "雷达感知功能异常,请检查固件版本" + }, + "fpv_tip_0x16000001": { + "de": "Flugregler überlastet. Start nicht möglich. Fluggerät neu starten", + "en": "Flight controller overloaded. Unable to take off. Restart aircraft", + "es": "Controlador de vuelo sobrecargado. No se puede despegar. Reinicia la aeronave", + "fr": "Contrôleur du vol surchargé. Décollage impossible. Redémarrez l\\'appareil", + "ja": "フライトコントローラー過負荷状態。離陸できません。機体を再起動してください", + "ko": "비행 컨트롤러 과부하. 이륙할 수 없습니다. 기체 재시동", + "ru": "Полетный контроллер перегружен. Невозможно выполнить взлет. Перезапустите дрон", + "tr": "Uçuş kumandası aşırı yüklü. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:飞控系统负载高,请重启飞行器" + }, + "fpv_tip_0x16000001_in_the_sky": { + "de": "Flugregler überlastet. Wenn das Problem weiterhin besteht, umgehend mit dem Fluggerät landen", + "en": "Flight controller overloaded. If the issue persists, land aircraft promptly", + "es": "Controlador de vuelo sobrecargado. Si el problema continúa, aterriza la aeronave rápidamente", + "fr": "Contrôleur de vol surchargé. Si le problème persiste, atterrissez immédiatement", + "ja": "フライトコントローラー過負荷状態。問題が解決しない場合は、直ちに機体を着陸させてください", + "ko": "비행 컨트롤러 과부하. 문제가 지속되면 신속히 기체를 착륙하세요", + "ru": "Полетный контроллер перегружен. Если проблема не устранена, приземлите дрон как можно скорее", + "tr": "Uçuş kumandası aşırı yüklü. Sorun devam ederse hemen aracı indirin", + "zh": "飞控系统负载高,如若持续存在请尽快降落" + }, + "fpv_tip_0x16000002": { + "de": "Fehler: Flugdatenschreiber. Bitte an Händler vor Ort oder an DJI Support wenden", + "en": "Flight data recording error. Contact your local dealer or DJI Support", + "es": "Error al grabar los datos de vuelo . Contacta con el distribuidor local o la asistencia técnica de DJI", + "fr": "Erreur d\\'enregistrement des données de vol. Contactez votre revendeur local ou le Service client DJI", + "it": "", + "ja": "飛行データ記録エラー。最寄りの代理店またはDJIサポートにお問い合わせください", + "ko": "비행 데이터 기록 오류. 현지 딜러 또는 DJI 고객지원으로 문의해주세요", + "pt": "", + "ru": "Ошибка записи полетных данных. Свяжитесь с местным представителем или службой поддержки DJI", + "tr": "Uçuş veri kaydı hatası. Bölgenizdeki satıcı veya DJI Destek ile iletişime geçin", + "zh": "飞行数据记录异常,请尽快联系就近代理商或大疆售后服务。" + }, + "fpv_tip_0x16000002_in_the_sky": { + "de": "Anormale Flugdatenaufzeichnung. Sollte diese Warnung fortbestehen, nehmen Sie bitte Kontakt mit dem DJI Support oder Ihrem Händler auf.", + "en": "Flight data record abnorma.If the warning persists, contact your local dealer or DJI Support.", + "es": "Registro de datos de vuelo anómalo. Si la advertencia se sigue mostrando, ponte en contacto con el distribuidor local o la asistencia técnica de DJI.", + "fr": "Historique des données de vol anormal. Si le problème persiste, contactez votre revendeur local ou le service client DJI.", + "ja": "飛行データ記録異常。警告が消えない場合、最寄りの代理店またはDJIサポートにお問い合わせください。", + "ko": "비행 데이터 기록 비정상. 경고가 지속되면 현지 딜러 또는 DJI 고객지원으로 문의해주세요.", + "ru": "Ошибка записи данных полета. Если предупреждение не устранено, обратитесь к местному представителю или в службу поддержки DJI.", + "zh": "飞行数据记录异常,请尽快联系就近代理商或大疆售后服务。" + }, + "fpv_tip_0x16010001": { + "de": "Fehler: Sensorsystem . Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs . Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류 . 기체 재시작 필요", + "ru": "Ошибка системы датчиков . Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x16010001_in_the_sky": { + "de": "Fehler: Sensorsystem . Zum Startpunkt zurückkehren oder landen.", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système de capteurs . Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか、着陸してください", + "ko": "센서 시스템 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков . Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16010005": { + "de": "Initialisierung des Sensorsystems . Bitte warten bis die Initialisierung abgeschlossen ist", + "en": "Sensor system initializing. Wait for initialization to complete", + "es": "Iniciando sistema de sensores. Espera a que se complete el inicio", + "fr": "Initialisation du système de capteurs . Attendez que l\\'initialisation se termine", + "ja": "センサーシステム初期化中。初期化の完了を待ってください", + "ko": "센서 시스템 초기화 중 . 초기화가 완료될 때까지 기다려야 함", + "ru": "Запускается система датчиков . Дождитесь завершения запуска", + "tr": "Sensör sistemi başlatılıyor. Başlatmanın tamamlanmasını bekleyin", + "zh": "传感器系统初始化中,请等待初始化完成" + }, + "fpv_tip_0x16010005_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur du système de capteurs. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか、着陸してください", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16010007": { + "de": "Fehler im Sensorsystem. Fluggerät neu starten.", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicie la aeronave", + "fr": "Erreur du système de capteur. Redémarrer l'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작", + "ru": "Ошибка системы датчика. Перезапустите дрон", + "tr": "Sensör sistemi hatası. Hava aracını yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x16010007_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur du système de capteurs. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか、着陸してください", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x1601000A": { + "de": "Initialisierung des Sensorsystems. Bitte auf Abschluss der Initialisierung warten", + "en": "Sensor system initializing. Wait for initialization to complete", + "es": "Iniciando sistema de sensores. Espera a que se complete el inicio", + "fr": "Initialisation du système de capteurs. Attendez que l\\'initialisation se termine", + "ja": "センサーシステム初期化中。初期化が完了するまでお待ちください", + "ko": "센서 시스템 초기화 중. 초기화가 완료될 때까지 대기", + "ru": "Инициализация системы датчика. Дождитесь завершения инициализации", + "tr": "Sensör sistemi başlatılıyor. Başlatmanın tamamlanmasını bekleyin", + "zh": "传感器系统初始化中,请等待初始化完成" + }, + "fpv_tip_0x1601000A_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x1601000D": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x1601000D_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16010010": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x16010010_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16010013": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x16010013_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16010016": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x16010016_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16010019": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x16010019_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x1601001C": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x1601001C_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x1601001F": { + "de": "Fehler: Sensorsystem . Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs . Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류 . 기체 재시작 필요", + "ru": "Ошибка системы датчиков . Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x1601001F_in_the_sky": { + "de": "Not Applicable. This string has been deleted", + "en": "Not Applicable. This string has been deleted", + "es": "Not Applicable. This string has been deleted", + "fr": "Non applicable. Cette chaîne a été supprimée", + "ja": "該当なし。この文字列は削除されました", + "ko": "해당 없음. 이 문자열은 삭제되었음", + "ru": "Не применимо. Эта строка была удалена", + "tr": "Uygulanamaz. Bu metin silindi", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16010022": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x16010022_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16010025": { + "de": "Hot Swapping wird für das RTK-Modul nicht unterstützt. Start nicht möglich.", + "en": "Hot swapping not supported for RTK module. Unable to take off", + "es": "El intercambio en caliente no es compatible con el módulo RTK. No se puede despegar", + "fr": "Le remplacement à chaud n'est pas pris en charge pour le module RTK. Impossible de décoller", + "ja": "ホットスワップはRTKモジュールではサポートされていません。離陸できません", + "ko": "RTK 모듈에서는 핫 스와핑이 지원되지 않습니다. 이륙 불가", + "ru": "Горячая замена не поддерживается для модуля RTK. Не удается выполнить взлет", + "tr": "RTK modülü için çalışırken değiştirme desteklenmiyor. Kalkış yapılamıyor", + "zh": "无法起飞:RTK模块不支持热插拔" + }, + "fpv_tip_0x16010025_in_the_sky": { + "de": "RTK-Fehler. Umgehend landen.", + "en": "RTK error. Land promptly", + "es": "Error de RTK. Aterrice rápidamente", + "fr": "Erreur RTK. Atterrissez immédiatement", + "ja": "RTKエラーです。直ちに着陸させてください", + "ko": "RTK 오류. 즉시 착륙하세요", + "ru": "Ошибка RTK. Немедленно выполните посадку", + "tr": "RTK hatası. Derhal iniş yapın", + "zh": "RTK异常,请尽快降落" + }, + "fpv_tip_0x16010026": { + "ar": "", + "de": "", + "en": "Unable to take off. Non-DJI RTK module detected", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "无法起飞:检测到非官方RTK模块", + "zh-Hant": "" + }, + "fpv_tip_0x16010026_in_the_sky": { + "ar": "", + "de": "", + "en": "Non-DJI RTK module detected", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "检测到非官方RTK模块", + "zh-Hant": "" + }, + "fpv_tip_0x16010028": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x16010028_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x1601002B": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x1601002B_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x1601002F": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x1601002F_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16010032": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x16010032_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16010041": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x16010041_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16010050": { + "en": "", + "zh": "当前仅使用雷达定位,请勿在狭窄走廊、隧道等环境飞行" + }, + "fpv_tip_0x16020001": { + "de": "Fehler: IMU . Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU . Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류 . 기체 재시작 필요", + "ru": "Ошибка IMU . Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x16020001_in_the_sky": { + "de": "Fehler: IMU . Zum Startpunk zurückkehren oder landen.", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU . Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか、着陸してください", + "ko": "IMU 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка IMU . Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x16020004": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x16020004_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x16020007": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x16020007_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x1602000A": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x1602000A_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x1602000D": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x1602000D_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x16020016": { + "de": "Abweichung des IMU zu groß . IMU kalibrieren", + "en": "IMU bias too large. Calibrate IMU", + "es": "Desviación de la IMU demasiado grande. Calibra la IMU", + "fr": "Écart IMU trop grand . Étalonnez l\\'IMU", + "ja": "IMUバイアスが大きすぎます。IMUをキャリブレーションしてください", + "ko": "IMU 바이어스 오차 너무 큼 . IMU 캘리브레이션 필요", + "ru": "Слишком большое смещение IMU . Откалибруйте модуль", + "tr": "IMU sapması çok büyük. IMU’yu Kalibre Et", + "zh": "IMU偏差过大,请校准 IMU" + }, + "fpv_tip_0x16020016_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか、着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x16020027": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x16020027_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x1602002A": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x1602002A_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x16020620": { + "de": "Rückkehrfunktion (RTH) abgebrochen. Steuerknüppel nach unten gedrückt", + "en": "RTH canceled. Control stick pushed down", + "es": "RPO cancelado. Palanca de control presionada hacia abajo.", + "fr": "RTH annulé. Joystick poussé vers le bas", + "ja": "RTHがキャンセル。操作スティックが倒されました", + "ko": "RTH 취소됨. 조종 스틱이 아래로 눌림", + "ru": "Возврат на базу отменен. Джойстик наклонен вниз", + "tr": "BND iptal edildi. Kontrol çubuğu aşağı bastırıldı", + "zh": "返航中断:检测到反向杆量" + }, + "fpv_tip_0x16020621": { + "de": "Rückkehrfunktion (RTH) abgebrochen. Hindernis erkannt", + "en": "RTH canceled. Obstacle detected", + "es": "RPO cancelado. Obstáculo detectado.", + "fr": "RTH annulé. Obstacle détecté", + "ja": "RTHがキャンセル。障害物が検知されました", + "ko": "RTH 취소됨. 장애물 감지됨", + "ru": "Возврат на базу отменен. Обнаружено препятствие", + "tr": "BND iptal edildi. Engel tespit edildi", + "zh": "返航中断:检测到障碍物" + }, + "fpv_tip_0x16020622": { + "de": "Rückkehrfunktion (RTH) abgebrochen. Hohe Windgeschwindigkeit oder Fluggerät nähert sich einer GEO-Zone", + "en": "RTH canceled. Strong wind or aircraft approaching GEO Zone", + "es": "RPO cancelado. Viento fuerte o aeronave acercándose a la zona GEO.", + "fr": "RTH annulé. Vent fort ou appareil approchant une zone GEO", + "ja": "RTHがキャンセル。機体が強風下にあるかGEO区域に接近中です", + "ko": "RTH 취소됨. 강한 바람 또는 기체가 GEO 구역에 접근 중", + "ru": "Возврат на базу отменен. Сильный ветер или дрон приближается к зоне GEO", + "tr": "BND iptal edildi. Güçlü rüzgar veya hava aracı GEO Bölgesine yaklaşıyor", + "zh": "返航中断:风速过大或有限飞区" + }, + "fpv_tip_0x16020623": { + "de": "Rückkehrfunktion (RTH) abgebrochen. GPS-Fehler", + "en": "RTH canceled. GPS error", + "es": "RPO cancelado. Error de GPS.", + "fr": "RTH annulé. Erreur GPS", + "ja": "RTHがキャンセル。GPSエラー", + "ko": "RTH 취소됨. GPS 오류", + "ru": "Возврат на базу отменен. Ошибка GPS", + "tr": "BND iptal edildi. GPS hatası", + "zh": "返航中断:GPS异常" + }, + "fpv_tip_0x16030001": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x16030001_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x16030004": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x16030004_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x16030007": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x16030007_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x1603000A": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x1603000A_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x1603000D": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x1603000D_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x16030010": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x16030010_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x16030013": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x16030013_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x16030016": { + "de": "IMU-Abweichung zu groß. IMU kalibrieren", + "en": "IMU bias too large. Calibrate IMU", + "es": "Desviación de la IMU demasiado grande. Calibra la IMU", + "fr": "IMU bias too large. Calibrate IMU", + "ja": "IMU bias too large . Calibrate IMU", + "ko": "IMU 바이어스 오차가 너무 큼. IMU 캘리브레이션 필요", + "ru": "Смещение модуля IMU слишком велико. Откалибруйте модуль IMU", + "tr": "IMU sapması çok büyük. IMU’yu Kalibre Et", + "zh": "IMU偏差过大,请校准 IMU" + }, + "fpv_tip_0x16030016_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x1603001C": { + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x1603001C_in_the_sky": { + "de": "Fehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか着陸してください", + "ko": "IMU 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка модуля IMU. Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x1603001D": { + "de": "Abnormale Vibrationen des Fluggeräts. Umgehend zum Startpunkt zurückkehren oder landen.", + "en": "Abnormal aircraft vibration. Return to home or land promptly", + "es": "Vibración anormal de la aeronave. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Vibrations anormales de l'appareil. Retourner au point de départ ou atterrir rapidement", + "ja": "機体の異常な振動。直ちに帰還するか、着陸してください", + "ko": "비정상적 기체 진동. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Аномальная вибрация дрона. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Anormal araç titreşimi. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "飞行器异常振动,请尽快返航或降落" + }, + "fpv_tip_0x16040001": { + "de": "Fehler: Barometer . Fluggerät neu starten", + "en": "Barometer error. Restart aircraft", + "es": "Error del barómetro. Reinicia la aeronave", + "fr": "Erreur baromètre . Redémarrez l\\'appareil", + "ja": "気圧計エラー。機体を再起動してください", + "ko": "기압계 오류 . 기체 재시작 필요", + "ru": "Ошибка барометра . Перезагрузите дрон", + "tr": "Barometre hatası. Aracı yeniden başlatın", + "zh": "气压计异常,请重启飞行器" + }, + "fpv_tip_0x16040001_in_the_sky": { + "de": "Fehler: Barometer . Zum Startpunk zurückkehren oder landen.", + "en": "Barometer error. Return to home or land", + "es": "Error del barómetro. Regresa al punto de origen o aterriza", + "fr": "Erreur baromètre . Revenez au point de départ ou atterrissez", + "ja": "気圧計エラー。帰還するか、着陸してください", + "ko": "기압계 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка барометра . Вернитесь домой или приземлитесь", + "tr": "Barometre hatası. Eve geri dönün veya iniş yapın", + "zh": "气压计异常,请返航或降落" + }, + "fpv_tip_0x16040004": { + "de": "Fehler: Barometer. Fluggerät neu starten", + "en": "Barometer error. Restart aircraft", + "es": "Error del barómetro. Reinicia la aeronave", + "fr": "Erreur baromètre. Redémarrez l\\'appareil", + "ja": "気圧計エラー。機体を再起動してください", + "ko": "기압계 오류. 기체 재시작 필요", + "ru": "Ошибка барометра. Перезагрузите дрон", + "tr": "Barometre hatası. Aracı yeniden başlatın", + "zh": "气压计异常,请重启飞行器" + }, + "fpv_tip_0x16040004_in_the_sky": { + "de": "Fehler: Barometer. Zum Startpunkt zurückkehren oder landen", + "en": "Barometer error. Return to home or land", + "es": "Error del barómetro. Regresa al punto de origen o aterriza", + "fr": "Erreur baromètre. Revenez au point de départ ou atterrissez", + "ja": "気圧計エラー。帰還するか着陸してください", + "ko": "기압계 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка барометра. Вернитесь домой или приземлитесь", + "tr": "Barometre hatası. Eve geri dönün veya iniş yapın", + "zh": "气压计异常,请返航或降落" + }, + "fpv_tip_0x16040007": { + "de": "Fehler: Barometer. Fluggerät neu starten", + "en": "Barometer error. Restart aircraft", + "es": "Error del barómetro. Reinicia la aeronave", + "fr": "Erreur baromètre. Redémarrez l\\'appareil", + "ja": "気圧計エラー。機体を再起動してください", + "ko": "기압계 오류. 기체 재시작 필요", + "ru": "Ошибка барометра. Перезагрузите дрон", + "tr": "Barometre hatası. Aracı yeniden başlatın", + "zh": "气压计异常,请重启飞行器" + }, + "fpv_tip_0x16040007_in_the_sky": { + "de": "Fehler: Barometer. Zum Startpunkt zurückkehren oder landen", + "en": "Barometer error. Return to home or land", + "es": "Error del barómetro. Regresa al punto de origen o aterriza", + "fr": "Erreur baromètre. Revenez au point de départ ou atterrissez", + "ja": "気圧計エラー。帰還するか着陸してください", + "ko": "기압계 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка барометра. Вернитесь домой или приземлитесь", + "tr": "Barometre hatası. Eve geri dönün veya iniş yapın", + "zh": "气压计异常,请返航或降落" + }, + "fpv_tip_0x1604000A": { + "de": "Fehler: Barometer. Fluggerät neu starten", + "en": "Barometer error. Restart aircraft", + "es": "Error del barómetro. Reinicia la aeronave", + "fr": "Erreur baromètre. Redémarrez l\\'appareil", + "ja": "気圧計エラー。機体を再起動してください", + "ko": "기압계 오류. 기체 재시작 필요", + "ru": "Ошибка барометра. Перезагрузите дрон", + "tr": "Barometre hatası. Aracı yeniden başlatın", + "zh": "气压计异常,请重启飞行器" + }, + "fpv_tip_0x1604000A_in_the_sky": { + "de": "Fehler: Barometer. Zum Startpunkt zurückkehren oder landen", + "en": "Barometer error. Return to home or land", + "es": "Error del barómetro. Regresa al punto de origen o aterriza", + "fr": "Erreur baromètre. Revenez au point de départ ou atterrissez", + "ja": "気圧計エラー。帰還するか着陸してください", + "ko": "기압계 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка барометра. Вернитесь домой или приземлитесь", + "tr": "Barometre hatası. Eve geri dönün veya iniş yapın", + "zh": "气压计异常,请返航或降落" + }, + "fpv_tip_0x16040010": { + "de": "Fehler: Barometer. Fluggerät neu starten", + "en": "Barometer error. Restart aircraft", + "es": "Error del barómetro. Reinicia la aeronave", + "fr": "Erreur baromètre. Redémarrez l\\'appareil", + "ja": "気圧計エラー。機体を再起動してください", + "ko": "기압계 오류. 기체 재시작 필요", + "ru": "Ошибка барометра. Перезагрузите дрон", + "tr": "Barometre hatası. Aracı yeniden başlatın", + "zh": "气压计异常,请重启飞行器" + }, + "fpv_tip_0x16040010_in_the_sky": { + "de": "Fehler: Barometer. Zum Startpunkt zurückkehren oder landen", + "en": "Barometer error. Return to home or land", + "es": "Error del barómetro. Regresa al punto de origen o aterriza", + "fr": "Erreur baromètre. Revenez au point de départ ou atterrissez", + "ja": "気圧計エラー。帰還するか着陸してください", + "ko": "기압계 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка барометра. Вернитесь домой или приземлитесь", + "tr": "Barometre hatası. Eve geri dönün veya iniş yapın", + "zh": "气压计异常,请返航或降落" + }, + "fpv_tip_0x16040013": { + "de": "Fehler: Barometer. Fluggerät neu starten", + "en": "Barometer error. Restart aircraft", + "es": "Error del barómetro. Reinicia la aeronave", + "fr": "Erreur baromètre. Redémarrez l\\'appareil", + "ja": "気圧計エラー。機体を再起動してください", + "ko": "기압계 오류. 기체 재시작 필요", + "ru": "Ошибка барометра. Перезагрузите дрон", + "tr": "Barometre hatası. Aracı yeniden başlatın", + "zh": "气压计异常,请重启飞行器" + }, + "fpv_tip_0x16040013_in_the_sky": { + "de": "Fehler: Barometer. Zum Startpunkt zurückkehren oder landen", + "en": "Barometer error. Return to home or land", + "es": "Error del barómetro. Regresa al punto de origen o aterriza", + "fr": "Erreur baromètre. Revenez au point de départ ou atterrissez", + "ja": "気圧計エラー。帰還するか着陸してください", + "ko": "기압계 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка барометра. Вернитесь домой или приземлитесь", + "tr": "Barometre hatası. Eve geri dönün veya iniş yapın", + "zh": "气压计异常,请返航或降落" + }, + "fpv_tip_0x16040016": { + "de": "Fehler: Barometer. Fluggerät neu starten", + "en": "Barometer error. Restart aircraft", + "es": "Error del barómetro. Reinicia la aeronave", + "fr": "Erreur baromètre. Redémarrez l\\'appareil", + "ja": "気圧計エラー。機体を再起動してください", + "ko": "기압계 오류. 기체 재시작 필요", + "ru": "Ошибка барометра. Перезагрузите дрон", + "tr": "Barometre hatası. Aracı yeniden başlatın", + "zh": "气压计异常,请重启飞行器" + }, + "fpv_tip_0x16040016_in_the_sky": { + "de": "Fehler: Barometer. Zum Startpunkt zurückkehren oder landen", + "en": "Barometer error. Return to home or land", + "es": "Error del barómetro. Regresa al punto de origen o aterriza", + "fr": "Erreur baromètre. Revenez au point de départ ou atterrissez", + "ja": "気圧計エラー。帰還するか着陸してください", + "ko": "기압계 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка барометра. Вернитесь домой или приземлитесь", + "tr": "Barometre hatası. Eve geri dönün veya iniş yapın", + "zh": "气压计异常,请返航或降落" + }, + "fpv_tip_0x16040019": { + "de": "Fehler: Barometer. Fluggerät neu starten", + "en": "Barometer error. Restart aircraft", + "es": "Error del barómetro. Reinicia la aeronave", + "fr": "Erreur baromètre. Redémarrez l\\'appareil", + "ja": "気圧計エラー。機体を再起動してください", + "ko": "기압계 오류. 기체 재시작 필요", + "ru": "Ошибка барометра. Перезагрузите дрон", + "tr": "Barometre hatası. Aracı yeniden başlatın", + "zh": "气压计异常,请重启飞行器" + }, + "fpv_tip_0x16040019_in_the_sky": { + "de": "Fehler: Barometer. Zum Startpunkt zurückkehren oder landen", + "en": "Barometer error. Return to home or land", + "es": "Error del barómetro. Regresa al punto de origen o aterriza", + "fr": "Erreur baromètre. Revenez au point de départ ou atterrissez", + "ja": "気圧計エラー。帰還するか着陸してください", + "ko": "기압계 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка барометра. Вернитесь домой или приземлитесь", + "tr": "Barometre hatası. Eve geri dönün veya iniş yapın", + "zh": "气压计异常,请返航或降落" + }, + "fpv_tip_0x16050001": { + "de": "GPS-Fehler. Fluggerät neu starten", + "en": "GPS error. Restart aircraft", + "es": "Error de GPS. Reinicia la aeronave", + "fr": "Erreur GPS. Redémarrez l\\'appareil", + "ja": "GPSエラー。機体を再起動してください", + "ko": "GPS 오류. 기체 재시작 필요", + "ru": "Ошибка GPS. Перезагрузите дрон", + "tr": "GPS hatası. Aracı yeniden başlatın", + "zh": "GPS异常,请重启飞行器" + }, + "fpv_tip_0x16050001_in_the_sky": { + "de": "GPS-Fehler. Zum Startpunkt zurückkehren oder landen", + "en": "GPS error. Return to home or land", + "es": "Error de GPS. Regresa al punto de origen o aterriza", + "fr": "Erreur GPS. Revenez au point de départ ou atterrissez", + "ja": "GPSエラー。帰還するか着陸してください", + "ko": "GPS 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка GPS. Вернитесь домой или приземлитесь", + "tr": "GPS hatası. Eve geri dönün veya iniş yapın", + "zh": "GPS异常,请返航或降落" + }, + "fpv_tip_0x16050004": { + "de": "GPS-Fehler. Fluggerät neu starten", + "en": "GPS error. Restart aircraft", + "es": "Error de GPS. Reinicia la aeronave", + "fr": "Erreur GPS. Redémarrez l\\'appareil", + "ja": "GPSエラー。機体を再起動してください", + "ko": "GPS 오류. 기체 재시작 필요", + "ru": "Ошибка GPS. Перезагрузите дрон", + "tr": "GPS hatası. Aracı yeniden başlatın", + "zh": "GPS异常,请重启飞行器" + }, + "fpv_tip_0x16050004_in_the_sky": { + "de": "GPS-Fehler. Zum Startpunkt zurückkehren oder landen", + "en": "GPS error. Return to home or land", + "es": "Error de GPS. Regresa al punto de origen o aterriza", + "fr": "Erreur GPS. Revenez au point de départ ou atterrissez", + "ja": "GPSエラー。帰還するか着陸してください", + "ko": "GPS 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка GPS. Вернитесь домой или приземлитесь", + "tr": "GPS hatası. Eve geri dönün veya iniş yapın", + "zh": "GPS异常,请返航或降落" + }, + "fpv_tip_0x16050019": { + "de": "Fehler: GPS . Fluggerät neu starten", + "en": "GPS error. Restart aircraft", + "es": "Error de GPS. Reinicia la aeronave", + "fr": "Erreur GPS . Redémarrez l\\'appareil", + "ja": "GPSエラー。機体を再起動してください", + "ko": "GPS 오류 . 기체 재시작 필요", + "ru": "Ошибка GPS . Перезагрузите дрон", + "tr": "GPS hatası. Aracı yeniden başlatın", + "zh": "GPS异常,请重启飞行器" + }, + "fpv_tip_0x16050019_in_the_sky": { + "de": "Fehler: GPS . Zum Startpunkt zurückkehren oder landen.", + "en": "GPS error. Return to home or land", + "es": "Error de GPS. Regresa al punto de origen o aterriza", + "fr": "Erreur GPS . Revenez au point de départ ou atterrissez", + "ja": "GPSエラー。帰還するか、着陸してください", + "ko": "GPS 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка GPS . Вернитесь домой или приземлитесь", + "tr": "GPS hatası. Eve geri dönün veya iniş yapın", + "zh": "GPS异常,请返航或降落" + }, + "fpv_tip_0x1605001C": { + "de": "GPS-Fehler. Fluggerät neu starten", + "en": "GPS error. Restart aircraft", + "es": "Error de GPS. Reinicia la aeronave", + "fr": "Erreur GPS. Redémarrez l\\'appareil", + "ja": "GPSエラー。機体を再起動してください", + "ko": "GPS 오류. 기체 재시작 필요", + "ru": "Ошибка GPS. Перезагрузите дрон", + "tr": "GPS hatası. Aracı yeniden başlatın", + "zh": "GPS异常,请重启飞行器" + }, + "fpv_tip_0x1605001C_in_the_sky": { + "de": "GPS-Fehler. Zum Startpunkt zurückkehren oder landen", + "en": "GPS error. Return to home or land", + "es": "Error de GPS. Regresa al punto de origen o aterriza", + "fr": "Erreur GPS. Revenez au point de départ ou atterrissez", + "ja": "GPSエラー。帰還するか着陸してください", + "ko": "GPS 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка GPS. Вернитесь домой или приземлитесь", + "tr": "GPS hatası. Eve geri dönün veya iniş yapın", + "zh": "GPS异常,请返航或降落" + }, + "fpv_tip_0x1605001F": { + "de": "GPS-Signalstörungen. Mit Vorsicht fliegen", + "en": "GPS signal interference. Fly with caution", + "es": "Interferencia de señal GPS. Vuele con cuidado.", + "fr": "Interférence de signal GPS. Pilotez avec précaution", + "ja": "GPS信号干渉があります。慎重に飛行してください", + "ko": "GPS 신호 간섭. 비행 시 주의 필요", + "ru": "Помехи в сигнале GPS. Соблюдайте осторожность при полете", + "tr": "GPS sinyal müdahalesi. Dikkatlice uçun", + "zh": "飞行器GPS受到干扰,谨慎飞行" + }, + "fpv_tip_0x16050020": { + "ar": "", + "de": "Starke GPS-Störung. Fluggerät kehrt zum Startpunkt zurück", + "en": "Strong GPS interference. Aircraft returning to home", + "es": "Fuerte interferencia de GPS. La aeronave se está dirigiendo al punto de partida", + "fr": "Fortes interférences GPS. L'appareil retourne à son point de départ", + "id": "", + "it": "", + "ja": "強いGPS干渉。帰還中です。", + "ko": "강한 GPS 간섭. 기체가 리턴 투 홈 중입니다.", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Сильные помехи GPS. Дрон выполняет возврат домой", + "th": "", + "tr": "Güçlü GPS paraziti. Hava aracı kalkış noktasına dönüyor", + "ug": "", + "vi": "", + "zh": "GPS干扰强,飞行器自动返航", + "zh-Hant": "" + }, + "fpv_tip_0x16050021": { + "de": "RTK nicht konvergiert. Fluggerät in einem offenen Bereich platzieren und Aufgabe starten, nachdem RTK konvergiert ist.", + "en": "RTK not converged. Place aircraft in an open area and start task after RTK converged", + "es": "RTK no convergente. Sitúe la aeronave en una zona abierta y comience la tarea después de la convergencia de RTK", + "fr": "RTK non convergent. Placez l'appareil dans une zone dégagée et démarrez la tâche après la convergence RTK", + "ja": "RTKが収束していません。機体を開けた場所に置き、RTKが収束したらタスクを開始してください", + "ko": "RTK가 수렴되지 않았습니다. 기체를 개방된 공간에 두고 RTK가 수렴된 후 작업을 시작하세요", + "ru": "RTK без конвергенции. Разместите дрон на открытой местности и приступайте к выполнению задачи после конвергенции RTK", + "tr": "RTK yakınsanmadı. Hava aracını açık bir alana yerleştirin ve RTK yakınsandıktan sonra göreve başlayın", + "zh": "RTK 启用未收敛,请将飞机置于空旷环境等待 RTK 收敛后执行任务" + }, + "fpv_tip_0x16050022": { + "de": "GNSS-Signalfehler groß. Mit Vorsicht fliegen.", + "en": "GNSS signal error large. Fly with caution", + "es": "Error de señal GNSS grande. Vuela con cuidado.", + "fr": "Erreur de signal GNSS importante. Pilotez avec précaution.", + "ja": "GNSS信号エラーが大きいです。慎重に飛行してください", + "ko": "GNSS 신호 오류가 큽니다. 비행 시 주의 필요.", + "ru": "Ошибка сигнала GNSS. Будьте осторожны в полете", + "tr": "GNSS sinyal hatası büyük. Dikkatlice uçurun", + "zh": "当前飞行环境GNSS信号误差大,请谨慎飞行" + }, + "fpv_tip_0x1605002B": { + "de": "Es werden nur BDS-Daten verwendet. Die Anzahl gesuchter Satelliten wird möglicherweise beeinträchtigt", + "en": "Only BDS data used. Number of searched satellites may be affected", + "es": "Solo se utilizan datos de BDS. El número de satélites buscados puede verse afectado.", + "fr": "Utilisation des données BDS uniquement. Le nombre de satellites recherchés peut être affecté", + "ja": "BDSデータのみ使用。検索される衛星の数に影響する可能性があります", + "ko": "BDS 데이터만 사용됨. 검색된 위성 수에 영향을 줄 수 있음", + "ru": "Используются только данные BDS. Может быть затронут ряд искомых спутников", + "tr": "Yalnızca BDS verileri kullanılıyor. Aranan uyduların sayısı değişebilir", + "zh": "进入单北斗模式,搜星质量可能变差" + }, + "fpv_tip_0x16060001": { + "de": "Fehler: Kompass . Fluggerät neu starten", + "en": "Compass error. Restart aircraft", + "es": "Error de brújula. Reinicia la aeronave", + "fr": "Erreur du compas . Redémarrez l\\'appareil", + "ja": "コンパスエラー。機体を再起動してください", + "ko": "콤파스 오류 . 기체 재시작 필요", + "ru": "Ошибка компаса . Перезагрузите дрон", + "tr": "Pusula hatası. Aracı yeniden başlatın", + "zh": "指南针异常,请重启飞行器" + }, + "fpv_tip_0x16060001_in_the_sky": { + "de": "Fehler: Kompass . Zum Startpunkt zurückkehren oder landen.", + "en": "Compass error. Return to home or land", + "es": "Error de brújula. Regresa al punto de origen o aterriza", + "fr": "Erreur compas . Revenez au point de départ ou atterrissez", + "ja": "コンパスエラー。帰還するか、着陸してください", + "ko": "콤파스 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка компаса . Вернитесь домой или приземлитесь", + "tr": "Pusula hatası. Eve geri dönün veya iniş yapın", + "zh": "指南针异常,请返航或降落" + }, + "fpv_tip_0x16060007": { + "de": "Kompassfehler. Fluggerät neu starten", + "en": "Compass error. Restart aircraft", + "es": "Error de brújula. Reinicia la aeronave", + "fr": "Erreur du compas. Redémarrez l\\'appareil", + "ja": "コンパスエラー。機体を再起動してください", + "ko": "콤파스 오류. 기체 재시작 필요", + "ru": "Ошибка компаса. Перезагрузите дрон", + "tr": "Pusula hatası. Aracı yeniden başlatın", + "zh": "指南针异常,请重启飞行器" + }, + "fpv_tip_0x16060007_in_the_sky": { + "de": "Kompassfehler. Zum Startpunkt zurückkehren oder landen", + "en": "Compass error. Return to home or land", + "es": "Error de brújula. Regresa al punto de origen o aterriza", + "fr": "Erreur compas. Revenez au point de départ ou atterrissez", + "ja": "コンパスエラー。帰還するか着陸してください", + "ko": "콤파스 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка компаса. Вернитесь домой или приземлитесь", + "tr": "Pusula hatası. Eve geri dönün veya iniş yapın", + "zh": "指南针异常,请返航或降落" + }, + "fpv_tip_0x1606000A": { + "de": "Kompassfehler. Fluggerät neu starten", + "en": "Compass error. Restart aircraft", + "es": "Error de brújula. Reinicia la aeronave", + "fr": "Erreur du compas. Redémarrez l\\'appareil", + "ja": "コンパスエラー。機体を再起動してください", + "ko": "콤파스 오류. 기체 재시작 필요", + "ru": "Ошибка компаса. Перезагрузите дрон", + "tr": "Pusula hatası. Aracı yeniden başlatın", + "zh": "指南针异常,请重启飞行器" + }, + "fpv_tip_0x1606000A_in_the_sky": { + "de": "Kompassfehler. Zum Startpunkt zurückkehren oder landen", + "en": "Compass error. Return to home or land", + "es": "Error de brújula. Regresa al punto de origen o aterriza", + "fr": "Erreur compas. Revenez au point de départ ou atterrissez", + "ja": "コンパスエラー。帰還するか着陸してください", + "ko": "콤파스 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка компаса. Вернитесь домой или приземлитесь", + "tr": "Pusula hatası. Eve geri dönün veya iniş yapın", + "zh": "指南针异常,请返航或降落" + }, + "fpv_tip_0x1606000D": { + "de": "Fehler: Kompass . Kompass neu kalibrieren", + "en": "Compass interference. Calibrate compass", + "es": "Interferencias en la brújula. Calibra la brújula", + "fr": "Interférence compas . Étalonnez le compas", + "ja": "コンパスの干渉。コンパスをキャリブレーション", + "ko": "콤파스 간섭 . 콤파스 캘리브레이션 필요", + "ru": "Помехи компаса . Откалибруйте его", + "tr": "Pusula müdahalesi. Pusulayı kalibre edin", + "zh": "指南针受到干扰,请校准指南针" + }, + "fpv_tip_0x1606000D_in_the_sky": { + "de": "Kompassstörung . Fluggerät von der Störquelle wegbewegen.", + "en": "Compass interference. Move aircraft away from interference source", + "es": "Interferencias en la brújula. Aleja la aeronave de la fuente de interferencia", + "fr": "Interférence compas . Éloignez l\\'appareil des sources d\\'interférence", + "ja": "コンパスの干渉。干渉源から機体を遠ざけてください", + "ko": "콤파스 간섭 . 기체를 간섭원에서 멀리 이동해야 함", + "ru": "Помехи компаса . Отдалитесь от источника помех", + "tr": "Pusula müdahalesi. Aracı müdahale kaynağından uzaklaştırın", + "zh": "指南针受到干扰,请远离干扰源" + }, + "fpv_tip_0x16060010": { + "de": "Kompassstörung. Kompass kalibrieren", + "en": "Compass interference. Calibrate compass", + "es": "Interferencias en la brújula. Calibra la brújula", + "fr": "Interférence compas. Étalonnez le compas", + "ja": "コンパス干渉。コンパスのキャリブレーションを行ってください", + "ko": "콤파스 간섭. 콤파스 캘리브레이션 필요", + "ru": "Помехи в работе компаса. Откалибруйте компас", + "tr": "Pusula müdahalesi. Pusulayı kalibre edin", + "zh": "指南针受到干扰,请校准指南针" + }, + "fpv_tip_0x16060010_in_the_sky": { + "de": "Kompassstörung. Fluggerät von der Störquelle wegbewegen", + "en": "Compass interference. Move aircraft away from interference source", + "es": "Interferencias en la brújula. Aleja la aeronave de la fuente de interferencia", + "fr": "Interférence compas. Éloignez l\\'appareil des sources d\\'interférence", + "ja": "コンパス干渉。干渉源から機体を遠ざけてください", + "ko": "콤파스 간섭. 기체를 간섭원에서 멀리 이동해야 함", + "ru": "Помехи в работе компаса. Переместите дрон вдаль от источника помех", + "tr": "Pusula müdahalesi. Aracı müdahale kaynağından uzaklaştırın", + "zh": "指南针受到干扰,请远离干扰源" + }, + "fpv_tip_0x16070001": { + "de": "Flugregler überhitzt. Rückkehr zum Startpunkt...", + "en": "Flight controller overheats. Returning to home...", + "es": "El controlador de vuelo se sobrecalienta. Regresando al punto de origen...", + "fr": "Surchauffe du contrôleur de vol. Retour au point de départ en cours...", + "ja": "フライトコントローラーが過熱状態。ホームに帰還中...", + "ko": "비행 컨트롤러 과열. RTH 진행 중...", + "ru": "Полетный контроллер перегревается. Возвращение на базу...", + "tr": "Uçuş kontrol sistemi aşırı ısındı. Başlangıç noktasına dönülüyor...", + "zh": "飞控温度过高,返航中" + }, + "fpv_tip_0x16070002": { + "de": "Flugregler überhitzt. Rückkehr zum Startpunkt...", + "en": "Flight controller overheats. Returning to home...", + "es": "El controlador de vuelo se sobrecalienta. Regresando al punto de origen...", + "fr": "Surchauffe du contrôleur de vol. Retour au point de départ en cours...", + "ja": "フライトコントローラーが過熱状態。ホームに帰還中...", + "ko": "비행 컨트롤러 과열. RTH 진행 중...", + "ru": "Полетный контроллер перегревается. Возвращение на базу...", + "tr": "Uçuş kontrol sistemi aşırı ısındı. Başlangıç noktasına dönülüyor...", + "zh": "飞控温度过高,返航中" + }, + "fpv_tip_0x16070003": { + "de": "Flugregler überhitzt. Automatische Landung…", + "en": "Flight controller overheats. Auto landing...", + "es": "El controlador de vuelo se sobrecalienta. Realizando aterrizaje automático…", + "fr": "Surchauffe du contrôleur de vol. Atterrissage automatique en cours...", + "ja": "フライトコントローラーが過熱状態。自動着陸中...", + "ko": "비행 컨트롤러 과열. 자동 착륙 진행 중...", + "ru": "Полетный контроллер перегревается. Автоматическая посадка…", + "tr": "Uçuş kontrol sistemi aşırı ısındı. Otomatik iniş yapılıyor...", + "zh": "飞控温度过高,强制降落中" + }, + "fpv_tip_0x16070020": { + "de": "Keine RTK-Daten vom Fluggerät empfangen. Fluggerät neu starten", + "en": "RTK data not received by aircraft", + "es": "La aeronave no recibe datos RTK. Reinicia la aeronave", + "fr": "Données RTK non reçues par l\\'appareil. Redémarrez l\\'appareil", + "ja": "機体でRTKデータを受信できません。機体を再起動してください", + "ko": "항공기가 RTK 데이터를 받지 못했습니다. 항공기를 다시 시작하세요.", + "ru": "Данные RTK не получены дроном", + "tr": "RTK verisi araç tarafından alınmadı. Aracı yeniden başlatın", + "zh": "飞行器未接收到RTK数据" + }, + "fpv_tip_0x16070021": { + "de": "RTK-Datenfehler. Fluggerät neu starten", + "en": "RTK data error. Restart aircraft", + "es": "Error de datos RTK. Reinicia la aeronave", + "fr": "Erreur liée aux données RTK. Redémarrez l\\'appareil", + "ja": "RTKデータエラーです。機体を再起動してください", + "ko": "RTK 데이터 오류입니다. 항공기를 다시 시작하세요.", + "ru": "Ошибка данных RTK. Перезапустите дрон", + "tr": "RTK verisi hatası. Aracı yeniden başlatın", + "zh": "RTK 数据异常,请重启飞行器" + }, + "fpv_tip_0x16070023": { + "de": "Fehler bei der Aktualisierungsfrequenz der RTK-Daten. Vorsichtig fliegen.", + "en": "RTK data refresh frequency error", + "es": "Error de frecuencia de actualización de datos RTK. Vuela con cuidado", + "fr": "Erreur de fréquence d\\'actualisation des données RTK. Volez avec prudence", + "ja": "RTKデータ更新頻度のエラーです。注意して飛行してください", + "ko": "RTK 데이터 새로 고침 빈도 오류입니다. 주의하여 비행하세요.", + "ru": "Слишком частое обновление данных RTK", + "tr": "RTK veri yenileme sıklığı hatası. Dikkatli uçurun", + "zh": "RTK 数据更新频率异常" + }, + "fpv_tip_0x16070024": { + "de": "RTK-Datenfehler. Vorsichtig fliegen.", + "en": "RTK data error", + "es": "Error de datos RTK. Vuela con cuidado", + "fr": "Erreur liée aux données RTK. Volez avec prudence", + "ja": "RTKデータエラーです。注意して飛行してください", + "ko": "RTK 데이터 오류입니다. 주의하여 비행하세요.", + "ru": "Ошибка данных RTK", + "tr": "RTK verisi hatası. Dikkatli uçurun", + "zh": "RTK 数据异常" + }, + "fpv_tip_0x16070025": { + "de": "Die RTK-Positionsdaten können nicht aktualisiert werden. Fluggerät neu starten", + "en": "Unable to refresh RTK position data", + "es": "No se pueden actualizar los datos de posición de RTK. Reinicia la aeronave", + "fr": "Impossible d\\'actualiser les données de position RTK. Redémarrez l\\'appareil", + "ja": "RTK位置データを更新できません。機体を再起動してください", + "ko": "RTK 위치 데이터를 새로 고칠 수 없습니다. 항공기를 다시 시작하세요.", + "ru": "Не удалось обновить данные положения RTK. Перезапустите дрон", + "tr": "RTK pozisyon verisini yenileyemiyor. Aracı yeniden başlatın", + "zh": "RTK 定位数据停止更新" + }, + "fpv_tip_0x16070026": { + "de": "Plötzliche Änderung der RTK-Positionsdaten. Fluggerät neu starten", + "en": "Sudden RTK position data change", + "es": "Cambio repentino de los datos de posición de RTK. Reinicia la aeronave", + "fr": "Changement soudain des données de position RTK. Redémarrez l\\'appareil", + "ja": "RTK位置データが突然変更されました。機体を再起動してください", + "ko": "갑자기 RTK 위치 데이터가 변경되었습니다. 항공기를 다시 시작하세요.", + "ru": "Внезапное изменение данных положения RTK. Перезапустите дрон", + "tr": "RTK konum verisinde ani değişiklik. Aracı yeniden başlatın", + "zh": "RTK 定位数据跳变" + }, + "fpv_tip_0x16070027": { + "de": "RTK- und Sensorhöhendaten stimmen nicht überein. Fluggerät neu starten", + "en": "RTK and sensor altitude data inconsistent", + "es": "Datos de altitud de RTK y del sensor incoherentes. Reinicia la aeronave", + "fr": "Les données RTK et les données d\\'altitude du capteur sont incohérentes. Redémarrez l\\'appareil", + "ja": "RTKとセンサーの高度データが一致しません。機体を再起動してください", + "ko": "RTK 및 센서 고도 데이터가 일치하지 않습니다. 항공기를 다시 시작하세요.", + "ru": "Показания высоты RTK и датчика не совпадают", + "tr": "RTK ve sensör irtifa verisi tutarsız. Aracı yeniden başlatın", + "zh": "RTK 高度与传感器高度数据不一致" + }, + "fpv_tip_0x16070028": { + "de": "RTK- und GPS-Positionen stimmen nicht überein. Fluggerät neu starten", + "en": "RTK and GPS positions do not match", + "es": "Las posiciones de RTK y GPS no coinciden. Reinicia la aeronave", + "fr": "Les positions RTK et GPS ne correspondent pas. Redémarrez l\\'appareil", + "ja": "RTKとGPSの位置情報が一致しません。機体を再起動してください", + "ko": "RTK와 GPS 위치가 일치하지 않습니다. 항공기를 다시 시작하세요.", + "ru": "Положения RTK и GPS не совпадают. Перезапустите дрон", + "tr": "RTK ve GPS pozisyonları eşleşmiyor. Aracı yeniden başlatın", + "zh": "RTK 定位与 GPS 定位不一致" + }, + "fpv_tip_0x16070029": { + "de": "Die RTK-Positionsdaten haben sich bei stationärem Fluggerät leicht geändert. Fluggerät neu starten", + "en": "RTK position data changed slightly when aircraft is stationary", + "es": "Cambio leve en los datos de posición de RTK con la aeronave estática. Reinicia la aeronave", + "fr": "Données de position RTK légèrement modifiées lorsque l\\'appareil était à l\\'arrêt. Redémarrez l\\'appareil", + "ja": "機体は静止していますが、RTKの位置データがわずかに変更されました。機体を再起動してください", + "ko": "항공기가 정지 상태일 때 RTK 위치 데이터가 약간 변경되었습니다. 항공기를 다시 시작하세요.", + "ru": "Данные позиционирования RTK слегка изменились при неподвижном дроне", + "tr": "RTK konum verisi araç sabitken biraz değişti. Aracı yeniden başlatın", + "zh": "飞行器静止时 RTK 定位缓变" + }, + "fpv_tip_0x16070030": { + "de": "RTK-Firmware-Version stimmt nicht überein. Aktualisierung erforderlich", + "en": "RTK firmware version does not match", + "es": "La versión del firmware de RTK no coincide. Es necesario actualizar", + "fr": "Version du firmware RTK non correspondante. Mise à jour requise", + "ja": "RTKファームウェアバージョンが一致しません。更新が必要です", + "ko": "RTK 펌웨어 버전이 일치하지 않습니다. 업데이트해야 합니다.", + "ru": "Несоответствие версии прошивки RTK. Требуется обновление", + "tr": "RTK donanım yazılımı sürümü eşleşmiyor. Güncelleme gerekli", + "zh": "RTK 固件版本不匹配" + }, + "fpv_tip_0x16070031": { + "de": "Umschaltfehler RTK-Signalquelle", + "en": "RTK signal source switching error", + "es": "Error de cambio en la señal de origen RTK", + "fr": "Erreur de commutation de source de signal RTK", + "ja": "RTK信号源切り替えエラー", + "ko": "RTK 신호원 전환 오류", + "ru": "Ошибка переключения источника сигнала RTK", + "tr": "RTK sinyal kaynağı değiştirme hatası", + "zh": "RTK信号源切换异常" + }, + "fpv_tip_0x16070032": { + "de": "D-RTK-Mobilstation abgenommen. Status der Mobilstation prüfen oder Fluggerät neu starten", + "en": "D-RTK mobile station detached", + "es": "Estación móvil D-RTK no conectada. Comprueba la estación móvil y reinicia la aeronave", + "fr": "Station mobile D-RTK déconnectée. Vérifiez la station mobile et redémarrez l\\'appareil", + "ja": "D-RTKモバイルステーションが取り外されました。モバイルステーションを確認して、機体を再起動してください", + "ko": "D-RTK 이동국이 분리되었습니다. 이동국을 확인하고 항공기를 다시 시작하세요.", + "ru": "Мобильная станция D-RTK отсоединена", + "tr": "D-RTK mobil istasyonu söküldü. Mobil istasyonu kontrol edin ve aracı yeniden başlatın", + "zh": "D-RTK 移动站倾倒" + }, + "fpv_tip_0x16070033": { + "de": "D-RTK-Mobilstation bewegt. Status der Mobilstation prüfen oder Fluggerät neu starten", + "en": "D-RTK mobile station moved", + "es": "Estación móvil D-RTK desplazada. Comprueba la estación móvil y reinicia la aeronave", + "fr": "Station mobile D-RTK déplacée. Vérifiez la station mobile et redémarrez l\\'appareil", + "ja": "D-RTKモバイルステーションが移動しました。モバイルステーションを確認して、機体を再起動してください", + "ko": "D-RTK 이동국이 이동되었습니다. 이동국을 확인하고 항공기를 다시 시작하세요.", + "ru": "Мобильная станция D-RTK перемещена", + "tr": "D-RTK mobil istasyonu hareket etti. Mobil istasyonu kontrol edin ve aracı yeniden başlatın", + "zh": "D-RTK 移动站发生移动" + }, + "fpv_tip_0x16070034": { + "de": "RTK-Flugkurs mit anderen Quellen inkonsistent. Vorsichtig fliegen.", + "en": "RTK flight heading inconsistent with other sources", + "es": "Orientación de vuelo RTK incoherente con otras fuentes. Vuela con cuidado", + "fr": "Cap de vol RTK incompatible avec d\\'autres sources. Volez avec prudence", + "ja": "RTK飛行方向が他のソースと一致しません。注意して飛行してください", + "ko": "RTK 비행 기수 방위가 다른 소스와 일치하지 않습니다. 주의하여 비행하세요.", + "ru": "Направление полета RTK не совпадает с другими источниками", + "tr": "RTK uçuş istikameti diğer kaynaklarla uyuşmuyor. Dikkatli uçurun", + "zh": "RTK 航向与其他源不一致" + }, + "fpv_tip_0x16070035": { + "de": "D-RTK-Fluggeräte-Antennenfehler. Vorsichtig fliegen.", + "en": "Aircraft D-RTK antenna error", + "es": "Error de la antena D-RTK de la aeronave. Vuela con cuidado", + "fr": "Erreur d\\'antenne D-RTK de l\\'appareil. Volez avec prudence", + "ja": "機体のD-RTKアンテナのエラーです。注意して飛行してください", + "ko": "항공기 D-RTK 안테나 오류입니다. 주의하여 비행하세요.", + "ru": "Ошибка антенны D-RTK дрона", + "tr": "Araç D-RTK anten hatası. Dikkatli uçurun", + "zh": "机载 D-RTK 天线异常" + }, + "fpv_tip_0x16070036": { + "de": "Start nicht möglich. RTK-Antennen getrennt. DJI Support kontaktieren", + "en": "Unable to take off. RTK antennas disconnected. Contact DJI Support", + "es": "No se puede despegar. Antenas RTK desconectadas. Póngase en contacto con la Asistencia técnica de DJI", + "fr": "Impossible de décoller. Antennes RTK déconnectées. Contactez le service client DJI", + "ja": "離陸できません。RTKアンテナの接続が切断されました。DJIサポートまでお問い合わせください", + "ko": "이륙 불가. RTK 안테나 연결이 끊어졌습니다. DJI 고객지원으로 문의하세요.", + "ru": "Не удается выполнить взлет. Антенны RTK отключены. Свяжитесь со службой поддержки DJI", + "tr": "Kalkış yapılamıyor. RTK antenlerinin bağlantısı kesildi. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:RTK天线断连,请联系DJI售后" + }, + "fpv_tip_0x16070036_in_the_sky": { + "de": "RTK-Antennen getrennt. Umgehend zum Startpunkt zurückkehren oder landen.", + "en": "RTK antennas disconnected. Return to home or land promptly", + "es": "Antenas RTK desconectadas. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Antennes RTK déconnectées. Retourner au point de départ ou atterrir rapidement", + "ja": "RTKアンテナの接続が切断されました。直ちに帰還するか、着陸してください", + "ko": "RTK 안테나 연결이 끊어졌습니다. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Антенны RTK отключены. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "RTK antenlerinin bağlantısı kesildi. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "RTK天线断连,请尽快返航或降落" + }, + "fpv_tip_0x16070037": { + "de": "Zertifizierungsfehler: RTK-Dongle", + "en": "RTK Dongle Certification Error", + "es": "Error de certificación de adaptador RTK", + "fr": "Erreur de certification de dongle RTK", + "ja": "RTKドングル認証エラー", + "ko": "RTK 동글 인증 오류", + "ru": "Ошибка сертификации ключа RTK", + "tr": "RTK Dongle Sertifikasyon Hatası", + "zh": "RTK认证错误" + }, + "fpv_tip_0x16070040": { + "en": "RTK not converged. Place aircraft in an open environment and start task after RTK converged", + "zh": "RTK 启用未收敛,请将飞机置于空旷环境等待 RTK 收敛后执行任务" + }, + "fpv_tip_0x16080020": { + "de": "Motor %index blockiert. Fluggerät sofort landen", + "en": "Motor %index stalled . Land aircraft immediately", + "es": "Motor %index atascado. Aterriza la aeronave de inmediato", + "fr": "Moteur %index a calé . Atterrissez immédiatement", + "ja": "モーター%indexが停止しました。機体を直ちに着陸させてください", + "ko": "모터 %index 정지됨 . 즉시 기체 착륙해야 함", + "ru": "Мотор %index остановился . Посадите дрон немедленно", + "tr": "Motor %index durdu. Hemen aracı indirin", + "zh": "%index号电机堵转,请停止飞行。" + }, + "fpv_tip_0x16080021": { + "de": "Kurzschluss am ESC %index . Sofort landen und Fluggerät neu starten", + "en": "ESC %index short-circuited . Land immediately and restart aircraft", + "es": "Cortocircuito de ESC %index. Aterriza de inmediato y reinicia la aeronave", + "fr": "Court-circuit ESC %index . Atterrissez immédiatement et redémarrez l\\'appareil", + "ja": "ESC%index短絡。直ちに着陸させて、機体を再起動してください", + "ko": "ESC %index 합선 . 즉시 착륙하고 기체 재시작해야 함", + "ru": "Короткое замыкание ESC %index . Приземлитесь немедленно и перезагрузите дрон", + "tr": "ESC %index kısa devre yaptı. Hemen iniş yapın ve aracı yeniden başlatın", + "zh": "%index号电调短路,请停止飞行,并重启飞行器。" + }, + "fpv_tip_0x16080022": { + "de": "ESC %index überlastet %index. Fluggerät sofort landen", + "en": "ESC %index overloaded . Land aircraft immediately", + "es": "ESC %index sobrecargado. Aterriza la aeronave de inmediato", + "fr": "Surcharge ESC %index . Atterrissez immédiatement", + "ja": "ESC%index過負荷状態。機体を直ちに着陸させてください", + "ko": "ESC %index 과부하 . 즉시 기체 착륙해야 함", + "ru": "Перегрузка ESC %index . Приземлитесь немедленно", + "tr": "ESC %index aşırı yüklü. Hemen aracı indirin", + "zh": "%index号电机过载,请停止飞行。" + }, + "fpv_tip_0x16080023": { + "de": "Kommunikationsfehler: Motor %index %index. Sofort landen und Fluggerät neu starten", + "en": "Motor %index communication error . Land immediately and restart aircraft", + "es": "Error de comunicación del motor %index. Aterriza de inmediato y reinicia la aeronave", + "fr": "Erreur de communication du moteur %index . Atterrissez immédiatement et redémarrez l\\'appareil", + "ja": "モーター%index通信エラー。直ちに着陸させて、機体を再起動してください", + "ko": "모터 %index 통신 오류 . 즉시 착륙하고 기체 재시작해야 함", + "ru": "Ошибка связи мотора %index . Приземлитесь немедленно и перезагрузите дрон", + "tr": "Motor %index iletişim hatası. Hemen iniş yapın ve aracı yeniden başlatın", + "zh": "%index号电机通信异常,请停止飞行,并重启飞行器。" + }, + "fpv_tip_0x16080024": { + "de": "Motor %index überlastet. Bitte Steuerknüppel loslassen %index", + "en": "Motor %index over-accelerating. Stop pressing control stick", + "es": "Sobreaceleración del motor %index. Deja de presionar la palanca de control", + "fr": "Suraccélération du moteur %index. Ne touchez pas au joystick", + "ja": "モーター%indexが過度に加速。操作スティックを押すのを止めてください", + "ko": "과도한 모터 %index 가속. 조종 스틱 누르기 중지해야 함", + "ru": "Чрезмерное ускорение мотора %index. Отпустите джойстик", + "tr": "Motor %index aşırı hızlanıyor. Kumanda çubuğuna basmayı bırakın", + "zh": "%index号电机油门过高,请回中摇杆。" + }, + "fpv_tip_0x16080025": { + "de": "Kommunikationsfehler: Motor %index %index", + "en": "Motor %index communication error", + "es": "Error de comunicación del motor %index", + "fr": "Erreur de communication du moteur %index", + "ja": "モーター%index通信エラー", + "ko": "모터 %index 통신 오류", + "ru": "Ошибка связи мотора %index", + "tr": "Motor %index iletişim hatası", + "zh": "%index号电机通信异常。" + }, + "fpv_tip_0x16080026": { + "de": "Kommunikationsfehler: Motor %index %index", + "en": "Motor %index communication error", + "es": "Error de comunicación del motor %index", + "fr": "Erreur de communication du moteur %index", + "ja": "モーター%index通信エラー", + "ko": "모터 %index 통신 오류", + "ru": "Ошибка связи мотора %index", + "tr": "Motor %index iletişim hatası", + "zh": "%index号电机通信异常" + }, + "fpv_tip_0x16080027": { + "de": "Kommunikationsfehler: Motor %index", + "en": "Motor %index communication error", + "es": "Error de comunicación del motor %index", + "fr": "Erreur de communication du moteur %index", + "ja": "モーター%index通信エラー", + "ko": "모터 %index 통신 오류", + "ru": "Ошибка связи мотора %index", + "tr": "Motor %index iletişim hatası", + "zh": "%index号电机通信异常" + }, + "fpv_tip_0x16080028": { + "de": "Kommunikationsfehler: Motor %index", + "en": "Motor %index communication error", + "es": "Error de comunicación del motor %index", + "fr": "Erreur de communication du moteur %index", + "ja": "モーター%index通信エラー", + "ko": "모터 %index 통신 오류", + "ru": "Ошибка связи мотора %index", + "tr": "Motor %index iletişim hatası", + "zh": "%index号电机通信异常" + }, + "fpv_tip_0x16080029": { + "de": "Propeller an Motor %index lose oder falsch eingebaut %index", + "en": "Motor %index propeller detached or installed incorrectly", + "es": "Hélice del motor %index no conectada o instalada de forma incorrecta", + "fr": "Hélice du moteur %index détachée ou mal installée", + "ja": "モーター%indexのプロペラが外れているか、または正しく取り付けられていません", + "ko": "모터 %index 프로펠러 분리 또는 제대로 설치 안 됨", + "ru": "Пропеллеры мотора %index отсоединены или неверно установлены", + "tr": "Motor %index kanatları uygun olmayan şekilde sökülmüş ya da takılmış", + "zh": "%index号电机射桨或空载" + }, + "fpv_tip_0x1608002A": { + "de": "ESC %index überhitzt %index", + "en": "ESC %index overheated", + "es": "ESC %index sobrecalentado", + "fr": "Surchauffe ESC %index", + "ja": "ESC%index高温", + "ko": "ESC %index 과열", + "ru": "Перегрев ESC %index", + "tr": "ESC %index aşırı ısındı", + "zh": "%index号电调温度过高" + }, + "fpv_tip_0x1608002B": { + "de": "ESC %index überhitzt", + "en": "ESC %index overheated", + "es": "ESC %index sobrecalentado", + "fr": "Surchauffe ESC %index", + "ja": "ESC %index高温", + "ko": "ESC %index 과열", + "ru": "ESC %index перегрелся", + "tr": "ESC %index aşırı ısındı", + "zh": "%index号电调温度过高" + }, + "fpv_tip_0x1608002C": { + "de": "ESC %index Spannung zu hoch %index", + "en": "ESC %index voltage too high", + "es": "Voltaje de ESC %index demasiado alto", + "fr": "Tension ESC %index trop élevée", + "ja": "ESC%index高電圧", + "ko": "ESC %index 전압 너무 높음", + "ru": "Слишком высокое напряжение ESC %index", + "tr": "ESC %index voltajı çok yüksek", + "zh": "%index号电调电压过高" + }, + "fpv_tip_0x1608002D": { + "de": "ESC %index Spannung zu niedrig %index", + "en": "ESC %index voltage too low", + "es": "Voltaje de ESC %index demasiado bajo", + "fr": "Tension ESC %index trop basse", + "ja": "ESC%index低電圧", + "ko": "ESC %index 전압 너무 낮음", + "ru": "Слишком низкое напряжение ESC %index", + "tr": "ESC %index voltajı çok düşük", + "zh": "%index号电调电压过低" + }, + "fpv_tip_0x1608002E": { + "de": "ESC %index Flash-Speicherfehler %index", + "en": "ESC %index flash memory error", + "es": "Error de memoria flash de ESC %index", + "fr": "Erreur mémoire flash ESC %index", + "ja": "ESC%indexフラッシュメモリのエラー", + "ko": "ESC %index 플래시 메모리 오류", + "ru": "Ошибка флеш-памяти ESC %index", + "tr": "ESC %index flaş bellek hatası", + "zh": "%index号电调闪存异常" + }, + "fpv_tip_0x1608002F": { + "de": "Selbsttest des ESC %index fehlgeschlagen %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC%index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080030": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080031": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080032": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080033": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080034": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080035": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080036": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080037": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080038": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080039": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x1608003a": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x1608003b": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x1608003c": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x1608003d": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x1608003e": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x1608003f": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080040": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080041": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080042": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080043": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080044": { + "de": "Spannung von ESC %index zu niedrig", + "en": "ESC %index voltage too low", + "es": "Voltaje de ESC %index demasiado bajo", + "fr": "Tension ESC %index trop basse", + "ja": "ESC %index低電圧", + "ko": "ESC %index 전압 너무 낮음", + "ru": "Слишком низкое напряжение ESC %index", + "tr": "ESC %index voltajı çok düşük", + "zh": "%index号电调电压过低" + }, + "fpv_tip_0x16080045": { + "de": "Spannung von ESC %index zu hoch", + "en": "ESC %index voltage too high", + "es": "Voltaje de ESC %index demasiado alto", + "fr": "Tension ESC %index trop élevée", + "ja": "ESC %index高電圧", + "ko": "ESC %index 전압 너무 높음", + "ru": "Слишком высокое напряжение ESC %index", + "tr": "ESC %index voltajı çok yüksek", + "zh": "%index号电调电压过高" + }, + "fpv_tip_0x16080046": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080047": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080048": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080049": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x1608004a": { + "de": "ESC %index überhitzt", + "en": "ESC %index overheated", + "es": "ESC %index sobrecalentado", + "fr": "Surchauffe ESC %index", + "ja": "ESC %index高温", + "ko": "ESC %index 과열", + "ru": "ESC %index перегрелся", + "tr": "ESC %index aşırı ısındı", + "zh": "%index号电调温度过高" + }, + "fpv_tip_0x1608004b": { + "de": "ESC %index Temperatur zu niedrig %index", + "en": "ESC %index temperature too low", + "es": "Temperatura de ESC %index demasiado baja", + "fr": "Température ESC %index trop basse", + "ja": "ESC%index低温", + "ko": "ESC %index 온도 너무 낮음", + "ru": "Слишком низкая температура ESC %index", + "tr": "ESC %index sıcaklığı çok düşük", + "zh": "%index号电调温度过低" + }, + "fpv_tip_0x1608004c": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x1608004d": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x1608004e": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x1608004f": { + "de": "Fehler: Selbsttest von ESC %index", + "en": "ESC %index auto-check error", + "es": "Error de comprobación automática de ESC %index", + "fr": "Erreur vérif. auto de l\\'ESC %index", + "ja": "ESC %index自動確認エラー", + "ko": "ESC %index 자체 점검 오류", + "ru": "Ошибка автопроверки ESC %index", + "tr": "ESC %index otomatik kontrol hatası", + "zh": "%index号电调自检异常" + }, + "fpv_tip_0x16080050": { + "de": "ESC-Fehler. Start nicht möglich. Fluggerät neu starten und erneut versuchen", + "en": "ESC error. Unable to take off. Restart aircraft and try again", + "es": "Error de ESC. No se puede despegar. Reinicia la aeronave y vuelve a intentarlo", + "fr": "Erreur de l'ESC Impossible de décoller. Redémarrez l'appareil et réessayez", + "ja": "ESCエラー。離陸できません。機体を再起動し、やり直してください", + "ko": "ESC 오류. 이륙 불가. 기체를 재시작하고 다시 시도하세요.", + "ru": "Ошибка ESC. Не удается выполнить взлет. Перезапустите дрон и повторите попытку", + "tr": "ESC hatası. Kalkış yapılamıyor. Aracı yeniden başlatın ve tekrar deneyin", + "zh": "无法起飞:电调异常,请尝试重启飞行器" + }, + "fpv_tip_0x16080050_in_the_sky": { + "de": "ESC-Fehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "ESC error. Return to home or land promptly", + "es": "Error de ESC. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de l'ESC Retournez au point de départ ou atterrissez rapidement", + "ja": "ESCエラー。直ちに帰還するか、着陸してください", + "ko": "ESC 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка ESC. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "ESC hatası. Eve geri dönün veya derhal iniş yapın", + "zh": "电调异常,请尽快返航或降落" + }, + "fpv_tip_0x16080051": { + "de": "ESC-Fehler. Mit Vorsicht fliegen", + "en": "ESC error. Fly with caution", + "es": "Error de ESC. Vuela con cuidado", + "fr": "Erreur de l'ESC Pilotez avec précaution", + "ja": "ESCエラー。慎重に飛行してください", + "ko": "ESC 오류. 비행 시 주의 필요", + "ru": "Ошибка ESC. Соблюдайте осторожность при полете", + "tr": "ESC hatası. Aracınızı dikkatli uçurun", + "zh": "电调异常,请谨慎飞行" + }, + "fpv_tip_0x16080052": { + "de": "Antriebssystem-Fehler. Propeller gefaltet. Start nicht möglich", + "en": "Propulsion system error. Propellers folded. Unable to take off", + "es": "Error del sistema de propulsión. Hélices plegadas. No se puede despegar", + "fr": "Erreur du système de propulsion. Hélices repliées. Impossible de décoller", + "ja": "推進システムエラー。プロペラが折りたたまれています。離陸できません", + "ko": "추진력 시스템 오류. 프로펠러 접힘. 이륙 불가", + "ru": "Ошибка силовой установки. Пропеллеры сложены. Не удается выполнить взлет", + "tr": "Tahrik sistemi hatası. Pervaneler katlanmış durumda. Kalkış yapılamıyor", + "zh": "无法起飞:动力系统异常,桨叶未展开" + }, + "fpv_tip_0x16080052_in_the_sky": { + "de": "Antriebssystem-Fehler. Propeller gefaltet", + "en": "Propulsion system error. Propellers folded", + "es": "Error del sistema de propulsión. Hélices plegadas", + "fr": "Erreur du système de propulsion. Hélices repliées", + "ja": "推進システムエラー。プロペラが折りたたまれています", + "ko": "추진력 시스템 오류. 프로펠러 접힘", + "ru": "Ошибка силовой установки. Пропеллеры сложены", + "tr": "Tahrik sistemi hatası. Pervaneler katlanmış durumda", + "zh": "动力系统异常,桨叶未展开" + }, + "fpv_tip_0x16080053": { + "de": "ESC-Fehler. Mit Vorsicht fliegen", + "en": "ESC error. Fly with caution", + "es": "Error de ESC. Vuela con cuidado", + "fr": "Erreur de l'ESC Pilotez avec précaution", + "ja": "ESCエラー。慎重に飛行してください", + "ko": "ESC 오류. 비행 시 주의 필요", + "ru": "Ошибка ESC. Соблюдайте осторожность при полете", + "tr": "ESC hatası. Aracınızı dikkatli uçurun", + "zh": "电调异常,请谨慎飞行" + }, + "fpv_tip_0x16080054": { + "de": "ESC-Fehler. Start nicht möglich. Fluggerät neu starten und erneut versuchen", + "en": "ESC error. Unable to take off. Restart aircraft and try again", + "es": "Error de ESC. No se puede despegar. Reinicia la aeronave y vuelve a intentarlo", + "fr": "Erreur de l'ESC Impossible de décoller. Redémarrez l'appareil et réessayez", + "ja": "ESCエラー。離陸できません。機体を再起動し、やり直してください", + "ko": "ESC 오류. 이륙 불가. 기체를 재시작하고 다시 시도하세요.", + "ru": "Ошибка ESC. Не удается выполнить взлет. Перезапустите дрон и повторите попытку", + "tr": "ESC hatası. Kalkış yapılamıyor. Aracı yeniden başlatın ve tekrar deneyin", + "zh": "无法起飞:电调异常,请尝试重启飞行器" + }, + "fpv_tip_0x16080054_in_the_sky": { + "de": "ESC-Fehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "ESC error. Return to home or land promptly", + "es": "Error de ESC. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de l'ESC Retournez au point de départ ou atterrissez rapidement", + "ja": "ESCエラー。直ちに帰還するか、着陸してください", + "ko": "ESC 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка ESC. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "ESC hatası. Eve geri dönün veya derhal iniş yapın", + "zh": "电调异常,请尽快返航或降落" + }, + "fpv_tip_0x16080055": { + "ar": "", + "de": "Motor %index überhitzt. Fluggerät sofort landen", + "en": "Motor %index overheated. Land aircraft immediately", + "es": "Motor %index sobrecalentado. Aterrice la aeronave de inmediato", + "fr": "Surchauffe du moteur %index. Faire atterrir l'appareil immédiatement", + "id": "", + "it": "", + "ja": "モーター%indexがオーバーヒートしました。機体を直ちに着陸させてください", + "ko": "모터 %index 과열 상태입니다. 기기를 즉시 착륙시키세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Двигатель %index перегрелся. Немедленно посадите дрон", + "th": "", + "tr": "Motor %index aşırı ısındı. Hava aracını derhal indirin", + "ug": "", + "vi": "", + "zh": "%index号电机温度较高,请尽快降落", + "zh-Hant": "" + }, + "fpv_tip_0x16080056": { + "ar": "", + "de": "Motor %index überhitzt. Fluggerät landet möglicherweise automatisch", + "en": "Motor %index overheated. Aircraft may be auto landing", + "es": "Motor %index sobrecalentado. La aeronave puede realizar un aterrizaje automático", + "fr": "Surchauffe du moteur %index. L'appareil peut atterrir automatiquement", + "id": "", + "it": "", + "ja": "モーター%indexがオーバーヒートしました。機体が自動着陸中の可能性があります", + "ko": "모터 %index 과열 상태입니다. 기체가 자동 착륙할 수 있습니다", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Двигатель %index перегрелся. Дрон может совершать автоматическую посадку", + "th": "", + "tr": "Motor %index aşırı ısındı. Hava aracı otomatik iniş yapıyor olabilir", + "ug": "", + "vi": "", + "zh": "%index号电机温度过高,飞机可能降落", + "zh-Hant": "" + }, + "fpv_tip_0x16080056_in_the_sky": { + "ar": "", + "de": "Motor %index -Temperatur zu hoch. Fluggeschwindigkeit beschränkt.", + "en": "Motor %index temperature too high. Flight speed limited", + "es": "Temperatura del motor %index demasiado alta. Velocidad de vuelo limitada", + "fr": "Température moteur %index trop élevée. Vitesse de vol limitée", + "id": "", + "it": "", + "ja": "モーター%indexの温度が高すぎます。飛行速度が制限されている", + "ko": "모터 %index 온도 너무 높음. 비행 속도 제한됨", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Слишком высокая температура мотора %index. Скорость полета ограничена", + "th": "", + "tr": "Motor %index sıcaklığı çok yüksek. Uçuş hızı sınırlı", + "ug": "", + "vi": "", + "zh": "%index号电机温度过高,飞机可能降落", + "zh-Hant": "" + }, + "fpv_tip_0x16080057": { + "de": "ESC-Fehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "ESC error. Return to home or land promptly", + "es": "Error de ESC. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de l'ESC Retournez au point de départ ou atterrissez rapidement", + "ja": "ESCエラー。直ちに帰還するか、着陸してください", + "ko": "ESC 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка ESC. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "ESC hatası. Eve geri dönün veya derhal iniş yapın", + "zh": "电调异常,请尽快返航或降落" + }, + "fpv_tip_0x16080057_in_the_sky": { + "de": "ESC-Fehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "ESC error. Return to home or land promptly", + "es": "Error de ESC. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de l'ESC Retournez au point de départ ou atterrissez rapidement", + "ja": "ESCエラー。直ちに帰還するか、着陸してください", + "ko": "ESC 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка ESC. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "ESC hatası. Eve geri dönün veya derhal iniş yapın", + "zh": "电调异常,请尽快返航或降落" + }, + "fpv_tip_0x16080058": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x16080058_in_the_sky": { + "de": "ESC-Fehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "ESC error. Return to home or land promptly", + "es": "Error de ESC. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de l'ESC Retournez au point de départ ou atterrissez rapidement", + "ja": "ESCエラー。直ちに帰還するか、着陸してください", + "ko": "ESC 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка ESC. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "ESC hatası. Eve geri dönün veya derhal iniş yapın", + "zh": "电调异常,请尽快返航或降落" + }, + "fpv_tip_0x16080059": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x16080059_in_the_sky": { + "de": "ESC-Fehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "ESC error. Return to home or land promptly", + "es": "Error de ESC. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de l'ESC Retournez au point de départ ou atterrissez rapidement", + "ja": "ESCエラー。直ちに帰還するか、着陸してください", + "ko": "ESC 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка ESC. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "ESC hatası. Eve geri dönün veya derhal iniş yapın", + "zh": "电调异常,请尽快返航或降落" + }, + "fpv_tip_0x1608005A": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "it": "", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "pt": "", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x1608005A_in_the_sky": { + "de": "ESC-Fehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "ESC error. Return to home or land promptly", + "es": "Error de ESC. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de l'ESC Retournez au point de départ ou atterrissez rapidement", + "ja": "ESCエラー。直ちに帰還するか、着陸してください", + "ko": "ESC 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка ESC. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "ESC hatası. Eve geri dönün veya derhal iniş yapın", + "zh": "电调异常,请尽快返航或降落" + }, + "fpv_tip_0x1608005B": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "it": "", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "pt": "", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x1608005B_in_the_sky": { + "de": "ESC-Fehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "ESC error. Return to home or land promptly", + "es": "Error de ESC. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de l'ESC Retournez au point de départ ou atterrissez rapidement", + "ja": "ESCエラー。直ちに帰還するか、着陸してください", + "ko": "ESC 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка ESC. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "ESC hatası. Eve geri dönün veya derhal iniş yapın", + "zh": "电调异常,请尽快返航或降落" + }, + "fpv_tip_0x1608005C": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "it": "", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "pt": "", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x1608005C_in_the_sky": { + "de": "ESC-Fehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "ESC error. Return to home or land promptly", + "es": "Error de ESC. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de l'ESC Retournez au point de départ ou atterrissez rapidement", + "ja": "ESCエラー。直ちに帰還するか、着陸してください", + "ko": "ESC 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка ESC. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "ESC hatası. Eve geri dönün veya derhal iniş yapın", + "zh": "电调异常,请尽快返航或降落" + }, + "fpv_tip_0x1608005D": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "it": "", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "pt": "", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x1608005D_in_the_sky": { + "de": "ESC-Fehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "ESC error. Return to home or land promptly", + "es": "Error de ESC. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de l'ESC Retournez au point de départ ou atterrissez rapidement", + "ja": "ESCエラー。直ちに帰還するか、着陸してください", + "ko": "ESC 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка ESC. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "ESC hatası. Eve geri dönün veya derhal iniş yapın", + "zh": "电调异常,请尽快返航或降落" + }, + "fpv_tip_0x1608005E": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "it": "", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "pt": "", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x1608005F": { + "ar": "", + "de": "Motor %index überhitzt. Fluggerät landet automatisch", + "en": "Motor %index overheated. Aircraft auto landing", + "es": "Motor %index sobrecalentado. Aterrizaje automático de la aeronave", + "fr": "Surchauffe du moteur %index. Atterrissage automatique de l'appareil", + "id": "", + "it": "", + "ja": "モーター%indexがオーバーヒートしました。機体が自動着陸中", + "ko": "모터 %index 과열 상태입니다. 기체 자동 착륙", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Двигатель %index перегрелся. Автоматическая посадка дрона", + "th": "", + "tr": "Motor %index aşırı ısındı. Araç otomatik iniş yapıyor", + "ug": "", + "vi": "", + "zh": "%index号电机超温,强制降落", + "zh-Hant": "" + }, + "fpv_tip_0x1608005a": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x1608005b": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x1608005c": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x1608005d": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x1608005e": { + "de": "ESC-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de l'ESC Impossible de décoller. Contactez le Service client DJI", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류. 이륙 불가. DJI 고객지원으로 문의하세요.", + "ru": "Ошибка ESC. Не удается выполнить взлет. Свяжитесь со службой поддержки DJI", + "tr": "ESC hatası. Kalkış yapılamıyor. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后" + }, + "fpv_tip_0x1608005e_in_the_sky": { + "de": "ESC-Fehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "ESC error. Return to home or land promptly", + "es": "Error de ESC. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de l'ESC Retournez au point de départ ou atterrissez rapidement", + "ja": "ESCエラー。直ちに帰還するか、着陸してください", + "ko": "ESC 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка ESC. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "ESC hatası. Eve geri dönün veya derhal iniş yapın", + "zh": "电调异常,请尽快返航或降落" + }, + "fpv_tip_0x16080077": { + "ar": "", + "de": "", + "en": "%index ESC overheated (%alarmid)", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%index号电调严重超温(%alarmid)", + "zh-Hant": "" + }, + "fpv_tip_0x16080078": { + "ar": "", + "de": "", + "en": "%index ESC overheated (%alarmid)", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%index号电调严重超温(%alarmid)", + "zh-Hant": "" + }, + "fpv_tip_0x16080079": { + "ar": "", + "de": "", + "en": "%index ESC firmware incompatible with aircraft model (%alarmid)", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%index号电调固件与飞机机型不匹配(%alarmid)", + "zh-Hant": "" + }, + "fpv_tip_0x1608007A": { + "ar": "", + "de": "", + "en": "%index ESC firmware incompatible with aircraft model (%alarmid)", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%index号电调固件与飞机机型不匹配(%alarmid)", + "zh-Hant": "" + }, + "fpv_tip_0x1608007B": { + "ar": "", + "de": "", + "en": "%index ESC auto-check error (%alarmid)", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%index号电调自检异常(%alarmid)", + "zh-Hant": "" + }, + "fpv_tip_0x1608007C": { + "ar": "", + "de": "", + "en": "%index ESC auto-check error (%alarmid)", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%index号电调自检异常(%alarmid)", + "zh-Hant": "" + }, + "fpv_tip_0x1608007D": { + "ar": "", + "de": "", + "en": "%index ESC or motor auto-check error (%alarmid)", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%index号电调或电机自检异常(%alarmid)", + "zh-Hant": "" + }, + "fpv_tip_0x1608007E": { + "ar": "", + "de": "", + "en": "%index ESC or motor auto-check error (%alarmid)", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%index号电调或电机自检异常(%alarmid)", + "zh-Hant": "" + }, + "fpv_tip_0x1608007F": { + "ar": "", + "de": "", + "en": "%index ESC or motor auto-check error (%alarmid)", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%index号电调或电机自检异常(%alarmid)", + "zh-Hant": "" + }, + "fpv_tip_0x16080080": { + "ar": "", + "de": "", + "en": "%index ESC or motor auto-check error (%alarmid)", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "%index号电调或电机自检异常(%alarmid)", + "zh-Hant": "" + }, + "fpv_tip_0x16090050": { + "de": "%battery_index Akku: Stromversorgungsfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery power supply error. Return to home or land promptly", + "es": "Error de fuente de alimentación de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur d'alimentation de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー電源エラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 전력 공급 장치 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: ошибка источника питания. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil güç kaynağı hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池供电异常,请尽快返航或降落" + }, + "fpv_tip_0x16090051": { + "de": "%battery_index Akku: Stromversorgungsfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery power supply error. Return to home or land promptly", + "es": "Error de fuente de alimentación de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur d'alimentation de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー電源エラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 전력 공급 장치 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: ошибка источника питания. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil güç kaynağı hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池供电异常,请尽快返航或降落" + }, + "fpv_tip_0x16090052": { + "de": "%battery_index Akku: Temperatursensorfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery temperature sensor error. Return to home or land promptly", + "es": "Error del sensor de temperatura de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur capteur de température de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー温度センサーエラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 온도 센서 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: ошибка датчика температуры. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil sıcaklık sensörü hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池温度传感器异常,请尽快返航或降落" + }, + "fpv_tip_0x16090061": { + "de": "%battery_index Akku: Überhitzt. Umgehend zum Startpunkt zurückkehren oder landen. Akku nicht mehr verwenden", + "en": "%battery_index Battery overheated. Return to home or land promptly. Stop using battery", + "es": "Batería %battery_index sobrecalentada. Regrese al punto de origen o aterrice rápidamente. Deje de usar la batería.", + "fr": "Surchauffe batterie %battery_index. Retourner au point de départ ou atterrir rapidement. Cesser d'utiliser la batterie", + "ja": "%battery_index バッテリー高温。 直ちに帰還するか、着陸してください。 バッテリーの使用を中止してください", + "ko": "%battery_index 배터리 과열됨. 즉시 리턴 투 홈을 실행하거나 착륙하세요. 배터리 사용을 중지하세요.", + "ru": "Перегрев %battery_index АКБ. Как можно скорее вернитесь на базу или приземлитесь. Прекратите использовать АКБ", + "tr": "%battery_index Pil aşırı ısındı. Başlangıç noktasına geri dönün veya derhal iniş yapın. Pili kullanmayı bırakın", + "zh": "%battery_index电池温度过高,请尽快返航或降落,停止使用该电池" + }, + "fpv_tip_0x16090062": { + "de": "%battery_index Akku: MOS-Temperatur zu hoch. Umgehend zum Startpunkt zurückkehren oder landen. %battery_index Akku: Warten, bis Akku abgekühlt ist", + "en": "%battery_index Battery MOS temperature too high. Return to home or land promptly. Wait until %battery_index Battery cools down", + "es": "Temperatura del MOS de la batería %battery_index demasiado alta. Regrese al punto de origen o aterrice rápidamente. Espere a que se enfríe la batería %battery_index.", + "fr": "Température MOS de la batterie %battery_index excessive. Retourner au point de départ ou atterrir rapidement. Attendre que la batterie %battery_index refroidisse", + "ja": "%battery_index バッテリー MOS 温度が高すぎます。 直ちに帰還するか、着陸してください。 %battery_index バッテリーが冷えるまでお待ちください", + "ko": "%battery_index 배터리 MOS 온도가 너무 높음. 즉시 리턴 투 홈을 실행하거나 착륙하세요. %battery_index 배터리가 식을 때까지 기다려 주세요.", + "ru": "%battery_index АКБ: слишком высокая температура MOS. Как можно скорее вернитесь на базу или приземлитесь. Подождите, пока %battery_index АКБ остынет", + "tr": "%battery_index Pil MOS sıcaklığı çok yüksek. Başlangıç noktasına geri dönün veya derhal iniş yapın. %battery_index Pil soğuyana kadar bekleyin", + "zh": "%battery_index电池MOS温度过高,请尽快返航或降落,等待%battery_index电池温度降低" + }, + "fpv_tip_0x16090063": { + "de": "%battery_index Akku: Spannung zu hoch. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery voltage too high. Return to home or land promptly", + "es": "Voltaje de la batería %battery_index demasiado alto. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Tension de batterie %battery_index excessive. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー電圧が高すぎます。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 전압이 너무 높음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: слишком высокое напряжение. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil gerilimi çok yüksek. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池总电压过高,请尽快返航或降落" + }, + "fpv_tip_0x16090064": { + "de": "%battery_index Akku: Spannung zu niedrig. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery voltage too low. Return to home or land promptly", + "es": "Voltaje de la batería %battery_index demasiado bajo. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Tension de batterie %battery_index trop basse. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー電圧が低すぎます。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 전압이 너무 낮음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: слишком низкое напряжение. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil gerilimi çok düşük. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池总电压过低,请尽快返航或降落" + }, + "fpv_tip_0x16090065": { + "de": "%battery_index Akku: Spannung einer einzelnen Akkuzelle zu hoch. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery single cell voltage too high. Return to home or land promptly", + "es": "Voltaje de la célula individual de la batería %battery_index demasiado alto. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Tension de cellule unique de la batterie %battery_index excessive. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー 1セルの電圧が高すぎます。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 단일 셀 전압이 너무 높음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: слишком высокое напряжение отдельной ячейки. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil tek hücre gerilimi çok yüksek. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池单电芯电压过高,请尽快返航或降落" + }, + "fpv_tip_0x16090066": { + "de": "%battery_index Akku: Spannung einer einzelnen Akkuzelle zu niedrig. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery single cell voltage too low. Return to home or land promptly", + "es": "Voltaje de la célula individual de la batería %battery_index demasiado bajo. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Tension de cellule unique de la batterie %battery_index trop basse. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー 1セルの電圧が低すぎます。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 단일 셀 전압이 너무 낮음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: слишком низкое напряжение отдельной ячейки. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil tek hücre gerilimi çok düşük. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池单电芯电压过低,请尽快返航或降落" + }, + "fpv_tip_0x16090067": { + "de": "%battery_index Akku: Großer Unterschied bei statischen Spannungen zwischen Akkuzellen. Akku nicht mehr verwenden", + "en": "Large static voltage difference between %battery_index Battery cells. Stop using battery", + "es": "Gran diferencia entre los voltajes estáticos de las células de la batería %battery_index. Deje de usar la batería.", + "fr": "Différence importante entre les tensions statiques des cellules de batterie %battery_index. Cesser d'utiliser la batterie", + "ja": "%battery_index バッテリーセル間の静電電圧差が大きすぎます。 バッテリーの使用を中止してください", + "ko": "%battery_index 배터리 셀 간 정전압 차가 너무 큼. 배터리 사용을 중지하세요.", + "ru": "Большая разница между статическими напряжениями ячеек %battery_index АКБ. Прекратите использовать АКБ", + "tr": "%battery_index Pil hücreleri arasındaki statik gerilim farkı yüksek. Pili kullanmayı bırakın", + "zh": "%battery_index电池静态压差过大,请停止使用该电池" + }, + "fpv_tip_0x16090068": { + "de": "%battery_index Akku: Großer Unterschied bei Ladespannungen zwischen Akkuzellen. Umgehend zum Startpunkt zurückkehren oder landen. Akku nicht mehr verwenden", + "en": "Large charge voltage difference between %battery_index Battery cells. Return to home or land promptly. Stop using battery", + "es": "Gran diferencia entre los voltajes de carga de las células de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente. Deje de usar la batería.", + "fr": "Différence de charge importante entre les cellules de batterie %battery_index. Retourner au point de départ ou atterrir rapidement. Cesser d'utiliser la batterie", + "ja": "%battery_index バッテリーセル間の充電電圧差が大きすぎます。 直ちに帰還するか、着陸してください。 バッテリーの使用を中止してください", + "ko": "%battery_index 배터리 셀 간 충전 전압 차가 너무 큼. 즉시 리턴 투 홈을 실행하거나 착륙하세요. 배터리 사용을 중지하세요.", + "ru": "Большая разница между напряжениями заряда ячеек %battery_index АКБ. Как можно скорее вернитесь на базу или приземлитесь. Прекратите использовать АКБ", + "tr": "%battery_index Pil hücreleri arasındaki şarj gerilim farkı yüksek. Başlangıç noktasına geri dönün veya derhal iniş yapın. Pili kullanmayı bırakın", + "zh": "%battery_index电池充电电芯间压差过大,请尽快返航或降落,并停止使用该电池" + }, + "fpv_tip_0x16090069": { + "de": "%battery_index Akku: Großer Unterschied bei Entladespannungen zwischen Akkuzellen. Umgehend zum Startpunkt zurückkehren oder landen. Akku nicht mehr verwenden", + "en": "Large discharge voltage difference between %battery_index Battery cells. Return to home or land promptly. Stop using battery", + "es": "Gran diferencia entre los voltajes de descarga de las células de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente. Deje de usar la batería.", + "fr": "Différence de décharge importante entre les cellules de batterie %battery_index. Retourner au point de départ ou atterrir rapidement. Cesser d'utiliser la batterie", + "ja": "%battery_index バッテリーセル間の放電電圧差が大きすぎます。 直ちに帰還するか、着陸してください。 バッテリーの使用を中止してください", + "ko": "%battery_index 배터리 셀 간 방전 전압 차가 너무 큼. 즉시 리턴 투 홈을 실행하거나 착륙하세요. 배터리 사용을 중지하세요.", + "ru": "Большая разница между напряжениями разряда ячеек %battery_index АКБ. Как можно скорее вернитесь на базу или приземлитесь. Прекратите использовать АКБ", + "tr": "%battery_index Pil hücreleri arasındaki deşarj gerilim farkı yüksek. Başlangıç noktasına geri dönün veya derhal iniş yapın. Pili kullanmayı bırakın", + "zh": "%battery_index电池放电电芯间压差过大,请尽快返航或降落,并停止使用该电池" + }, + "fpv_tip_0x1609006A": { + "de": "%battery_index Akku: MOS-Verbindungsfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery MOS connection error. Return to home or land promptly", + "es": "Error de conexión del MOS de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur de connexion MOS de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー MOS 接続エラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 MOS 연결 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: ошибка подключения MOS. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil MOS bağlantı hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池MOS连接异常,请尽快返航或降落" + }, + "fpv_tip_0x1609006B": { + "de": "%battery_index Akku: MOS-Impedanzfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery MOS impedance error. Return to home or land promptly", + "es": "Error de impedancia del MOS de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur d'impédance MOS de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー MOS インピーダンスエラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 MOS 임피던스 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: ошибка сопротивления MOS. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil MOS empedans hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池MOS阻抗异常,请尽快返航或降落" + }, + "fpv_tip_0x1609006C": { + "de": "%battery_index Akku: Alterung. Die Flugsicherheit ist möglicherweise beeinträchtigt. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery aging. Flight safety may be affected. Return to home or land promptly", + "es": "Envejecimiento de la batería %battery_index. La seguridad de vuelo puede verse afectada. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Vieillissement de la batterie %battery_index. La sécurité en vol peut être affectée. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー劣化。 飛行安全性に影響する可能性があります。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 노화. 비행 안전에 영향을 줄 수 있음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "Износ %battery_index АКБ. Это может повлиять на безопасность полета. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil eski. Uçuş güvenliği etkilenebilir. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池老化,可能影响飞行安全,请尽快返航或降落" + }, + "fpv_tip_0x1609006D": { + "de": "%battery_index Akku: Mikro-Kurzschluss aufgetreten. Die Flugsicherheit ist möglicherweise beeinträchtigt. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery experienced micro short circuit. Flight safety may be affected. Return to home or land promptly", + "es": "La batería %battery_index sufrió un microcortocircuito. La seguridad de vuelo puede verse afectada. Regrese al punto de origen o aterrice rápidamente.", + "fr": "La batterie %battery_index a subi un micro court-circuit. La sécurité en vol peut être affectée. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリーでマイクロ短絡が発生しました。 飛行安全性に影響する可能性があります。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리에 마이크로 단락 발생. 비행 안전에 영향을 줄 수 있음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: произошло микрозамыкание. Это может повлиять на безопасность полета. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pilde mikro kısa devre oldu. Uçuş güvenliği etkilenebilir. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池微短路,可能影响飞行安全,请尽快返航或降落" + }, + "fpv_tip_0x1609006F": { + "de": "%battery_index Akku: Anschlusstemperatur zu hoch. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery connector temperature too high. Return to home or land promptly", + "es": "Temperatura del conector de la batería %battery_index demasiado alta. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Température du connecteur de la batterie %battery_index excessive. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリーコネクターの温度が高すぎます。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 커넥터 온도가 너무 높음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: слишком высокая температура разъема. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil konektör sıcaklığı çok yüksek. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池连接器温度过高,请尽快返航或降落" + }, + "fpv_tip_0x16090070": { + "de": "%battery_index Akku: Spannung zu niedrig. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery voltage too low. Return to home or land promptly", + "es": "Voltaje de la batería %battery_index demasiado bajo. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Tension de batterie %battery_index trop basse. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー電圧が低すぎます。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 전압이 너무 낮음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: слишком низкое напряжение. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil gerilimi çok düşük. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池电压过低,请尽快返航或降落" + }, + "fpv_tip_0x16090071": { + "ar": "", + "de": "", + "en": "Battery overvoltage protection", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "电池电压过压保护", + "zh-Hant": "" + }, + "fpv_tip_0x16090072": { + "de": "%battery_index Akku: Überstrom beim Laden. Ladegerät überprüfen", + "en": "%battery_index Battery overcurrent when charging. Check charging device", + "es": "Sobrecorriente de la batería %battery_index durante la carga. Compruebe el dispositivo de carga.", + "fr": "Surintensité de la batterie %battery_index lors de la charge. Vérifier le chargeur", + "ja": "充電時の %battery_index バッテリーの過電流。 充電器を確認してください", + "ko": "충전 중 %battery_index 배터리 과전류 발생. 충전 기기를 확인하세요.", + "ru": "%battery_index АКБ: перегрузка по току при зарядке. Проверьте зарядное устройство", + "tr": "Şarj olurken %battery_index Pil aşırı akımı. Şarj cihazını kontrol edin", + "zh": "%battery_index电池充电过流,请检查充电设备" + }, + "fpv_tip_0x16090073": { + "de": "%battery_index Akku: Überstrom beim Entladen. Überprüfen, ob Fluggerät überladen ist", + "en": "%battery_index Battery overcurrent when discharging. Check if aircraft is overloaded", + "es": "Sobrecorriente de la batería %battery_index durante la descarga. Compruebe si la aeronave está sobrecargada.", + "fr": "Surintensité de la batterie %battery_index lors de la décharge. Vérifier si l'appareil est surchargé", + "ja": "放電時の %battery_index バッテリーの過電流。 機体が過負荷になっていないかを確認してください", + "ko": "방전 중 %battery_index 배터리 과전류 발생. 기체 과부화 여부를 확인하세요.", + "ru": "%battery_index АКБ: перегрузка по току при разрядке. Проверьте, не перегружен ли дрон", + "tr": "Deşarj olurken %battery_index Pil aşırı akımı. Aracın aşırı yüklenip yüklenmediğini kontrol edin", + "zh": "%battery_index电池放电过流,请检查飞行器是否有负重" + }, + "fpv_tip_0x16090074": { + "de": "%battery_index Akku: Tiefentladung. Überprüfen, ob Fluggerät überladen ist", + "en": "%battery_index Battery over discharged. Check if aircraft is overloaded", + "es": "Descarga excesiva de la batería %battery_index. Compruebe si la aeronave está sobrecargada.", + "fr": "Batterie %battery_index trop déchargée. Vérifier si l'appareil est surchargé", + "ja": "%battery_index バッテリー過放電エラー。 機体が過負荷になっていないかを確認してください", + "ko": "%battery_index 배터리 과다 방전됨. 기체 과부화 여부를 확인하세요.", + "ru": "%battery_index АКБ: чрезмерная разрядка. Проверьте, не перегружен ли дрон", + "tr": "%battery_index Pil fazla deşarj edildi. Aracın aşırı yüklenip yüklenmediğini kontrol edin", + "zh": "%battery_index电池放电过载,请检查飞行器是否有负重" + }, + "fpv_tip_0x16090075": { + "de": "%battery_index Akku: Systemfehler. Akku neu starten und erneut versuchen", + "en": "%battery_index Battery system error. Restart %battery_index Battery and try again", + "es": "Error del sistema de la batería %battery_index. Reinicie la batería %battery_index e inténtelo de nuevo.", + "fr": "Erreur système de la batterie %battery_index. Redémarrer la batterie %battery_index et réessayer", + "ja": "%battery_index バッテリーシステムエラー。 %battery_index バッテリーを再起動し、やり直してください", + "ko": "%battery_index 배터리 시스템 오류. %battery_index 배터리를 재시동한 후 다시 시도하세요.", + "ru": "%battery_index АКБ: ошибка системы. Перезагрузите %battery_index АКБ и повторите попытку", + "tr": "%battery_index Pil sistem hatası. %battery_index Pili yeniden başlatıp tekrar deneyin", + "zh": "%battery_index电池系统异常,请重启%battery_index电池后重试" + }, + "fpv_tip_0x16090076": { + "de": "%battery_index Akku: Interner Modulfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery internal module error. Return to home or land promptly", + "es": "Error del módulo interno de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur de module interne de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー内部モジュールエラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 내부 모듈 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: внутренняя ошибка модуля. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil dahili modül hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池内部模块异常,请尽快返航或降落" + }, + "fpv_tip_0x16090077": { + "de": "%battery_index Akku: Ladetemperatur zu hoch. Ladevorgang beenden und warten, bis Akku abgekühlt ist", + "en": "%battery_index Battery charging temperature too high. Stop charging and wait until %battery_index Battery cools down", + "es": "Temperatura de carga de la batería %battery_index demasiado alta. Deje de cargar y espere a que se enfríe la batería %battery_index.", + "fr": "Température de charge de la batterie %battery_index excessive. Arrêter la charge et attendre que la batterie %battery_index refroidisse", + "ja": "%battery_index バッテリー充電温度が高すぎます。 充電を中止し、%battery_index バッテリーが冷えるまでお待ちください", + "ko": "%battery_index 배터리 충전 온도가 너무 높음. 충전을 중지하고 %battery_index 배터리가 식을 때까지 기다려 주세요.", + "ru": "%battery_index АКБ: слишком высокая температура зарядки. Прекратите зарядку и подождите, пока %battery_index АКБ остынет", + "tr": "%battery_index Pil şarj etme sıcaklığı çok yüksek. Şarjı durdurun ve %battery_index Pil soğuyana kadar bekleyin", + "zh": "%battery_index电池充电温度过高,禁止充电,等待%battery_index电池温度降低" + }, + "fpv_tip_0x16090078": { + "de": "%battery_index Akku: Entladetemperatur zu hoch. Umgehend zum Startpunkt zurückkehren oder landen. %battery_index Akku: Warten, bis Akku abgekühlt ist", + "en": "%battery_index Battery discharging temperature too high. Return to home or land promptly. Wait until %battery_index Battery cools down", + "es": "Temperatura de descarga de la batería %battery_index demasiado alta. Regrese al punto de origen o aterrice rápidamente. Espere a que se enfríe la batería %battery_index.", + "fr": "Température de décharge de la batterie %battery_index excessive. Retourner au point de départ ou atterrir rapidement. Attendre que la batterie %battery_index refroidisse", + "ja": "%battery_index バッテリーの放電温度が高すぎます。 直ちに帰還するか、着陸してください。 %battery_index バッテリーが冷えるまでお待ちください", + "ko": "%battery_index 배터리 방전 온도가 너무 높음. 즉시 리턴 투 홈을 실행하거나 착륙하세요. %battery_index 배터리가 식을 때까지 기다려 주세요.", + "ru": "%battery_index АКБ: слишком высокая температура разрядки. Как можно скорее вернитесь на базу или приземлитесь. Подождите, пока %battery_index АКБ остынет", + "tr": "%battery_index Pil deşarj etme sıcaklığı çok yüksek. Başlangıç noktasına geri dönün veya derhal iniş yapın. %battery_index Pil soğuyana kadar bekleyin", + "zh": "%battery_index电池放电温度过高,请尽快返航或降落,等待%battery_index电池温度降低" + }, + "fpv_tip_0x16090079": { + "de": "%battery_index Akku: Ladetemperatur zu niedrig. Akku vor dem Laden aufwärmen", + "en": "%battery_index Battery charging temperature too low. Warm up %battery_index Battery before charging", + "es": "Temperatura de carga de la batería %battery_index demasiado baja. Caliente la batería %battery_index antes de cargarla", + "fr": "Température de charge de la batterie %battery_index trop basse. Réchauffer la batterie %battery_index avant la charge", + "ja": "%battery_index バッテリー充電温度が低すぎます。 充電前に %battery_index バッテリーをウォームアップしてください", + "ko": "%battery_index 배터리 충전 온도가 너무 낮음. 충전하기 전에 %battery_index 배터리를 예열하세요.", + "ru": "%battery_index АКБ: слишком низкая температура зарядки. Прогрейте %battery_index АКБ перед зарядкой", + "tr": "%battery_index Pil şarj etme sıcaklığı çok düşük. Şarj etmeden önce %battery_index Pili ısıtın", + "zh": "%battery_index电池充电温度过低,禁止充电,请预热%battery_index电池后充电" + }, + "fpv_tip_0x1609007A": { + "de": "%battery_index Akku: Entladetemperatur zu niedrig. Umgehend zum Startpunkt zurückkehren oder landen. Akku vor dem Start aufwärmen", + "en": "%battery_index Battery discharging temperature too low. Return to home or land promptly. Warm up %battery_index Battery before takeoff", + "es": "Temperatura de descarga de la batería %battery_index demasiado baja. Regrese al punto de origen o aterrice rápidamente. Caliente la batería %battery_index antes del despegue.", + "fr": "Température de décharge de la batterie %battery_index trop basse. Retourner au point de départ ou atterrir rapidement. Réchauffer la batterie %battery_index avant le décollage", + "ja": "%battery_index バッテリーの放電温度が低すぎます。 直ちに帰還するか、着陸してください。 離陸前に %battery_index バッテリーをウォームアップしてください", + "ko": "%battery_index 배터리 방전 온도가 너무 낮음. 즉시 리턴 투 홈을 실행하거나 착륙하세요. 이륙하기 전에 %battery_index 배터리를 예열하세요.", + "ru": "%battery_index АКБ: слишком низкая температура разрядки. Как можно скорее вернитесь на базу или приземлитесь. Прогрейте %battery_index АКБ перед взлетом", + "tr": "%battery_index Pil deşarj etme sıcaklığı çok düşük. Başlangıç noktasına geri dönün veya derhal iniş yapın. Kalkıştan önce %battery_index Pili ısıtın", + "zh": "%battery_index电池放电温度过低,请尽快返航或降落,请预热%battery_index电池后再起飞" + }, + "fpv_tip_0x1609007B": { + "de": "%battery_index Akku: Spannung zu hoch. %battery_index Akku: Vor dem Start wieder einsetzen", + "en": "%battery_index Battery voltage too high. Reinstall %battery_index Battery before takeoff", + "es": "Voltaje de la batería %battery_index demasiado alto. Reinstale la batería %battery_index antes del despegue.", + "fr": "Tension de batterie %battery_index excessive. Réinstallez la batterie %battery_index avant le décollage", + "ja": "%battery_index バッテリー電圧が高すぎます。 離陸前に %battery_index バッテリーを取り付け直してください", + "ko": "%battery_index 배터리 전압이 너무 높음. 이륙하기 전에 %battery_index 배터리를 다시 장착하세요.", + "ru": "%battery_index АКБ: слишком высокое напряжение. Повторно установите %battery_index АКБ перед взлетом", + "tr": "%battery_index Pil gerilimi çok yüksek. Kalkıştan önce %battery_index Pili yeniden takın", + "zh": "%battery_index电池电压过高,请拔插%battery_index电池后再起飞" + }, + "fpv_tip_0x1609007C": { + "de": "%battery_index Akku: Spannung zu niedrig. %battery_index Akku: Vor dem Start wieder einsetzen", + "en": "%battery_index Battery voltage too low. Reinstall %battery_index Battery before takeoff", + "es": "Voltaje de la batería %battery_index demasiado bajo. Reinstale la batería %battery_index antes del despegue.", + "fr": "Tension de batterie %battery_index trop basse. Réinstallez la batterie %battery_index avant le décollage", + "ja": "%battery_index バッテリー電圧が低すぎます。 離陸前に %battery_index バッテリーを取り付け直してください", + "ko": "%battery_index 배터리 전압이 너무 낮음. 이륙하기 전에 %battery_index 배터리를 다시 장착하세요.", + "ru": "%battery_index АКБ: слишком низкое напряжение. Повторно установите %battery_index АКБ перед взлетом", + "tr": "%battery_index Pil gerilimi çok düşük. Kalkıştan önce %battery_index Pili yeniden takın", + "zh": "%battery_index电池电压过低,请拔插%battery_index电池后再起飞" + }, + "fpv_tip_0x1609007D": { + "de": "Spannung des Ladegeräts zu hoch. Gerät überprüfen", + "en": "Charging device voltage too high. Check device", + "es": "Voltaje del dispositivo de carga demasiado alto. Compruebe el dispositivo", + "fr": "Tension du chargeur trop élevée. Vérifier l'appareil", + "it": "", + "ja": "充電器の電圧が高すぎます。機器を確認してください", + "ko": "충전 기기 전압이 너무 높음. 기기를 확인하세요", + "pt": "", + "ru": "Напряжение зарядного устройства слишком высокое. Проверьте устройство", + "tr": "Şarj cihazı gerilimi çok yüksek. Cihazı kontrol edin", + "zh": "充电器电压过高,请检查充电设备" + }, + "fpv_tip_0x1609007E": { + "de": "Spannung des Ladegeräts zu niedrig. Gerät überprüfen", + "en": "Charging device voltage too low. Check device", + "es": "Voltaje del dispositivo de carga demasiado bajo. Compruebe el dispositivo", + "fr": "Tension du chargeur trop faible. Vérifier l'appareil", + "it": "", + "ja": "充電器の電圧が低すぎます。機器を確認してください", + "ko": "충전 기기 전압이 너무 낮음. 기기를 확인하세요", + "pt": "", + "ru": "Напряжение зарядного устройства слишком низкое. Проверьте устройство", + "tr": "Şarj cihazı gerilimi çok düşük. Cihazı kontrol edin", + "zh": "充电器电压过低,请检查充电设备" + }, + "fpv_tip_0x1609007F": { + "de": "%battery_index Akku: Überhitzt. Start nicht möglich. %battery_index Akku: Warten, bis Akku abgekühlt ist", + "en": "%battery_index Battery overheated. Unable to take off. Wait until %battery_index Battery cools down", + "es": "Batería %battery_index sobrecalentada. No se puede despegar. Espere a que se enfríe la batería %battery_index.", + "fr": "Surchauffe batterie %battery_index. Impossible de décoller. Attendre que la batterie %battery_index refroidisse", + "ja": "%battery_index バッテリー高温。 離陸できません。 %battery_index バッテリーが冷えるまでお待ちください", + "ko": "%battery_index 배터리 과열됨. 이륙 불가. %battery_index 배터리가 식을 때까지 기다려 주세요.", + "ru": "Перегрев %battery_index АКБ. Не удается выполнить взлет. Подождите, пока %battery_index АКБ остынет", + "tr": "%battery_index Pil aşırı ısındı. Kalkış yapılamıyor. %battery_index Pil soğuyana kadar bekleyin", + "zh": "%battery_index电池温度过高,无法起飞,等待%battery_index电池温度降低" + }, + "fpv_tip_0x16090080": { + "de": "%battery_index Akku: Überhitzt. Umgehend zum Startpunkt zurückkehren oder landen. %battery_index Akku: Warten, bis Akku abgekühlt ist", + "en": "%battery_index Battery overheated. Return to home or land promptly. Wait until %battery_index Battery cools down", + "es": "Batería %battery_index sobrecalentada. Regrese al punto de origen o aterrice rápidamente. Espere a que se enfríe la batería %battery_index.", + "fr": "Surchauffe batterie %battery_index. Retourner au point de départ ou atterrir rapidement. Attendre que la batterie %battery_index refroidisse", + "ja": "%battery_index バッテリー高温。 直ちに帰還するか、着陸してください。 %battery_index バッテリーが冷えるまでお待ちください", + "ko": "%battery_index 배터리 과열됨. 즉시 리턴 투 홈을 실행하거나 착륙하세요. %battery_index 배터리가 식을 때까지 기다려 주세요.", + "ru": "Перегрев %battery_index АКБ. Как можно скорее вернитесь на базу или приземлитесь. Подождите, пока %battery_index АКБ остынет", + "tr": "%battery_index Pil aşırı ısındı. Başlangıç noktasına geri dönün veya derhal iniş yapın. %battery_index Pil soğuyana kadar bekleyin", + "zh": "%battery_index电池温度过高,请尽快返航或降落,等待%battery_index电池温度降低" + }, + "fpv_tip_0x16090081": { + "de": "%battery_index Akku: Überhitzt. Umgehend zum Startpunkt zurückkehren oder landen. %battery_index Akku: Warten, bis Akku abgekühlt ist", + "en": "%battery_index Battery overheated. Return to home or land promptly. Wait until %battery_index Battery cools down", + "es": "Batería %battery_index sobrecalentada. Regrese al punto de origen o aterrice rápidamente. Espere a que se enfríe la batería %battery_index.", + "fr": "Surchauffe batterie %battery_index. Retourner au point de départ ou atterrir rapidement. Attendre que la batterie %battery_index refroidisse", + "ja": "%battery_index バッテリー高温。 直ちに帰還するか、着陸してください。 %battery_index バッテリーが冷えるまでお待ちください", + "ko": "%battery_index 배터리 과열됨. 즉시 리턴 투 홈을 실행하거나 착륙하세요. %battery_index 배터리가 식을 때까지 기다려 주세요.", + "ru": "Перегрев %battery_index АКБ. Как можно скорее вернитесь на базу или приземлитесь. Подождите, пока %battery_index АКБ остынет", + "tr": "%battery_index Pil aşırı ısındı. Başlangıç noktasına geri dönün veya derhal iniş yapın. %battery_index Pil soğuyana kadar bekleyin", + "zh": "%battery_index电池温度过高,请尽快返航或降落,等待%battery_index电池温度降低" + }, + "fpv_tip_0x16090082": { + "de": "%battery_index Akku: Interner Kommunikationsfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery internal communication error. Return to home or land promptly", + "es": "Error de comunicación interna de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur de communication interne de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー内部通信エラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 내부 통신 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: ошибка внутренней связи. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil dahili iletişim hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池内部通讯异常,请尽快返航或降落" + }, + "fpv_tip_0x16090083": { + "de": "%battery_index Akku: Interner Kommunikationsfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery internal communication error. Return to home or land promptly", + "es": "Error de comunicación interna de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur de communication interne de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー内部通信エラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 내부 통신 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: ошибка внутренней связи. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil dahili iletişim hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池内部通讯异常,请尽快返航或降落" + }, + "fpv_tip_0x16090084": { + "de": "%battery_index Akku: Interner Kommunikationsfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery internal communication error. Return to home or land promptly", + "es": "Error de comunicación interna de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur de communication interne de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー内部通信エラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 내부 통신 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: ошибка внутренней связи. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil dahili iletişim hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池内部通讯异常,请尽快返航或降落" + }, + "fpv_tip_0x16090085": { + "de": "%battery_index Akku: Externer Kommunikationsfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery external communication error. Return to home or land promptly", + "es": "Error de comunicación externa de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur de communication externe de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー外部通信エラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 외부 통신 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: ошибка внешней связи. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil harici iletişim hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池对外通信异常,请尽快返航或降落" + }, + "fpv_tip_0x16090086": { + "en": "%battery_index battery connector temperature too high. Flight safety affected", + "zh": "%battery_index电池连接器温度过高,影响飞行安全" + }, + "fpv_tip_0x16090086_in_the_sky": { + "de": "%battery_index battery-Anschlusstemperatur zu hoch. Flugsicherheit beeinträchtigt. Zeitnah zum Startpunkt zurückkehren oder landen", + "en": "%battery_index battery connector temperature too high. Flight safety affected. Return to home or land promptly", + "es": "Temperatura del conector %battery_index battery demasiado alta. Seguridad de vuelo afectada. Regrese al punto de origen o aterrice lo antes posible", + "fr": "Température du connecteur %battery_index battery trop élevée. Sécurité en vol affectée. Retourner au point de départ ou atterrir immédiatement", + "ja": "%battery_index batteryコネクターの温度が高すぎます。飛行安全性に影響します。すぐにRTHするか着陸させてください", + "ko": "%battery_index battery 커넥터 온도가 너무 높습니다. 비행 안전에 영향이 있습니다. 즉시 리턴 투 홈(RTH)하거나 착륙시키세요", + "ru": "%battery_index battery слишком высокая температура коннектора. Затронута безопасность полетов. Незамедлительно совершите возврат домой или посадку", + "tr": "%battery_index battery konektör sıcaklığı çok yüksek. Uçuş güvenliği etkilendi. Hemen başlangıç noktasına dönün veya iniş yapın", + "zh": "%battery_index电池连接器温度过高,影响飞行安全,请尽快返航或降落" + }, + "fpv_tip_0x16090092": { + "ar": "", + "de": "", + "en": "Pack voltage sensor error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "Vpack电压采样异常", + "zh-Hant": "" + }, + "fpv_tip_0x16090093": { + "de": "%battery_index Akku: Spannung instabil. Umgehend zum Startpunkt zurückkehren oder landen. Fluggerät nach Landung neu starten", + "en": "%battery_index Battery voltage unstable. Return to home or land promptly. Restart aircraft after landing", + "es": "Voltaje de la batería %battery_index inestable. Regrese al punto de origen o aterrice rápidamente. Reinicie la aeronave después del aterrizaje.", + "fr": "Tension de la batterie %battery_index instable. Retourner au point de départ ou atterrir rapidement. Redémarrer l'appareil après l'atterrissage", + "ja": "%battery_index バッテリー電圧が不安定です。 直ちに帰還するか、着陸してください。 着陸後に機体を再起動してください", + "ko": "%battery_index 배터리 전압 불안정. 즉시 리턴 투 홈을 실행하거나 착륙하세요. 착륙 후 기체를 재시동하세요.", + "ru": "%battery_index АКБ: нестабильное напряжение. Как можно скорее вернитесь на базу или приземлитесь. Перезапустите дрон после приземления", + "tr": "%battery_index Pil gerilimi güvenilir değil. Başlangıç noktasına geri dönün veya derhal iniş yapın. İnişten sonra aracı yeniden başlatın", + "zh": "%battery_index电池电压不稳定,请尽快返航或降落后重启电池" + }, + "fpv_tip_0x16090094": { + "de": "%battery_index Akku: Spannungssensorfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery voltage sensor error. Return to home or land promptly", + "es": "Error del sensor de voltaje de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur capteur de tension de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー電圧センサーエラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 전압 센서 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: ошибка датчика напряжения. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil gerilim sensörü hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池电压采集异常,请尽快返航或降落" + }, + "fpv_tip_0x16090095": { + "de": "%battery_index Akku: Spannung zu hoch. Umgehend zum Startpunkt zurückkehren oder landen. Fluggerät nach Landung neu starten", + "en": "%battery_index Battery voltage too high. Return to home or land promptly. Restart aircraft after landing", + "es": "Voltaje de la batería %battery_index demasiado alto. Regrese al punto de origen o aterrice rápidamente. Reinicie la aeronave después del aterrizaje.", + "fr": "Tension de la batterie %battery_index excessive. Retourner au point de départ ou atterrir rapidement. Redémarrer l'appareil après l'atterrissage", + "ja": "%battery_index バッテリー電圧が高すぎます。 直ちに帰還するか、着陸してください。 着陸後に機体を再起動してください", + "ko": "%battery_index 배터리 전압이 너무 높음. 즉시 리턴 투 홈을 실행하거나 착륙하세요. 착륙 후 기체를 재시동하세요.", + "ru": "%battery_index АКБ: слишком высокое напряжение. Как можно скорее вернитесь на базу или приземлитесь. Перезапустите дрон после приземления", + "tr": "%battery_index Pil gerilimi çok yüksek. Başlangıç noktasına geri dönün veya derhal iniş yapın. İnişten sonra aracı yeniden başlatın", + "zh": "%battery_index电池电压过高,请尽快返航或降落后重启电池" + }, + "fpv_tip_0x16090096": { + "de": "%battery_index Akku: Wartung erforderlich. Mit Vorsicht fliegen", + "en": "%battery_index Battery maintenance required. Fly with caution", + "es": "La batería %battery_index requiere mantenimiento. Vuele con cuidado.", + "fr": "Maintenance de la batterie %battery_index requise. Pilotez avec précaution", + "ja": "%battery_index バッテリーのメンテナンスが必要です。 慎重に飛行してください", + "ko": "%battery_index 배터리 점검 필요. 비행 시 주의 필요", + "ru": "%battery_index АКБ: требуется обслуживание. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil bakımı gerekiyor. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池需要保养,请谨慎飞行" + }, + "fpv_tip_0x16090097": { + "de": "Akku %battery_index: Pflege erforderlich. Mit Vorsicht fliegen", + "en": "%battery_index battery maintenance required. Fly with caution", + "es": "La batería %battery_index requiere mantenimiento. Vuele con cuidado", + "fr": "Entretien de la batterie %battery_index requis. Pilotez avec précaution", + "ja": "%battery_indexバッテリーのメンテナンスが必要です。慎重に飛行してください", + "ko": "%battery_index 배터리 점검 필요. 비행 시 주의 필요", + "ru": "%battery_index АКБ: требуется обслуживание. Соблюдайте осторожность при полете", + "tr": "%battery_index pil bakımı gerekiyor. Dikkatlice uçurun", + "zh": "%battery_index电池需要保养,请谨慎飞行" + }, + "fpv_tip_0x16090098": { + "ar": "", + "de": "", + "en": "Large voltage difference during discharge", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "放电压差大告警", + "zh-Hant": "" + }, + "fpv_tip_0x16090099": { + "de": "%battery_index Akku: Überstrom. Mit Vorsicht fliegen", + "en": "%battery_index Battery overcurrent. Fly with caution", + "es": "Sobreintensidad en la batería %battery_index. Vuele con cuidado.", + "fr": "Surtension de batterie %battery_index. Pilotez avec précaution", + "ja": "%battery_index バッテリーが過電流です。 慎重に飛行してください", + "ko": "%battery_index 배터리 과전류 발생. 비행 시 주의 필요", + "ru": "%battery_index АКБ: перегрузка по току. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil aşırı akımı. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池电流过大,请谨慎飞行" + }, + "fpv_tip_0x1609009B": { + "de": "%battery_index Akku: Temperatur ist hoch. Umgehend zum Startpunkt zurückkehren oder landen. %battery_index Akku: Warten, bis Akku abgekühlt ist", + "en": "%battery_index Battery temperature high. Return to home or land promptly. Wait until %battery_index Battery cools down", + "es": "Temperatura alta de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente. Espere a que se enfríe la batería %battery_index.", + "fr": "Température de la batterie %battery_index élevée. Retourner au point de départ ou atterrir rapidement. Attendre que la batterie %battery_index refroidisse", + "ja": "%battery_index バッテリー温度が高いです。 直ちに帰還するか、着陸してください。 %battery_index バッテリーが冷えるまでお待ちください", + "ko": "%battery_index 배터리 온도가 너무 높음. 즉시 리턴 투 홈을 실행하거나 착륙하세요. %battery_index 배터리가 식을 때까지 기다려 주세요.", + "ru": "%battery_index АКБ: слишком высокая температура. Как можно скорее вернитесь на базу или приземлитесь. Подождите, пока %battery_index АКБ остынет", + "tr": "%battery_index Pil sıcaklığı yüksek. Başlangıç noktasına geri dönün veya derhal iniş yapın. %battery_index Pil soğuyana kadar bekleyin", + "zh": "%battery_index电池温度高,请尽快返航或降落,等待%battery_index电池温度降低" + }, + "fpv_tip_0x1609009C": { + "de": "%battery_index Akku: Temperatur ist hoch. Umgehend zum Startpunkt zurückkehren oder landen. %battery_index Akku: Warten, bis Akku abgekühlt ist", + "en": "%battery_index Battery temperature high. Return to home or land promptly. Wait until %battery_index Battery cools down", + "es": "Temperatura alta de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente. Espere a que se enfríe la batería %battery_index.", + "fr": "Température de la batterie %battery_index élevée. Retourner au point de départ ou atterrir rapidement. Attendre que la batterie %battery_index refroidisse", + "ja": "%battery_index バッテリー温度が高いです。 直ちに帰還するか、着陸してください。 %battery_index バッテリーが冷えるまでお待ちください", + "ko": "%battery_index 배터리 온도가 너무 높음. 즉시 리턴 투 홈을 실행하거나 착륙하세요. %battery_index 배터리가 식을 때까지 기다려 주세요.", + "ru": "%battery_index АКБ: слишком высокая температура. Как можно скорее вернитесь на базу или приземлитесь. Подождите, пока %battery_index АКБ остынет", + "tr": "%battery_index Pil sıcaklığı yüksek. Başlangıç noktasına geri dönün veya derhal iniş yapın. %battery_index Pil soğuyana kadar bekleyin", + "zh": "%battery_index电池温度高,请尽快返航或降落,等待%battery_index电池温度降低" + }, + "fpv_tip_0x1609009D": { + "de": "%battery_index battery-Anschlusstemperatur zu hoch", + "en": "%battery_index battery connector temperature too high", + "es": "Temperatura del conector %battery_index battery demasiado alta", + "fr": "Température du connecteur %battery_index battery trop élevée", + "ja": "%battery_index batteryコネクターの温度が高すぎます", + "ko": "%battery_index battery 커넥터 온도가 너무 높습니다", + "ru": "%battery_index battery слишком высокая температура коннектора", + "tr": "%battery_index battery konektör sıcaklığı çok yüksek", + "zh": "%battery_index电池连接器温度过高" + }, + "fpv_tip_0x1609009D_in_the_sky": { + "de": "%battery_index battery-Anschlusstemperatur zu hoch. Flugsicherheit beeinträchtigt. Zeitnah zum Startpunkt zurückkehren oder landen", + "en": "%battery_index battery connector temperature too high. Flight safety affected. Return to home or land promptly", + "es": "Temperatura del conector %battery_index battery demasiado alta. Seguridad de vuelo afectada. Regrese al punto de origen o aterrice lo antes posible", + "fr": "Température du connecteur %battery_index battery trop élevée. Sécurité en vol affectée. Retourner au point de départ ou atterrir immédiatement", + "ja": "%battery_index batteryコネクターの温度が高すぎます。飛行安全性に影響します。すぐにRTHするか着陸させてください", + "ko": "%battery_index battery 커넥터 온도가 너무 높습니다. 비행 안전에 영향이 있습니다. 즉시 리턴 투 홈(RTH)하거나 착륙시키세요", + "ru": "%battery_index battery слишком высокая температура коннектора. Затронута безопасность полетов. Незамедлительно совершите возврат домой или посадку", + "tr": "%battery_index battery konektör sıcaklığı çok yüksek. Uçuş güvenliği etkilendi. Hemen başlangıç noktasına dönün veya iniş yapın", + "zh": "%battery_index电池连接器温度过高,影响飞行安全,请尽快返航或降落" + }, + "fpv_tip_0x1609009E": { + "de": "%battery_index Akku: Spannung ist hoch. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery voltage high. Return to home or land promptly", + "es": "Voltaje de la batería %battery_index alto. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Tension de la batterie %battery_index élevée. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー電圧が高いです。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 전압이 높음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: высокое напряжение. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil gerilimi yüksek. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池电压高,请尽快返航或降落" + }, + "fpv_tip_0x1609009F": { + "de": "%battery_index Akku: Spannung ist niedrig. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery voltage low. Return to home or land promptly", + "es": "Voltaje de la batería %battery_index bajo. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Tension de batterie %battery_index basse. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー電圧が低いです。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 전압이 낮음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: низкое напряжение. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil gerilimi düşük. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池电压低,请尽快返航或降落" + }, + "fpv_tip_0x160900A2": { + "en": "%index battery connector overheated. Flight safety affected. Fly with caution", + "zh": "%index电池连接器温升异常,影响飞行安全,请谨慎飞行" + }, + "fpv_tip_0x160900A3": { + "en": "%index battery exceeds power limit. Flight safety affected. Return to home or land promptly", + "zh": "%index电池超过使用功率限制范围,影响飞行安全,请尽快返航或降落" + }, + "fpv_tip_0x160900A6": { + "de": "%battery_index Akku: Verbindungsfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery connection error. Return to home or land promptly", + "es": "Error de conexión de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Erreur de connexion de la batterie %battery_index. Retourner au point de départ ou atterrir rapidement", + "it": "", + "ja": "%battery_index バッテリー接続エラー。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 연결 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "pt": "", + "ru": "%battery_index АКБ: ошибка подключения. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil bağlantı hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "电池槽%battery_index电池接触不良,请尽快返航或降落" + }, + "fpv_tip_0x160900B0": { + "de": "%battery_index Akku: Akkustand ist falsch. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery level incorrect. Return to home or land promptly", + "es": "Nivel incorrecto de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Niveau de batterie %battery_index incorrect. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー残量が正しくありません。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 잔량 잘못됨. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: неверный уровень. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil düzeyi yanlış. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池电量不准,请尽快返航或降落" + }, + "fpv_tip_0x160900B1": { + "de": "%battery_index Akku: Akkustand ist instabil. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery level unstable. Return to home or land promptly", + "es": "Nivel inestable de la batería %battery_index. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Niveau de batterie %battery_index instable. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー残量が不安定です。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 잔량 불안정. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "%battery_index АКБ: нестабильный уровень. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil düzeyi güvenilir değil. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池电量变化过大,请尽快返航或降落" + }, + "fpv_tip_0x160900B2": { + "ar": "", + "de": "", + "en": "Abnormal SoC changes", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "SOC异常跳变", + "zh-Hant": "" + }, + "fpv_tip_0x160900B3": { + "de": "%battery_index Akku: Kapazitätsfehler. Mit Vorsicht fliegen", + "en": "%battery_index Battery capacity error. Fly with caution", + "es": "Error de capacidad de la batería %battery_index. Vuele con cuidado.", + "fr": "Erreur de capacité de la batterie %battery_index. Pilotez avec précaution", + "ja": "%battery_index バッテリー容量エラー。 慎重に飛行してください", + "ko": "%battery_index 배터리 용량 오류. 비행 시 주의 필요", + "ru": "%battery_index АКБ: ошибка емкости. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil kapasite hatası. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池容量异常,请谨慎飞行" + }, + "fpv_tip_0x160900B4": { + "de": "%battery_index Akku: Kapazitätsfehler. Mit Vorsicht fliegen", + "en": "%battery_index Battery capacity error. Fly with caution", + "es": "Error de capacidad de la batería %battery_index. Vuele con cuidado.", + "fr": "Erreur de capacité de la batterie %battery_index. Pilotez avec précaution", + "ja": "%battery_index バッテリー容量エラー。 慎重に飛行してください", + "ko": "%battery_index 배터리 용량 오류. 비행 시 주의 필요", + "ru": "%battery_index АКБ: ошибка емкости. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil kapasite hatası. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池容量异常,请谨慎飞行" + }, + "fpv_tip_0x160900B5": { + "de": "%battery_index Akku: Kapazitätsfehler. Mit Vorsicht fliegen", + "en": "%battery_index Battery capacity error. Fly with caution", + "es": "Error de capacidad de la batería %battery_index. Vuele con cuidado.", + "fr": "Erreur de capacité de la batterie %battery_index. Pilotez avec précaution", + "ja": "%battery_index バッテリー容量エラー。 慎重に飛行してください", + "ko": "%battery_index 배터리 용량 오류. 비행 시 주의 필요", + "ru": "%battery_index АКБ: ошибка емкости. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil kapasite hatası. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池容量异常,请谨慎飞行" + }, + "fpv_tip_0x160900B6": { + "de": "%battery_index Akku: Kapazitätsfehler. Mit Vorsicht fliegen", + "en": "%battery_index Battery capacity error. Fly with caution", + "es": "Error de capacidad de la batería %battery_index. Vuele con cuidado.", + "fr": "Erreur de capacité de la batterie %battery_index. Pilotez avec précaution", + "ja": "%battery_index バッテリー容量エラー。 慎重に飛行してください", + "ko": "%battery_index 배터리 용량 오류. 비행 시 주의 필요", + "ru": "%battery_index АКБ: ошибка емкости. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil kapasite hatası. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池容量异常,请谨慎飞行" + }, + "fpv_tip_0x160900B7": { + "de": "%battery_index Akku: Kapazitätsfehler. Mit Vorsicht fliegen", + "en": "%battery_index Battery capacity error. Fly with caution", + "es": "Error de capacidad de la batería %battery_index. Vuele con cuidado.", + "fr": "Erreur de capacité de la batterie %battery_index. Pilotez avec précaution", + "ja": "%battery_index バッテリー容量エラー。 慎重に飛行してください", + "ko": "%battery_index 배터리 용량 오류. 비행 시 주의 필요", + "ru": "%battery_index АКБ: ошибка емкости. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil kapasite hatası. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池容量异常,请谨慎飞行" + }, + "fpv_tip_0x160900B8": { + "de": "%battery_index Akku: Kapazitätsfehler. Mit Vorsicht fliegen", + "en": "%battery_index Battery capacity error. Fly with caution", + "es": "Error de capacidad de la batería %battery_index. Vuele con cuidado.", + "fr": "Erreur de capacité de la batterie %battery_index. Pilotez avec précaution", + "ja": "%battery_index バッテリー容量エラー。 慎重に飛行してください", + "ko": "%battery_index 배터리 용량 오류. 비행 시 주의 필요", + "ru": "%battery_index АКБ: ошибка емкости. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil kapasite hatası. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池容量异常,请谨慎飞行" + }, + "fpv_tip_0x160900B9": { + "ar": "", + "de": "%battery_index Akku: Kapazität über einen längeren Zeitraum nicht aktualisiert. Wartung erforderlich. Mit Vorsicht fliegen", + "en": "%battery_index Battery capacity not updated for extended period. Maintenance required. Fly with caution", + "es": "Capacidad de la batería %battery_index no actualizada durante un período prolongado. Se requiere mantenimiento. Vuele con cuidado.", + "fr": "La capacité de la batterie %battery_index n'a pas été mise à jour pendant une période prolongée. Maintenance requise. Pilotez avec précaution", + "it": "", + "ja": "%battery_index バッテリー容量が長期間更新されていません。 メンテナンスが必要です。 慎重に飛行してください", + "ko": "%battery_index 배터리 용량이 장기간 업데이트되지 않음. 점검 필요. 비행 시 주의 필요", + "pt": "", + "ru": "%battery_index АКБ: емкость не обновлялась в течение длительного периода. Требуется обслуживание. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil kapasitesi uzun süre güncellenmedi. Bakım gerekiyor. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池容量长期未更新,请谨慎飞行并进行容量校准" + }, + "fpv_tip_0x160900BA": { + "ar": "", + "de": "%battery_index Akku: Kapazität über einen längeren Zeitraum nicht aktualisiert. Wartung erforderlich. Mit Vorsicht fliegen", + "en": "%battery_index Battery capacity not updated for extended period. Maintenance required. Fly with caution", + "es": "Capacidad de la batería %battery_index no actualizada durante un período prolongado. Se requiere mantenimiento. Vuele con cuidado.", + "fr": "La capacité de la batterie %battery_index n'a pas été mise à jour pendant une période prolongée. Maintenance requise. Pilotez avec précaution", + "it": "", + "ja": "%battery_index バッテリー容量が長期間更新されていません。 メンテナンスが必要です。 慎重に飛行してください", + "ko": "%battery_index 배터리 용량이 장기간 업데이트되지 않음. 점검 필요. 비행 시 주의 필요", + "pt": "", + "ru": "%battery_index АКБ: емкость не обновлялась в течение длительного периода. Требуется обслуживание. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil kapasitesi uzun süre güncellenmedi. Bakım gerekiyor. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池容量长期未更新,请谨慎飞行并进行容量校准" + }, + "fpv_tip_0x160900BB": { + "de": "%battery_index Akku: Beeinträchtigt. Mit Vorsicht fliegen", + "en": "%battery_index Battery degraded. Fly with caution", + "es": "Batería %battery_index deteriorada. Vuele con cuidado.", + "fr": "Batterie %battery_index dégradée. Pilotez avec précaution", + "ja": "%battery_index バッテリー劣化。 慎重に飛行してください", + "ko": "%battery_index 배터리 성능 저하됨. 비행 시 주의 필요", + "ru": "%battery_index АКБ: снижение производительности. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil bozuldu. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池性能下降,请谨慎飞行" + }, + "fpv_tip_0x160900BC": { + "ar": "", + "de": "", + "en": "Battery internal resistance unusually low", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "电池内阻异常偏小", + "zh-Hant": "" + }, + "fpv_tip_0x160900BD": { + "de": "%battery_index Akku: Alterung. Die Flugsicherheit ist möglicherweise beeinträchtigt. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery aging. Flight safety may be affected. Return to home or land promptly", + "es": "Envejecimiento de la batería %battery_index. La seguridad de vuelo puede verse afectada. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Vieillissement de la batterie %battery_index. La sécurité en vol peut être affectée. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー劣化。 飛行安全性に影響する可能性があります。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 노화. 비행 안전에 영향을 줄 수 있음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "Износ %battery_index АКБ. Это может повлиять на безопасность полета. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil eski. Uçuş güvenliği etkilenebilir. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池老化,可能影响飞行安全,请尽快返航或降落" + }, + "fpv_tip_0x160900BE": { + "de": "%battery_index Akku: Alterung. Die Flugsicherheit ist möglicherweise beeinträchtigt. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "%battery_index Battery aging. Flight safety may be affected. Return to home or land promptly", + "es": "Envejecimiento de la batería %battery_index. La seguridad de vuelo puede verse afectada. Regrese al punto de origen o aterrice rápidamente.", + "fr": "Vieillissement de la batterie %battery_index. La sécurité en vol peut être affectée. Retourner au point de départ ou atterrir rapidement", + "ja": "%battery_index バッテリー劣化。 飛行安全性に影響する可能性があります。 直ちに帰還するか、着陸してください", + "ko": "%battery_index 배터리 노화. 비행 안전에 영향을 줄 수 있음. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "Износ %battery_index АКБ. Это может повлиять на безопасность полета. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "%battery_index Pil eski. Uçuş güvenliği etkilenebilir. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "%battery_index电池老化,可能影响飞行安全,请尽快返航或降落" + }, + "fpv_tip_0x160900BF": { + "ar": "", + "de": "%battery_index Akku: Nähert sich der Grenze der Anzahl von Zyklen. Es wird empfohlen, den Akku durch einen neuen Akku zu ersetzen und den alten Akku zu warten", + "en": "%battery_index Battery approaching cycle count limit. It is recommended to replace with new battery and maintain %battery_index Battery", + "es": "La batería %battery_index se acerca al límite de recuento de ciclos. Se recomienda reemplazarla por una batería nueva y mantener la batería %battery_index.", + "fr": "La batterie %battery_index approche de la limite du nombre de cycles. Il est recommandé de remplacer par une nouvelle batterie et d'entretenir la batterie %battery_index", + "it": "", + "ja": "%battery_index バッテリーはサイクル回数の上限に近づいています。 新しいバッテリーと交換し、%battery_index バッテリーをメンテナンスすることをお勧めします", + "ko": "%battery_index 배터리가 사이클 수 한도에 근접함. 새 배터리로 교체하고 %battery_index 배터리를 유지하는 것이 좋습니다.", + "pt": "", + "ru": "%battery_index АКБ: приближается к пределу количества циклов. Рекомендуется заменить на новую АКБ и сохранить %battery_index АКБ", + "tr": "%battery_index Pil döngü sayısı sınırına yaklaşıyor. Yeni pille değiştirmeniz ve %battery_index Pil değerini korumanız önerilir", + "zh": "%battery_index电池循环次数过高,建议更换该%battery_index电池" + }, + "fpv_tip_0x160900C0": { + "de": "%battery_index Akku: Nennleistung überschritten. Leistung begrenzt. Mit Vorsicht fliegen", + "en": "%battery_index Battery rated power exceeded. Performance limited. Fly with caution", + "es": "Se superó la potencia nominal de la batería %battery_index. Rendimiento limitado. Vuele con cuidado.", + "fr": "Puissance nominale de la batterie %battery_index dépassée. Performances limitées. Pilotez avec précaution", + "ja": "%battery_index バッテリーの定格出力を超えました。 性能が制限されています。 慎重に飛行してください", + "ko": "%battery_index 배터리 정격 출력 초과됨. 성능 제한됨. 비행 시 주의 필요", + "ru": "%battery_index АКБ: превышена номинальная мощность. Производительность ограничена. Соблюдайте осторожность при полете", + "tr": "%battery_index Pil nominal gücü aşıldı. Performans sınırlandı. Aracınızı dikkatli uçurun", + "zh": "%battery_index电池已超功率使用,飞行器性能受限,请谨慎飞行" + }, + "fpv_tip_0x160900C1": { + "ar": "", + "de": "", + "en": "Imbalanced battery", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "电池均衡故障", + "zh-Hant": "" + }, + "fpv_tip_0x160900C2": { + "ar": "", + "de": "", + "en": "Sudden SoC changes", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "显示SOC出现跳变", + "zh-Hant": "" + }, + "fpv_tip_0x160900C3": { + "de": "Akku nähert sich der Grenze der Anzahl von Zyklen. Weiterverwendung birgt Sicherheitsrisiken. Akku austauschen empfohlen", + "en": "Battery approaching cycle count limit. Continuing use will pose safety risks. Replace battery recommended", + "es": "La batería se acerca al límite de recuento de ciclos. Un uso continuo planteará riesgos de seguridad. Se recomienda sustituir la batería", + "fr": "La batterie approche de la limite du nombre de cycles. Le fait de continuer à l'utiliser présente des risques pour la sécurité. Remplacement de la batterie recommandé", + "ja": "バッテリーがサイクル回数上限に近づいています。使用を続けると安全上のリスクが発生します。バッテリーの交換をお勧めします", + "ko": "배터리가 사이클 수 한도에 근접함. 계속 사용하면 안전 위험이 발생할 수 있습니다. 배터리 교체를 권고합니다", + "ru": "АКБ приближается к пределу количества циклов. Продолжение использования создаст угрозу безопасности. Рекомендуется заменить АКБ", + "tr": "Pil döngü sayısı sınırına yaklaşıyor. Kullanıma devam etmek güvenlik riskleri doğuracaktır. Pilin değiştirilmesi önerilir", + "zh": "电池循环次数过高,继续使用有安全风险,建议更换该电池" + }, + "fpv_tip_0x160900C4": { + "de": "Kalibrierung des Akkustands von %battery_index erforderlich. Akku zum Regenerieren zwei Stunden lang ruhen lassen", + "en": "%battery_index battery level calibration required. Let battery sit for 2 hours to restore", + "es": "Es necesario calibrar el nivel de batería de %battery_index. Deje reposar la batería durante 2 horas para restaurarla", + "fr": "%battery_index étalonnage du niveau de batterie requis. Laissez la batterie reposer pendant 2 heures pour restaurer", + "ja": "%battery_index バッテリー残量キャリブレーションが必要です。復元するにはバッテリーを2時間放置します", + "ko": "%battery_index 배터리 잔량 캘리브레이션이 필요합니다. 복원하려면 배터리를 2시간 동안 그대로 둡니다", + "ru": "%battery_index требуется калибровка уровня заряда АКБ. Подождите 2 часа для восстановления АКБ", + "tr": "%battery_index pil seviyesi kalibrasyonu gerekli. Geri yüklemek için pili 2 saat kullanmadan bekletin", + "zh": "%battery_index电池电量需要校准,请静置2h尝试恢复" + }, + "fpv_tip_0x160900D2": { + "de": "%battery_index battery-Stand längere Zeit nicht kalibriert. Akku vor dem Kalibrieren eine Stunde lang ruhen lassen", + "en": "%battery_index battery level not calibrated for a long time. Let battery sit for 1 hour before calibration", + "es": "Nivel %battery_index battery no calibrado durante mucho tiempo. Deje reposar la batería durante 1 hora antes de la calibración", + "fr": "Niveau %battery_index battery non étalonné depuis longtemps. Laissez la batterie reposer pendant 1 heure avant l'étalonnage", + "ja": "%battery_index battery残量のキャリブレーションが長期間行われていません。バッテリーを1時間放置してからキャリブレーションを行ってください", + "ko": "%battery_index battery 레벨을 장기간 캘리브레이션하지 않았습니다. 배터리를 1시간 동안 그대로 두었다가 캘리브레이션을 진행하세요", + "ru": "%battery_index battery уровень давно не калибровался. Не используйте аккумулятор в течение 1 часа перед калибровкой", + "tr": "%battery_index battery seviye uzun süredir kalibre edilmedi. Kalibrasyondan önce bataryayı 1 saat bekletin", + "zh": "%battery_index电池电量长期未校准,请静置1h以上等待校准" + }, + "fpv_tip_0x160900D5": { + "zh": "无法起飞:电池已达最大寿命,请更换电池" + }, + "fpv_tip_0x160900D5_in_the_sky": { + "zh": "无法起飞:电池已达最大寿命,请更换电池" + }, + "fpv_tip_0x160900D6": { + "zh": "电池健康度低,寿命预计在20循环或20天后耗尽,请及时更换电池" + }, + "fpv_tip_0x160A0001": { + "ar": "", + "de": "", + "en": "Parachute communication error. Make sure parachute is installed properly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞通信异常,请检查是否正确安装", + "zh-Hant": "" + }, + "fpv_tip_0x160A0011": { + "de": "Die Registrierung mit Klarnamen wurde abgebrochen, was zu Flugsicherheitsrisiken führen kann. Vor dem Flug die Hilfedokumentation beachten und eine Registrierung mit Klarnamen anhand der Anweisungen abschließen", + "en": "Real-name registration is canceled, which may result in flight safety risks. View Help Documentation and complete real-name registration based on instructions before flight", + "es": "El registro de nombre real se ha cancelado, lo que puede provocar riesgos de seguridad de vuelo. Echa un vistazo a la documentación de ayuda y completa el registro de nombre real según las instrucciones antes del vuelo", + "fr": "L'enregistrement du nom réel est annulé, ce qui peut entraîner des risques de sécurité en vol. Consultez les documents d'aide et effectuez l'enregistrement du nom réel en fonction des instructions avant le vol", + "ja": "実名の登録がキャンセルされたため、飛行の安全性に危険が生じる可能性があります。飛行前に手順に従ってヘルプドキュメントを参照し、実名の登録を完了してください", + "ko": "실명 등록이 취소되어 비행 안전 위험이 발생할 수 있습니다. 비행 전에 지침에 따라 도움말 문서를 보고 실명 등록을 완료하세요.", + "ru": "Регистрация с использованием настоящего имени отменена. Это может угрожать безопасности полета. Изучите справочную документацию и завершите регистрацию по инструкции перед началом полета", + "tr": "Asıl adla kayıt işlemi iptal edildi. Bu durum, uçuş güvenliği risklerine neden olabilir. Uçuş öncesinde Yardım Belgesine bakın ve talimatlara uygun olarak asıl adla kayıt işlemini tamamlayın", + "zh": "飞机实名登记状态已注销,存在飞行风险,请点击查看帮助文档,按照指引完成实名登记后飞行" + }, + "fpv_tip_0x16100001": { + "de": "Fehler: Kompass . Start nicht möglich. Fluggerät neu starten", + "en": "Compass error. Unable to take off. Restart aircraft", + "es": "Error de brújula. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur du compas . Impossible de décoller. Redémarrez l\\'appareil", + "ja": "コンパスエラー。離陸できません。機体を再起動してください", + "ko": "콤파스 오류 . 이륙 불가. 기체 재시작 필요", + "ru": "Ошибка компаса . Взлет невозможен. Перезагрузите дрон", + "tr": "Pusula hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:指南针异常,请重启飞行器" + }, + "fpv_tip_0x16100001_in_the_sky": { + "de": "Kompassfehler. Zum Startpunkt zurückkehren oder landen", + "en": "Compass error. Return to home or land", + "es": "Error de brújula. Regresa al punto de origen o aterriza", + "fr": "Erreur du compas. Revenez au point de départ ou atterrissez", + "ja": "コンパスエラー。帰還するか、着陸してください", + "ko": "콤파스 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка компаса. Вернитесь домой или приземлитесь", + "tr": "Pusula hatası. Eve geri dönün veya iniş yapın", + "zh": "指南针异常,请返航或降落" + }, + "fpv_tip_0x16100002": { + "de": "DJI Assistant verbunden. Start nicht möglich. Vor dem Start die Verbindung trennen", + "en": "DJI Assistant connected. Unable to take off. Disconnect before taking off", + "es": "DJI Assistant conectado. No se puede despegar. Desconéctalo antes de despegar", + "fr": "DJI Assistant connecté. Impossible de décoller. Déconnectez-le avant de décoller", + "ja": "DJI Assistantに接続されています。離陸できません。離陸する前に接続を解除してください", + "ko": "DJI Assistant 연결됨. 이륙 불가. 이륙하기 전 연결 해제 필요", + "ru": "ПО DJI Assistant подключено. Взлет невозможен. Отключите его перед взлетом", + "tr": "DJI Assistant bağlandı. Kalkış yapamıyor. Kalkıştan önce bağlantıyı kes", + "zh": "无法起飞:已连接DJI Assistant 软件,请先断开再起飞" + }, + "fpv_tip_0x16100002_in_the_sky": { + "de": "DJI Assistant verbunden. Vor dem Start die Verbindung trennen", + "en": "DJI Assistant connected. Disconnect before taking off", + "es": "DJI Assistant conectado. Desconéctalo antes de despegar", + "fr": "DJI Assistant connecté. Déconnectez-le avant de décoller", + "ja": "DJI Assistantに接続されています。離陸する前に接続を解除してください", + "ko": "DJI Assistant 연결됨. 이륙하기 전 연결 해제 필요", + "ru": "ПО DJI Assistant подключено. Отключите его перед взлетом", + "tr": "DJI Assistant bağlandı. Kalkıştan önce bağlantıyı kes", + "zh": "已连接DJI Assistant 软件,请先断开再飞行" + }, + "fpv_tip_0x16100003": { + "de": "Fluggerät nicht aktiviert oder Firmware veraltet. Kann nicht abheben. Fluggerät aktivieren oder auf neueste Firmware-Version aktualisieren", + "en": "Aircraft not activated or firmware out-of-date. Unable to take off. Activate aircraft or update to latest firmware version", + "es": "Aeronave no activada o firmware obsoleto. No se puede despegar. Activa la aeronave o actualiza a la versión del firmware más reciente", + "fr": "L\\'appareil n\\'est pas activé ou le firmware est obsolète. Impossible de décoller. Activez l\\'appareil ou mettez le firmware à jour vers la version la plus récente", + "ja": "機体がアクティベーションされていないか、古いバッテリーファームウェアです。離陸できません。機体をアクティベーションするか、最新のファームウェアバージョンに更新してください", + "ko": "활성화 안 된 기체 또는 오래된 펌웨어. 이륙 불가. 기체를 활성화하거나 최신 펌웨어 버전으로 업데이트해야 함", + "ru": "Дрон не активирован или ПО устарело. Взлет невозможен. Активируйте дрон или установите последнюю версию ПО", + "tr": "Araç etkinleştirilmemiş ya da yazılım güncel değil. Kalkış yapamıyor. Aracı etkinleştirin ya da en son yazılım sürümüne güncelleyin", + "zh": "无法起飞:请检查是否激活或尝试升级最新固件" + }, + "fpv_tip_0x16100003_in_the_sky": { + "de": "Geräteaktivierung oder Firmware-Aktualisierung erforderlich", + "en": "Device activation or firmware update required", + "es": "Es necesario activar el dispositivo o actualizar el firmware", + "fr": "Activation de l\\'appareil ou mise à jour du firmware requise", + "ja": "機器のアクティベーションまたはファームウェアの更新が必要です", + "ko": "기기 활성화 또는 펌웨어 업데이트 필요", + "ru": "Требуется активировать устройство или обновить ПО", + "tr": "Cihazın etkinleştirilmesi ya da yazılımın güncellenmesi gerekiyor", + "zh": "请检查是否激活或尝试升级最新固件" + }, + "fpv_tip_0x16100005": { + "ar": "", + "de": "IMU-Fehler . Start nicht möglich. Fluggerät neu starten", + "en": "IMU error. Unable to take off. Restart aircraft", + "es": "Error de IMU. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur IMU. Impossible de décoller. Redémarrez l\\'appareil", + "it": "", + "ja": "IMU エラー。離陸できません。機体を再起動してください", + "ko": "IMU 오류 . 이륙 불가.기체 재시작 필요", + "pt": "", + "ru": "Ошибка IMU . Взлет невозможен. Перезагрузите дрон", + "tr": "IMU hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:IMU异常,请重启飞行器" + }, + "fpv_tip_0x16100005_in_the_sky": { + "ar": "", + "de": "Fehler: IMU. Fluggerät neu starten", + "en": "IMU error. Restart aircraft", + "es": "Error de IMU. Reinicia la aeronave", + "fr": "Erreur IMU. Redémarrez l\\'appareil", + "it": "", + "ja": "IMUエラー。機体を再起動してください", + "ko": "IMU 오류. 기체 재시작 필요", + "pt": "", + "ru": "Ошибка модуля IMU. Перезагрузите дрон", + "tr": "IMU hatası. Aracı yeniden başlatın", + "zh": "IMU异常,请重启飞行器" + }, + "fpv_tip_0x16100006": { + "de": "Ungültige IMU-Seriennummer . Kann nicht abheben. Wartung erforderlich", + "en": "Invalid IMU serial number. Unable to take off. Maintenance required", + "es": "Número de serie de la IMU no válido. No se puede despegar. Se requiere mantenimiento", + "fr": "N° de série de l\\'IMU invalide . Impossible de décoller. Opération de maintenance requise", + "ja": "無効なIMUシリアルナンバー。離陸できません。メンテナンスが必要です", + "ko": "유효하지 않은 IMU 시리얼 넘버 . 이륙 불가. 유지 보수 필요", + "ru": "Неверный серийный номер IMU . Взлет невозможен. Требуется обслуживание", + "tr": "Geçersiz IMU seri numarası. Kalkış yapamıyor. Bakım yapılması gerekli", + "zh": "无法起飞:IMU的SN标记错误,请返厂维修" + }, + "fpv_tip_0x16100006_in_the_sky": { + "de": "Ungültige IMU-Seriennummer . Zum Startpunkt zurückkehren oder landen.", + "en": "Invalid IMU serial number. Return to home or land", + "es": "Número de serie de la IMU no válido. Regresa al punto de origen o aterriza", + "fr": "N° de série IMU invalide . Revenez au point de départ ou atterrissez", + "ja": "無効なIMUシリアルナンバー。帰還するか、着陸してください", + "ko": "유효하지 않은 IMU 시리얼 넘버 . RTH 진행 또는 착륙 필요", + "ru": "Неверный серийный номер IMU . Вернитесь домой или приземлитесь", + "tr": "Geçersiz IMU seri numarası. Eve geri dönün veya iniş yapın", + "zh": "IMU的SN标记错误,请返航或降落" + }, + "fpv_tip_0x16100008": { + "de": "Kompass wird kalibriert. Kann nicht abheben. Bitte warten, bis Kalibrierung abgeschlossen ist (alarmierend)", + "en": "Compass calibrating. Unable to take off. Wait for calibration to complete before taking off(%alarmid)", + "es": "Calibrando la brújula. No se puede despegar. Espera a que se complete la calibración antes de despegar (%alarmid)", + "fr": "Étalonnage du compas en cours. Impossible de décoller. Patientez jusqu\\'à ce que l\\'étalonnage soit terminé avant de décoller", + "ja": "コンパスキャリブレーション中。離陸できません。キャリブレーションが完了してから離陸してください(%alarmid)", + "ko": "콤파스 캘리브레이션 중. 이륙 불가. 캘리브레이션 완료 후 이륙해야 함", + "ru": "Идет калибровка компаса. Взлет невозможен. Дождитесь ее окончания, прежде чем взлетать", + "tr": "Pusula kalibre ediliyor. Kalkış yapamıyor. Kalkıştan önce kalibrasyonun tamamlanmasını bekleyin (%alarmid)", + "zh": "无法起飞:指南针校准中,请等待校准完成再起飞" + }, + "fpv_tip_0x16100008_in_the_sky": { + "de": "Kompass wird kalibriert. Bitte warten, bis Kalibrierung abgeschlossen ist, bevor Sie abheben (alarmierend)", + "en": "Compass calibrating. Wait for calibration to complete before taking off", + "es": "Calibrando la brújula. Espera a que se complete la calibración antes de despegar", + "fr": "Étalonnage du compas en cours. Attendez la fin de l\\'étalonnage avant de décoller", + "ja": "コンパスキャリブレーション中。キャリブレーションが完了してから離陸してください", + "ko": "콤파스 캘리브레이션 중. 캘리브레이션 완료 후 이륙해야 함", + "ru": "Идет калибровка компаса. Дождитесь ее окончания, прежде чем взлетать", + "tr": "Pusula kalibre ediliyor. Kalkıştan önce kalibrasyonun tamamlanmasını bekleyin", + "zh": "指南针校准中,请等待校准完成再起飞" + }, + "fpv_tip_0x16100009": { + "de": "Initialisierung des Sensorsystems . Start nicht möglich. Bitte warten bis die Initialisierung abgeschlossen ist, bevor Sie starten", + "en": "Sensor system initializing. Unable to take off. Wait for initialization to complete before taking off", + "es": "Iniciando sistema de sensores. No se puede despegar. Espera a que se complete el inicio antes de despegar", + "fr": "Initialisation du système de capteurs . Impossible de décoller. Attendez la fin de l\\'initialisation avant de décoller", + "ja": "センサーシステム初期化中。離陸できません。初期化が完了してから離陸してください", + "ko": "센서 시스템 초기화 중 . 이륙 불가. 초기화 완료 후 이륙해야 함", + "ru": "Запускается система датчиков . Взлет невозможен. Дождитесь завершения процесса, прежде чем взлетать", + "tr": "Sensör sistemi başlatılıyor. Kalkış yapamıyor. Kalkıştan önce başlatmanın tamamlanmasını bekleyin", + "zh": "无法起飞:传感器系统初始化中,请等待初始化完成" + }, + "fpv_tip_0x16100009_in_the_sky": { + "de": "Initialisierung des Sensorsystems . Zum Startpunkt zurückkehren oder landen.", + "en": "Sensor system initializing. Return to home or land", + "es": "Iniciando sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Initialisation du système de capteurs . Revenez au point de départ ou atterrissez", + "ja": "センサーシステム初期化中。帰還するか、着陸してください", + "ko": "센서 시스템 초기화 중 . RTH 진행 또는 착륙 필요", + "ru": "Запускается система датчиков . Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi başlatılıyor. Eve geri dönün veya iniş yapın", + "zh": "传感器系统初始化中,请返航或降落" + }, + "fpv_tip_0x1610000A": { + "de": "Fluggerät im Anfängermodus. Kann nicht abheben. Bitte in einem offenen Außenbereich abheben (alarmierend)", + "en": "Aircraft in Beginner mode. Unable to take off. Take off in an open outdoor area when in Beginner mode", + "es": "Aeronave en modo Principiante. No se puede despegar. Cuando el modo Principiante esté activado, despega desde una zona exterior abierta", + "fr": "L\\'appareil est en mode Débutant. Impossible de décoller. En mode Débutant, décollez dans une zone à l\\'extérieur et dégagée", + "ja": "機体はビギナーモードです。離陸できません。ビギナーモード中は開けた屋外エリアで離陸してください", + "ko": "기체 초보자 모드 사용 중. 이륙 불가. 초보자 모드 사용 시 개방된 야외에서 이륙해야 함", + "ru": "Дрон в режиме новичка. Взлет невозможен. Взлетайте на открытом пространстве на улице в этом режиме", + "tr": "Araç Başlangıç modunda. Kalkış yapamıyor. Başlangıç modundayken açık bir dış mekan alanında kalkış yapın", + "zh": "无法起飞:新手模式下请在室外开阔环境飞行" + }, + "fpv_tip_0x1610000A_in_the_sky": { + "de": "Anfängermodus aktiviert. Wenn Sie den Anfängermodus verwenden, starten Sie in einem offenen Außenbereich", + "en": "Beginner mode enabled. When using Beginner mode, take off in an open, outdoor area", + "es": "Modo Principiante activado. Al usar el modo Principiante, despega desde una zona exterior abierta", + "fr": "Mode Débutant activé. En utilisant le mode Débutant, décollez dans une zone extérieure dégagée", + "ja": "ビギナーモードが有効です。ビギナーモード使用時は、開けた屋外エリアで離陸してください", + "ko": "초보자 모드 활성화됨. 초보자 모드 사용 시 개방된 야외에서 이륙해야 함", + "ru": "Активирован режим новичка. Взлетайте на открытом пространстве на улице", + "tr": "Başlangıç modu etkinleştirildi. Başlangıç modundayken açık bir dış mekan alanında kalkış yapın", + "zh": "新手模式下请在室外开阔环境飞行" + }, + "fpv_tip_0x1610000B": { + "de": "Fehler: Akkuzelle . Kann nicht abheben. Bitte DJI Support kontaktieren", + "en": "Battery cell error. Unable to take off. Contact DJI Support", + "es": "Error de la célula de batería. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de cellule de batterie . Impossible de décoller. Contactez l\\'assistance technique DJI", + "ja": "バッテリーセルエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "배터리 셀 오류 . 이륙 불가. DJI 고객지원으로 문의해주세요", + "ru": "Ошибка элемента батареи . Взлет невозможен. Обратитесь в службу поддержки DJI", + "tr": "Pil hücresi hatası. Kalkış yapamıyor. DJI Destek ile iletişime geçin", + "zh": "无法起飞:电池电芯错误,请联系售后服务" + }, + "fpv_tip_0x1610000B_in_the_sky": { + "de": "Fehler: Akkuzelle . Zum Startpunkt zurückkehren oder landen.", + "en": "Battery cell error. Return to home or land", + "es": "Error de la célula de batería. Regresa al punto de origen o aterriza", + "fr": "Erreur de cellule de batterie . Revenez au point de départ ou atterrissez", + "ja": "バッテリーセルエラー。帰還するか、着陸してください", + "ko": "배터리 셀 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка элемента батареи . Вернитесь домой или приземлитесь", + "tr": "Pil hücresi hatası. Eve geri dönün veya iniş yapın", + "zh": "电池电芯错误,请返航或降落" + }, + "fpv_tip_0x1610000C": { + "de": "Akkukommunikationsfehler . Kann nicht abheben. Akku erneut einlegen", + "en": "Battery communication error. Unable to take off. Reinstall battery", + "es": "Error de comunicación de la batería. No se puede despegar. Vuelve a instalar la batería", + "fr": "Erreur de communication avec la batterie . Impossible de décoller. Réinstallez la batterie", + "ja": "バッテリー通信エラー。離陸できません。バッテリーを再度取り付けてください", + "ko": "배터리 통신 오류 . 이륙 불가. 배터리 재설치 필요", + "ru": "Ошибка связи батареи . Взлет невозможен. Переустановите батарею", + "tr": "Pil iletişim hatası. Kalkış yapamıyor. Pili tekrar tak", + "zh": "无法起飞:电池通信错误,请重新安装电池" + }, + "fpv_tip_0x1610000C_in_the_sky": { + "de": "Kommunikationsfehler: Akku . Zum Startpunkt zurückkehren.", + "en": "Battery communication error. Return to home", + "es": "Error de comunicación de la batería. Regresa al punto de origen", + "fr": "Erreur de communication avec la batterie . Revenez au point de départ", + "ja": "バッテリー通信エラー。帰還してください", + "ko": "배터리 통신 오류 . RTH 진행 필요", + "ru": "Ошибка связи батареи . Вернитесь домой", + "tr": "Pil iletişim hatası. Eve dön", + "zh": "电池通信错误,请返航" + }, + "fpv_tip_0x1610000D": { + "de": "Akkuspannung sehr niedrig . Start nicht möglich. Bitte umgehend aufladen", + "en": "Critical low battery voltage. Unable to take off. Charge promptly", + "es": "Voltaje de la batería crítico. No se puede despegar. Cárgala cuanto antes", + "fr": "Tension de la batterie dangereusement faible . Impossible de décoller. Rechargez immédiatement", + "ja": "重度ローバッテリー電圧警告。離陸できません。直ちに充電してください", + "ko": "배터리 전압 매우 낮음 . 이륙 불가. 즉시 충전 필요", + "ru": "Критически низкое напряжение батареи . Взлет невозможен. Срочно зарядите дрон", + "tr": "Pil voltajı çok düşük. Kalkış yapamıyor. Hemen şarj edin", + "zh": "无法起飞:严重低电压警报,请及时充电" + }, + "fpv_tip_0x1610000D_in_the_sky": { + "de": "Kritisch niedrige Batteriespannung . Sofort zum Startpunkt zurückkehren oder landen.", + "en": "Critical low battery voltage. Return to home or land promptly", + "es": "Voltaje de la batería crítico. Regresa al punto de origen o aterriza rápidamente", + "fr": "Tension de la batterie dangereusement faible . Revenez au point de départ ou atterrissez", + "ja": "重度ローバッテリー電圧警告。直ちに帰還するか、着陸してください", + "ko": "배터리 전압 매우 낮음 . 즉시 RTH 진행 또는 착륙 필요", + "ru": "Критически низкое напряжение батареи . Вернитесь домой или приземлитесь немедленно", + "tr": "Pil voltajı çok düşük. Hemen eve dönün veya iniş yapın", + "zh": "严重低电压,请尽快返航或降落" + }, + "fpv_tip_0x1610000E": { + "de": "Akkuspannung extrem niedrig. Start nicht möglich. Umgehend aufladen", + "en": "Critically low battery voltage. Unable to take off. Charge promptly", + "es": "Voltaje de la batería críticamente bajo. No se puede despegar. Cárguela cuanto antes", + "fr": "Tension de la batterie dangereusement faible. Impossible de décoller. Rechargez rapidement", + "ja": "深刻なバッテリー低電圧です離陸できません。直ちに充電してください", + "ko": "배터리 전압이 매우 낮습니다. 이륙 불가. 즉시 충전하세요", + "ru": "Критически низкое напряжение АКБ. Невозможно взлететь. Немедленно зарядите АКБ", + "tr": "Kritik derecede düşük pil gerilimi. Kalkış yapılamıyor. Hemen şarj edin", + "zh": "无法起飞:严重低电压警报,请及时充电" + }, + "fpv_tip_0x1610000E_in_the_sky": { + "de": "Akkuspannung extrem niedrig. Zeitnah zum Startpunkt zurückkehren oder landen", + "en": "Critically low battery voltage. Return to home or land promptly", + "es": "Voltaje de la batería críticamente bajo. Regrese al punto de origen o aterrice lo antes posible", + "fr": "Tension de la batterie dangereusement faible. Retourner au point de départ ou atterrir immédiatement", + "ja": "深刻なバッテリー低電圧ですすぐにRTHするか着陸させてください", + "ko": "배터리 전압이 매우 낮습니다. 즉시 리턴 투 홈(RTH)하거나 착륙시키세요", + "ru": "Критически низкое напряжение АКБ. Незамедлительно совершите возврат домой или посадку", + "tr": "Kritik derecede düşük pil gerilimi. Hemen başlangıç noktasına dönün veya iniş yapın", + "zh": "严重低电压,请尽快返航或降落" + }, + "fpv_tip_0x1610000F": { + "de": "Akkuspannung kritisch niedrig. Start nicht möglich. Umgehend aufladen.", + "en": "Critical low battery voltage. Unable to take off. Charge promptly", + "es": "Voltaje de la batería crítico. No se puede despegar. Cárgala cuanto antes", + "fr": "Tension de la batterie dangereusement faible. Impossible de décoller. Rechargez immédiatement", + "ja": "重度のバッテリー低電圧。離陸できません。直ちに充電してください", + "ko": "배터리 전압 매우 부족. 이륙 불가. 즉시 충전하세요.", + "ru": "Критически низкое напряжение аккумулятора. Невозможно выполнить взлет. Немедленно зарядите", + "tr": "Pil voltajı çok düşük. Kalkış yapamıyor. Hemen şarj edin", + "zh": "无法起飞:严重低电压警报,请及时充电" + }, + "fpv_tip_0x1610000F_in_the_sky": { + "de": "Akkuspannung kritisch niedrig. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Critical low battery voltage. Return to home or land promptly", + "es": "Voltaje de la batería crítico. Regresa al punto de origen o aterriza rápidamente", + "fr": "Tension de la batterie dangereusement faible. Revenez au point de départ ou atterrissez", + "ja": "重度のバッテリー低電圧。直ちに帰還するか着陸してください", + "ko": "배터리 전압 매우 부족. 즉시 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Критически низкое напряжение аккумулятора. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "Pil voltajı çok düşük. Hemen eve dönün veya iniş yapın", + "zh": "严重低电压,请尽快返航或降落" + }, + "fpv_tip_0x16100010": { + "de": "Akkuausgangsleistung nicht ausreichend . Kann nicht abheben. Bitte aufladen", + "en": "Battery output power insufficient. Unable to take off. Charge promptly", + "es": "Potencia de salida de la batería insuficiente. No se puede despegar. Cárgala cuanto antes", + "fr": "Puissance de sortie de la batterie insuffisante . Impossible de décoller. Rechargez immédiatement", + "ja": "バッテリー出力不足。離陸できません。直ちに充電してください", + "ko": "배터리 출력 전원 부족 . 이륙 불가. 즉시 충전 필요", + "ru": "Недостаточная мощность батареи . Взлет невозможен. Срочно зарядите дрон", + "tr": "Pil çıkış gücü yetersiz. Kalkış yapamıyor. Hemen şarj edin", + "zh": "无法起飞:电池输出功率不足,请充电。若环境温度低,预热电池" + }, + "fpv_tip_0x16100010_in_the_sky": { + "de": "Akkuleistung unzureichend . Zum Startpunkt zurückkehren oder landen.", + "en": "Battery power output insufficient. Return to home or land", + "es": "Potencia de salida de la batería insuficiente. Regresa al punto de origen o aterriza", + "fr": "Puissance de sortie de la batterie insuffisante . Revenez au point de départ ou atterrissez", + "ja": "バッテリー出力不足。帰還するか、着陸してください", + "ko": "배터리 전원 출력 부족 . RTH 진행 또는 착륙 필요", + "ru": "Недостаточная производительность батареи . Вернитесь домой или приземлитесь", + "tr": "Pil çıkış gücü yetersiz. Eve geri dönün veya iniş yapın", + "zh": "电池输出功率不足,请尽快返航或降落" + }, + "fpv_tip_0x16100011": { + "de": "Akkustand kritisch niedrig. Start nicht möglich. Umgehend aufladen.", + "en": "Critical low battery. Unable to take off. Charge promptly", + "es": "Nivel de batería crítico. No se puede despegar. Cárgala cuanto antes", + "fr": "Batterie dangereusement faible. Impossible de décoller. Rechargez immédiatement", + "ja": "重度のローバッテリー。離陸できません。直ちに充電してください", + "ko": "심각한 배터리 부족. 이륙 불가. 즉시 충전하세요.", + "ru": "Критически низкий заряд аккумулятора. Невозможно выполнить взлет. Немедленно зарядите", + "tr": "Çok düşük pil. Kalkış yapamıyor. Hemen şarj edin", + "zh": "无法起飞:严重低电量警报,请及时充电" + }, + "fpv_tip_0x16100011_in_the_sky": { + "de": "Akkustand kritisch niedrig. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Critical low battery. Return to home or land promptly", + "es": "Nivel de batería crítico. Regresa al punto de origen o aterriza rápidamente", + "fr": "Batterie dangereusement faible. Revenez au point de départ ou atterrissez", + "ja": "重度のローバッテリー。直ちに帰還するか着陸してください", + "ko": "심각한 배터리 부족. 즉시 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Критически низкий заряд аккумулятора. Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "Çok düşük pil. Hemen eve dönün veya iniş yapın", + "zh": "严重低电量,请尽快返航或降落" + }, + "fpv_tip_0x16100012": { + "de": "Initialisierung des Akkus . Start nicht möglich. Bitte warten bis die Initialisierung abgeschlossen ist", + "en": "Battery initializing. Unable to take off. Wait for initialization to complete before taking off", + "es": "Iniciando batería. No se puede despegar. Espera a que se complete el inicio antes de despegar", + "fr": "Initialisation de la batterie . Impossible de décoller. Attendez la fin de l\\'initialisation avant de décoller", + "ja": "バッテリー初期化中。離陸できません。初期化が完了してから離陸してください", + "ko": "배터리 초기화 중 . 이륙 불가. 초기화 완료 후 이륙해야 함", + "ru": "Батарея включается . Взлет невозможен. Дождитесь завершения процесса перед взлетом", + "tr": "Pil başlatılıyor. Kalkış yapamıyor. Kalkıştan önce başlatmanın tamamlanmasını bekleyin", + "zh": "无法起飞:电池初始化中,请等待初始化完成" + }, + "fpv_tip_0x16100012_in_the_sky": { + "de": "Fehler: Akkuinitialisierung . Zum Startpunkt zurückkehren oder landen.", + "en": "Battery initialization error. Return to home or land", + "es": "Error de inicio de la batería. Regresa al punto de origen o aterriza", + "fr": "Erreur d\\'initialisation de la batterie . Revenez au point de départ ou atterrissez", + "ja": "バッテリー初期化エラー帰還するか、着陸してください", + "ko": "배터리 초기화 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка запуска батареи . Вернитесь домой или приземлитесь", + "tr": "Pil başlatma hatası. Eve geri dönün veya iniş yapın", + "zh": "电池异常初始化,请返航或降落" + }, + "fpv_tip_0x16100013": { + "de": "Flugsimulator aktiv. Kann nicht abheben. Neustart durchführen, um zu starten", + "en": "Running Flight Simulator. Unable to take off. Restart aircraft before taking off", + "es": "Se está ejecutando el simulador de vuelo. No se puede despegar. Reinicia la aeronave antes de despegar", + "fr": "Le simulateur de vol est en cours d’utilisation. Impossible de décoller. Redémarrez l’appareil avant de décoller", + "ja": "フライトシミュレーター実行中。離陸できません。離陸前に機体を再起動してください", + "ko": "비행 시뮬레이터 실행 중. 이륙 불가. 이륙하기 전 기체 재시작 필요", + "ru": "Работает симулятор полетов. Взлет невозможен. Перезагрузите дрон, прежде чем взлетать", + "tr": "Uçuş Simülatörü Çalışıyor. Kalkış yapamıyor. Kalkıştan önce aracı yeniden başlat", + "zh": "无法起飞:正在运行模拟器,起飞需要重启飞行器" + }, + "fpv_tip_0x16100013_in_the_sky": { + "de": "Flugsimulator aktiv. Neustart durchführen, um zu starten", + "en": "Running Flight Simulator. Restart aircraft before taking off", + "es": "Se está ejecutando el simulador de vuelo. Reinicia la aeronave antes de despegar", + "fr": "Le simulateur de vol est en cours d’utilisation. Redémarrez l’appareil avant de décoller", + "ja": "フライトシミュレーター実行中。離陸前に機体を再起動してください", + "ko": "비행 시뮬레이터 실행 중. 이륙하기 전 기체 재시작 필요", + "ru": "Работает симулятор полетов. Перезагрузите дрон, прежде чем взлетать", + "tr": "Uçuş Simülatörü Çalışıyor. Kalkıştan önce aracı yeniden başlat", + "zh": "正在运行模拟器,起飞需要重启飞行器" + }, + "fpv_tip_0x16100014": { + "de": "Start nicht möglich. Landegestell im Transportmodus", + "en": "Unable to take off. Landing gear in Travel mode", + "es": "No se puede despegar. Tren de aterrizaje en modo Viaje.", + "fr": "Impossible de décoller. Train d’atterrissage en mode Transport", + "ja": "離陸できません。ランディングギアがトラベルモード", + "ko": "이륙 불가. 랜딩 기어가 트래블 모드에 있습니다", + "ru": "Не удается выполнить взлет. Шасси в режиме движения", + "tr": "Kalkış yapılamıyor. İniş takımı seyahat modunda", + "zh": "无法起飞:起落架处于运输模式" + }, + "fpv_tip_0x16100015": { + "de": "Neigungswinkel des Fluggeräts zu groß. Kann nicht abheben. Fluggerät vor dem Start auf ebener Fläche abstellen", + "en": "Aircraft pitch angle too large. Unable to take off. Ensure aircraft is level before taking off", + "es": "Ángulo de inclinación de la aeronave demasiado grande. No se puede despegar. Asegúrate de que la aeronave esté nivelada antes de despegar", + "fr": "L\\'angle d\\'inclinaison de l\\'appareil est trop grand. Impossible de décoller. Assurez-vous que l\\'appareil est à l\\'horizontale avant de décoller", + "ja": "機体のピッチ角が大きすぎます。離陸できません。離陸前に機体が水平であることを確認してください", + "ko": "기체 피치각 너무 큼. 이륙 불가. 기체를 평평한 곳에 놓고 이륙해야 함", + "ru": "Слишком большой угол наклона дрона. Взлет невозможен. Убедитесь, что дрон расположен ровно перед взлетом", + "tr": "Aracın adım açısı çok büyük. Kalkış yapamıyor. Kalkış öncesi aracın düz olduğunda emin olun", + "zh": "无法起飞:飞行器倾斜角度过大,请水平放置飞行器后起飞" + }, + "fpv_tip_0x16100015_in_the_sky": { + "de": "Neigungswinkel des Fluggeräts zu groß. Fluggerät vor dem Start auf ebener Fläche abstellen", + "en": "Aircraft pitch angle too large. Ensure aircraft is level before taking off", + "es": "Ángulo de inclinación de la aeronave demasiado grande. Asegúrate de que la aeronave esté nivelada antes de despegar", + "fr": "Angle d\\'inclinaison de l\\'appareil trop grand. Assurez-vous que l\\'appareil est à l\\'horizontale avant de décoller", + "ja": "機体のピッチ角が大きすぎます。離陸前に機体が水平であることを確認してください", + "ko": "기체 피치각 너무 큼. 기체를 평평한 곳에 놓고 이륙해야 함", + "ru": "Слишком большой угол наклона дрона. Убедитесь, что дрон расположен ровно перед взлетом", + "tr": "Aracın adım açısı çok büyük. Kalkış öncesi aracın düz olduğunda emin olun", + "zh": "飞行器倾斜角度过大,请水平放置飞行器后起飞" + }, + "fpv_tip_0x16100016": { + "de": "Fluggerät nicht aktiviert. Kann nicht abheben. DJI Pilot neu starten und aktivieren", + "en": "Aircraft not activated. Unable to take off. Restart DJI Pilot and activate aircraft", + "es": "Aeronave no activada. No se puede despegar. Reinicia DJI Pilot y activa la aeronave", + "fr": "L\\'appareil n\\'est pas activé. Impossible de décoller. Redémarrez DJI Pilot et activez l\\'appareil", + "ja": "機体が未アクティベーション。離陸できません。DJI Pilotを再起動して機体をアクティベートしてください", + "ko": "활성화 안 된 기체. 이륙 불가. DJI Pilot 재시작 후 기체 활성화해야 함", + "ru": "Дрон не активирован. Взлет невозможен. Перезагрузите DJI Pilot и активируйте дрон", + "tr": "Araç etkinleştirilmemiş. Kalkış yapamıyor. DJI Pilot’u yeniden başlatın ve aracı etkinleştirin", + "zh": "无法起飞:飞行器未激活,请重启App进行激活" + }, + "fpv_tip_0x16100016_in_the_sky": { + "de": "Fluggerät nicht aktiviert. Starten Sie DJI Pilot neu und aktivieren Sie das Fluggerät", + "en": "Aircraft not activated. Restart DJI Pilot and activate aircraft", + "es": "Aeronave no activada. Reinicia DJI Pilot y activa la aeronave", + "fr": "Appareil non activé. Redémarrez DJI Pilot et activez l\\'appareil", + "ja": "機体が未アクティベーション。DJI Pilotを再起動して機体をアクティベートしてください", + "ko": "활성화 안 된 기체. DJI Pilot 재시작 후 기체 활성화해야 함", + "ru": "Дрон не активирован. Перезагрузите DJI Pilot и активируйте дрон", + "tr": "Araç etkinleştirilmemiş. DJI Pilot’u yeniden başlatın ve aracı etkinleştirin", + "zh": "飞行器未激活,请重启App进行激活" + }, + "fpv_tip_0x16100017": { + "de": "Fluggerät befindet sich ein einer GEO-Zone. Start nicht möglich. Bitte Karte auf empfohlene Zonen überprüfen", + "en": "Aircraft in GEO Zone. Unable to take off. Check map to find Recommended Zones", + "es": "Aeronave en zona GEO. No se puede despegar. Comprueba el mapa e identifica las zonas recomendadas", + "fr": "L\\'appareil est dans une zone GEO. Impossible de décoller. Consultez la carte pour trouver les zones recommandées", + "ja": "機体がGEO区域内です。離陸できません。マップを確認して推奨区域を探してください", + "ko": "기체가 GEO 구역 내 있음. 이륙 불가. 지도에서 권장 비행 구역 확인 필요", + "ru": "Дрон в зоне GEO. Взлет невозможен. Найдите рекомендуемые зоны на карте", + "tr": "Araç GEO Bölgesinde. Kalkış yapamıyor. Önerilen Bölgeleri bulmak için haritaya bak", + "zh": "无法起飞:飞行器在限飞区,请查看地图寻找可飞行区域" + }, + "fpv_tip_0x16100017_in_the_sky": { + "de": "Fluggerät befindet sich ein einer GEO-Zone. Bitte Karte auf empfohlene Zonen überprüfen", + "en": "Aircraft in GEO Zone. Check map to find Recommended Zones", + "es": "Aeronave en zona GEO. Comprueba el mapa e identifica las zonas recomendadas", + "fr": "L\\'appareil est dans une zone GEO. Consultez la carte pour trouver les zones recommandées", + "ja": "機体がGEO区域内です。マップを確認して推奨区域を探してください", + "ko": "기체가 GEO 구역 내 있음. 지도에서 권장 비행 구역 확인 필요", + "ru": "Дрон в зоне GEO. Найдите рекомендуемые зоны на карте", + "tr": "Araç GEO Bölgesinde. Önerilen Bölgeleri bulmak için haritaya bak", + "zh": "飞行器在限飞区,请查看地图寻找可飞行区域" + }, + "fpv_tip_0x16100018": { + "de": "IMU-Fehler . Start nicht möglich. IMU kalibrieren", + "en": "IMU error. Unable to take off. Calibrate IMU", + "es": "Error de IMU. No se puede despegar. Calibra la IMU", + "fr": "Erreur d’IMU . Impossible de décoller. Étalonnez l\\'IMU", + "ja": "IMUエラー。離陸できません。IMUをキャリブレーションしてください", + "ko": "IMU 오류 . 이륙 불가. IMU 캘리브레이션 필요", + "ru": "Ошибка IMU . Взлет невозможен. Откалибруйте IMU", + "tr": "IMU hatası. Kalkış yapamıyor. IMU’yu Kalibre Et", + "zh": "无法起飞:IMU 异常,请校准 IMU" + }, + "fpv_tip_0x16100018_in_the_sky": { + "de": "IMU-Initialisierungsfehler . Zum Startpunk zurückkehren oder landen.", + "en": "IMU initialization error. Return to home or land", + "es": "Error de inicio de la IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur d\\'initialisation de l\\'IMU . Revenez au point de départ ou atterrissez", + "ja": "IMU初期化エラー。帰還するか、着陸してください", + "ko": "IMU 초기화 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка запуска IMU . Вернитесь домой или приземлитесь", + "tr": "IMU başlatma hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU 初始化异常,请返航或降落" + }, + "fpv_tip_0x16100019": { + "de": "ESC-Fehler . Kann nicht abheben. Bitte DJI Support kontaktieren", + "en": "ESC error. Unable to take off. Contact DJI Support", + "es": "Error de ESC. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur ESC . Impossible de décoller. Contactez l\\'assistance technique DJI", + "ja": "ESCエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "ESC 오류 . 이륙 불가. DJI 고객지원으로 문의해주세요", + "ru": "Ошибка ESC . Взлет невозможен. Обратитесь в службу поддержки DJI", + "tr": "ESC hatası. Kalkış yapamıyor. DJI Destek ile iletişime geçin", + "zh": "无法起飞:电调异常,请联系售后服务" + }, + "fpv_tip_0x16100019_in_the_sky": { + "de": "ESC-Fehler . Bitte sofort landen.", + "en": "ESC error. Land immediately", + "es": "Error de ESC. Aterriza de inmediato", + "fr": "Erreur ESC . Atterrissez immédiatement", + "ja": "ESCエラー。直ちに着陸してください", + "ko": "ESC 오류 . 즉시 착륙 필요", + "ru": "Ошибка ESC . Приземлитесь немедленно", + "tr": "ESC hatası. Hemen iniş yap", + "zh": "电调异常,请立即降落" + }, + "fpv_tip_0x1610001A": { + "de": "Initialisierung des Sensorsystems. Start nicht möglich. Vor dem Start bitte auf Abschluss der Initialisierung warten", + "en": "Sensor system initializing. Unable to take off. Wait for initialization to complete before taking off", + "es": "Iniciando sistema de sensores. No se puede despegar. Espera a que se complete el inicio antes de despegar", + "fr": "Initialisation du système de capteurs. Impossible de décoller. Attendez la fin de l\\'initialisation avant de décoller", + "ja": "センサーシステム初期化中。離陸できません。初期化が完了するのを待ってから離陸してください", + "ko": "센서 시스템 초기화 중. 이륙 불가. 이륙 전에 초기화가 완료될 때까지 대기", + "ru": "Инициализация системы датчика. Невозможно выполнить взлет. Дождитесь завершения инициализации перед взлетом", + "tr": "Sensör sistemi başlatılıyor. Kalkış yapamıyor. Kalkıştan önce başlatmanın tamamlanmasını bekleyin", + "zh": "无法起飞:传感器系统初始化中,请等待初始化完成" + }, + "fpv_tip_0x1610001A_in_the_sky": { + "de": "Initialisierung des Sensorsystems. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system initializing. Return to home or land", + "es": "Iniciando sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Initialisation du système de capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステム初期化中。帰還するか着陸してください", + "ko": "센서 시스템 초기화 중. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Инициализация системы датчика. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi başlatılıyor. Eve geri dönün veya iniş yapın", + "zh": "传感器系统初始化中,请返航或降落" + }, + "fpv_tip_0x1610001B": { + "de": "System wird aktualisiert . Kann nicht abheben. Warten, bis Aktualisierung abgeschlossen ist", + "en": "System updating. Unable to take off. Wait for update to complete", + "es": "Actualizando el sistema. No se puede despegar. Espera a que se complete la actualización", + "fr": "Mise à jour du système . Impossible de décoller. Patientez jusqu\\'à ce que la mise la jour soit terminée", + "ja": "システム更新中。離陸できません。更新の完了を待ってください", + "ko": "시스템 업데이트 중 . 이륙 불가. 업데이트가 완료될 때까지 기다려야 함", + "ru": "Система обновляется . Взлет невозможен. Дождитесь завершения обновления", + "tr": "Sistem güncelleniyor. Kalkış yapamıyor. Güncellemenin tamamlanmasını bekleyin", + "zh": "无法起飞:系统正在升级,请稍等" + }, + "fpv_tip_0x1610001B_in_the_sky": { + "de": "Systemaktualisierung. Warten, bis die Aktualisierung abgeschlossen ist, bevor Sie abheben .", + "en": "System updating. Wait for update to complete before taking off", + "es": "Actualizando el sistema. Espera a que se complete la actualización antes de despegar", + "fr": "Mise à jour du système en cours. Attendez la fin de la mise à jour avant de décoller", + "ja": "システム更新中。更新が完了してから離陸してください", + "ko": "시스템 업데이트 중. 업데이트가 완료될 때까지 기다린 후 이륙해야 함", + "ru": "Система обновляется. Дождитесь окончания обновления, прежде чем взлетать", + "tr": "Sistem güncelleniyor. Kalkıştan önce güncellemenin tamamlanmasını bekleyin", + "zh": "系统正在升级,请等待升级结束再起飞" + }, + "fpv_tip_0x1610001C": { + "de": "Flugsimulator aktiv . Kann nicht abheben. Neustart durchführen, um zu starten", + "en": "Running Flight Simulator. Unable to take off. Restart aircraft before taking off", + "es": "Se está ejecutando el simulador de vuelo. No se puede despegar. Reinicia la aeronave antes de despegar", + "fr": "Le simulateur de vol est en cours d’utilisation . Impossible de décoller. Redémarrez l’appareil pour décoller", + "ja": "フライトシミュレーター実行中。離陸できません。離陸前に機体を再起動してください", + "ko": "비행 시뮬레이터 실행 중 . 이륙 불가. 이륙하기 전 기체 재시작 필요", + "ru": "Работает симулятор полетов . Взлет невозможен. Перезагрузите дрон перед взлетом", + "tr": "Uçuş Simülatörü Çalışıyor. Kalkış yapamıyor. Kalkıştan önce aracı yeniden başlat", + "zh": "无法起飞:已运行模拟器,起飞需要重启飞行器" + }, + "fpv_tip_0x1610001C_in_the_sky": { + "de": "Flugsimulator aktiv . Neustart durchführen, um zu starten.", + "en": "Running Flight Simulator. Restart aircraft before taking off", + "es": "Se está ejecutando el simulador de vuelo. Reinicia la aeronave antes de despegar", + "fr": "Le simulateur de vol est en cours d’utilisation . Redémarrez l’appareil pour décoller", + "ja": "フライトシミュレーター実行中。離陸前に機体を再起動してください", + "ko": "비행 시뮬레이터 실행 중 . 이륙하기 전 기체 재시작 필요", + "ru": "Работает симулятор полетов . Перезагрузите дрон перед взлетом", + "tr": "Uçuş Simülatörü Çalışıyor. Kalkıştan önce aracı yeniden başlat", + "zh": "已运行模拟器,起飞需要重启飞行器" + }, + "fpv_tip_0x1610001D": { + "de": "IMU-Kalibrierung . Kann nicht abheben. Warten, bis die Kalibrierung abgeschlossen ist", + "en": "IMU calibrating. Unable to take off. Wait for calibration to complete before takeoff", + "es": "Calibrando la IMU. No se puede despegar. Espera a que se complete la calibración antes de despegar", + "fr": "Étalonnage de l\\'IMU en cours . Impossible de décoller. Attendez la fin de l\\'étalonnage avant de décoller", + "ja": "IMUキャリブレーション中。離陸できません。キャリブレーションが完了してから離陸してください", + "ko": "IMU 캘리브레이션 중 . 이륙 불가. 캘리브레이션 완료 후 이륙해야 함", + "ru": "Идет калибровка IMU . Взлет невозможен. Дождитесь завершения процесса, прежде чем взлетать", + "tr": "IMU kalibre ediliyor. Kalkış yapamıyor. Kalkıştan önce kalibrasyonun tamamlanmasını bekleyin", + "zh": "无法起飞:IMU 校准中,请等待校准完毕再起飞" + }, + "fpv_tip_0x1610001D_in_the_sky": { + "de": "IMU wird kalibriert . Bitte warten, bis Kalibrierung abgeschlossen ist, bevor Sie abheben.", + "en": "Calibrating IMU. Wait for calibration to complete before taking off", + "es": "Calibrando la IMU. Espera a que se complete la calibración antes de despegar", + "fr": "Étalonnage de l\\'IMU en cours . Attendez la fin de l\\'étalonnage avant de décoller", + "ja": "IMUキャリブレーション中。キャリブレーションが完了してから離陸してください", + "ko": "IMU 캘리브레이션 중 . 캘리브레이션 완료 후 이륙해야 함", + "ru": "Идет калибровка IMU . Дождитесь ее завершения, прежде чем взлетать", + "tr": "IMU kalibre ediliyor. Kalkıştan önce kalibrasyonun tamamlanmasını bekleyin", + "zh": "IMU 校准中,请等待校准完毕再起飞" + }, + "fpv_tip_0x1610001E": { + "de": "Nickwinkel des Fluggeräts zu groß. Start nicht möglich. Fluggerät vor dem Start auf ebener Fläche abstellen", + "en": "Aircraft pitch angle too large. Unable to take off. Ensure aircraft is level before taking off", + "es": "Ángulo de inclinación de la aeronave demasiado grande. No se puede despegar. Asegúrate de que la aeronave esté nivelada antes de despegar", + "fr": "l\\'angle d\\'inclinaison de l\\'appareil est trop grand. Impossible de décoller. Assurez-vous que l\\'appareil est à l\\'horizontale avant de décoller", + "ja": "機体のピッチ角が大きすぎます。離陸できません。離陸前に機体が水平なことを確認してください", + "ko": "기체 피치각 너무 큼. 이륙 불가. 이륙 전에 기체가 수평인지 확인하세요", + "ru": "Слишком большой угол крена дрона. Невозможно выполнить взлет. Убедитесь, что дрон расположен горизонтально перед взлетом", + "tr": "Aracın adım açısı çok büyük. Kalkış yapamıyor. Kalkış öncesi aracın düz olduğunda emin olun", + "zh": "无法起飞:飞行器倾斜角度过大,请水平放置飞行器后起飞" + }, + "fpv_tip_0x1610001E_in_the_sky": { + "de": "Nickwinkel des Fluggeräts zu groß. Fluggerät vor dem Start auf ebener Fläche abstellen", + "en": "Aircraft pitch angle too large. Ensure aircraft is level before taking off", + "es": "Ángulo de inclinación de la aeronave demasiado grande. Asegúrate de que la aeronave esté nivelada antes de despegar", + "fr": "Angle d\\'inclinaison de l\\'appareil trop grand. Assurez-vous que l\\'appareil est à l\\'horizontale avant de décoller", + "ja": "機体のピッチ角が大きすぎます。離陸前に機体が水平なことを確認してください", + "ko": "기체 피치각 너무 큼. 이륙 전에 기체가 수평인지 확인하세요", + "ru": "Слишком большой угол крена дрона. Убедитесь, что дрон расположен горизонтально перед взлетом", + "tr": "Aracın adım açısı çok büyük. Kalkış öncesi aracın düz olduğunda emin olun", + "zh": "飞行器倾斜角度过大,请水平放置飞行器后起飞" + }, + "fpv_tip_0x1610001F": { + "ar": "", + "de": "Start nicht möglich.Flugregler überhitzt.", + "en": "Unable to take off. Flight controller overheats.", + "es": "No se puede despegar.El controlador de vuelo se sobrecalienta.", + "fr": "Impossible de décoller.Surchauffe du contrôleur de vol.", + "it": "", + "ja": "離陸できません。フライトコントローラーが過熱状態。", + "ko": "이륙 불가. 비행 컨트롤러 과열.", + "pt": "", + "ru": "Невозможно выполнить взлет.Полетный контроллер перегревается.", + "tr": "Kalkış yapamıyor.Uçuş kontrol sistemi aşırı ısındı.", + "zh": "无法起飞:飞控温度过高" + }, + "fpv_tip_0x1610001F_in_the_sky": { + "ar": "", + "de": "Flugregler überhitzt. Rückkehr zum Startpunkt...", + "en": "Flight controller overheats. Returning to home...", + "es": "El controlador de vuelo se sobrecalienta. Regresando al punto de origen...", + "fr": "Surchauffe du contrôleur de vol. Retour au point de départ en cours...", + "it": "", + "ja": "フライトコントローラーが過熱状態。ホームに帰還中...", + "ko": "비행 컨트롤러 과열. RTH 진행 중...", + "pt": "", + "ru": "Полетный контроллер перегревается. Возвращение на базу...", + "tr": "Uçuş kontrol sistemi aşırı ısındı. Başlangıç noktasına dönülüyor...", + "zh": "飞控温度过高,返航中" + }, + "fpv_tip_0x16100020": { + "ar": "", + "de": "Start nicht möglich.Flugregler überhitzt.", + "en": "Unable to take off. Flight controller overheats.", + "es": "No se puede despegar.El controlador de vuelo se sobrecalienta.", + "fr": "Impossible de décoller.Surchauffe du contrôleur de vol.", + "it": "", + "ja": "離陸できません。フライトコントローラーが過熱状態。", + "ko": "이륙 불가. 비행 컨트롤러 과열.", + "pt": "", + "ru": "Невозможно выполнить взлет.Полетный контроллер перегревается.", + "tr": "Kalkış yapamıyor.Uçuş kontrol sistemi aşırı ısındı.", + "zh": "无法起飞:飞控温度过高" + }, + "fpv_tip_0x16100020_in_the_sky": { + "ar": "", + "de": "Flugregler überhitzt. Rückkehr zum Startpunkt...", + "en": "Flight controller overheats. Returning to home...", + "es": "El controlador de vuelo se sobrecalienta. Regresando al punto de origen...", + "fr": "Surchauffe du contrôleur de vol. Retour au point de départ en cours...", + "it": "", + "ja": "フライトコントローラーが過熱状態。ホームに帰還中...", + "ko": "비행 컨트롤러 과열. RTH 진행 중...", + "pt": "", + "ru": "Полетный контроллер перегревается. Возвращение на базу...", + "tr": "Uçuş kontrol sistemi aşırı ısındı. Başlangıç noktasına dönülüyor...", + "zh": "飞控温度过高,返航中" + }, + "fpv_tip_0x16100021": { + "ar": "", + "de": "Start nicht möglich.Flugregler überhitzt.", + "en": "Unable to take off. Flight controller overheats.", + "es": "No se puede despegar.El controlador de vuelo se sobrecalienta.", + "fr": "Impossible de décoller.Surchauffe du contrôleur de vol.", + "it": "", + "ja": "離陸できません。フライトコントローラーが過熱状態。", + "ko": "이륙 불가. 비행 컨트롤러 과열.", + "pt": "", + "ru": "Невозможно выполнить взлет.Полетный контроллер перегревается.", + "tr": "Kalkış yapamıyor.Uçuş kontrol sistemi aşırı ısındı.", + "zh": "无法起飞:飞控温度过高" + }, + "fpv_tip_0x16100021_in_the_sky": { + "ar": "", + "de": "Flugregler überhitzt. Automatische Landung…", + "en": "Flight controller overheats. Auto landing...", + "es": "El controlador de vuelo se sobrecalienta. Realizando aterrizaje automático…", + "fr": "Surchauffe du contrôleur de vol. Atterrissage automatique en cours...", + "it": "", + "ja": "フライトコントローラーが過熱状態。自動着陸中...", + "ko": "비행 컨트롤러 과열. 자동 착륙 진행 중...", + "pt": "", + "ru": "Полетный контроллер перегревается. Автоматическая посадка…", + "tr": "Uçuş kontrol sistemi aşırı ısındı. Otomatik iniş yapılıyor...", + "zh": "飞控温度过高,强制降落中" + }, + "fpv_tip_0x16100024": { + "de": "Kompassstörung. Start nicht möglich. Fluggerät von der Störquelle wegbewegen oder Kompass kalibrieren.", + "en": "Compass interference. Unable to take off. Move away from source of interference or calibrate compass", + "es": "Interferencias en la brújula. No se puede despegar. Aléjese de la fuente de interferencia o calibre la brújula", + "fr": "Interférences avec le compas. Impossible de décoller. Éloignez-vous de la source des interférences ou étalonnez le compas", + "ja": "コンパスの干渉。離陸できません。干渉源から離れるかコンパス キャリブレーションを行ってください", + "ko": "콤파스 간섭. 이륙 불가. 간섭원에서 멀어지거나 콤파스 캘리브레이션 필요", + "ru": "Помехи в работе компаса. Не удается выполнить взлет. Отдалитесь от источника помех или откалибруйте компас", + "tr": "Pusula paraziti. Kalkış yapılamıyor. Parazit kaynağından uzaklaşın veya pusulanın kalibrasyonunu yapın", + "zh": "无法起飞:指南针受到干扰,请远离干扰或校准指南针" + }, + "fpv_tip_0x16100025": { + "ar": "", + "de": "Hot Swapping wird für das RTK-Modul nicht unterstützt. Start nicht möglich.", + "en": "Hot swapping not supported for RTK module. Unable to take off", + "es": "El intercambio en caliente no es compatible con el módulo RTK. No se puede despegar", + "fr": "Le remplacement à chaud n'est pas pris en charge pour le module RTK. Impossible de décoller", + "it": "", + "ja": "ホットスワップはRTKモジュールではサポートされていません。離陸できません", + "ko": "RTK 모듈에서는 핫 스와핑이 지원되지 않습니다. 이륙 불가", + "pt": "", + "ru": "Горячая замена не поддерживается для модуля RTK. Не удается выполнить взлет", + "tr": "RTK modülü için çalışırken değiştirme desteklenmiyor. Kalkış yapılamıyor", + "zh": "无法起飞:RTK模块不支持热插拔" + }, + "fpv_tip_0x16100025_in_the_sky": { + "ar": "", + "de": "RTK-Fehler. Umgehend landen.", + "en": "RTK error. Land promptly", + "es": "Error de RTK. Aterrice rápidamente", + "fr": "Erreur RTK. Atterrissez immédiatement", + "it": "", + "ja": "RTKエラーです。直ちに着陸させてください", + "ko": "RTK 오류. 즉시 착륙하세요", + "pt": "", + "ru": "Ошибка RTK. Немедленно выполните посадку", + "tr": "RTK hatası. Derhal iniş yapın", + "zh": "RTK异常,请尽快降落" + }, + "fpv_tip_0x16100026": { + "de": "Start nicht möglich. RTK-Modul eines Fremdherstellers erkannt", + "en": "Unable to take off. Non-DJI RTK module detected", + "es": "No se puede despegar. Módulo RTK no DJI detectado", + "fr": "Impossible de décoller. Module RTK autre que DJI détecté", + "ja": "離陸できません。DJI以外のRTKモジュールが検出されました", + "ko": "이륙 불가. 비 DJI RTK 모듈이 감지되었습니다", + "ru": "Не удается выполнить взлет. Обнаружен модуль RTK, не являющийся продуктом DJI", + "tr": "Kalkış yapılamıyor. DJI marka olmayan RTK modülü tespit edildi", + "zh": "无法起飞:检测到非官方RTK模块" + }, + "fpv_tip_0x16100026_in_the_sky": { + "de": "RTK-Modul eines Fremdherstellers erkannt", + "en": "Non-DJI RTK module detected", + "es": "Módulo RTK no DJI detectado", + "fr": "Module RTK autre que DJI détecté", + "ja": "DJI以外のRTKモジュールが検出されました", + "ko": "비 DJI RTK 모듈이 감지되었습니다", + "ru": "Обнаружен модуль RTK, не являющийся продуктом DJI", + "tr": "DJI marka olmayan RTK modülü tespit edildi", + "zh": "检测到非官方RTK模块" + }, + "fpv_tip_0x16100027": { + "ar": "", + "de": "Fehler: Flugregler. Start nicht möglich", + "en": "Flight control system error. Unable to take off", + "es": "Error en el sistema de control de vuelo. No se puede despegar", + "fr": "Erreur du système de contrôle du vol. Impossible de décoller", + "it": "", + "ja": "フライトコントロールシステムのエラー。離陸できません", + "ko": "비행 제어 시스템 오류. 이륙 불가", + "pt": "", + "ru": "Ошибка системы управления полетом. Не удается выполнить взлет", + "tr": "Uçuş kontrol sistemi hatası. Kalkış yapılamıyor", + "zh": "无法起飞:飞控系统异常" + }, + "fpv_tip_0x16100027_in_the_sky": { + "ar": "", + "de": "Fehler: Flugregler. Umgehend landen", + "en": "Flight control system error. Land promptly", + "es": "Error en el sistema de control de vuelo. Aterriza rápidamente", + "fr": "Erreur du système de contrôle du vol. Atterrissez immédiatement.", + "it": "", + "ja": "フライトコントロールシステムのエラー。直ちに着陸してください", + "ko": "비행 제어 시스템 오류. 즉시 착륙해주세요.", + "pt": "", + "ru": "Ошибка системы управления полетом. Немедленно выполните посадку", + "tr": "Uçuş kontrol sistemi hatası. Derhal iniş yapın", + "zh": "飞控系统异常,请尽快降落" + }, + "fpv_tip_0x16100029": { + "de": "Seriennummer des Fluggeräts ungültig. Kann nicht abheben. An Händler vor Ort oder an DJI-Support wenden", + "en": "Invalid aircraft serial number. Unable to take off. Contact your local dealer or DJI Support", + "es": "Número de serie de la aeronave no válido. No se puede despegar. Ponte en contacto con el distribuidor local o la asistencia técnica de DJI", + "fr": "N° de série appareil invalide. Impossible de décoller. Contactez votre revendeur local ou l\\'assistance technique DJI", + "ja": "無効な機体シリアルナンバー。離陸できません。最寄りの代理店またはDJIサポートにお問い合わせください", + "ko": "유효하지 않은 기체 시리얼 넘버. 이륙 불가. 현지 딜러 또는 DJI 고객지원으로 문의해주세요", + "ru": "Неверный серийный номер дрона. Взлет невозможен. Обратитесь к местному представителю или в службу поддержки DJI", + "tr": "Aracın seri numarası geçersiz. Kalkış yapamıyor. Yerel satıcınızla ya da DJI Destek ile iletişime geçin", + "zh": "无法起飞:飞行器SN异常,请联系就近代理商或者大疆售后服务" + }, + "fpv_tip_0x16100029_in_the_sky": { + "de": "Ungültige Seriennummer des Fluggeräts . Zum Startpunkt zurückkehren oder landen.", + "en": "Invalid aircraft serial number. Return to home or land", + "es": "Número de serie de la aeronave no válido. Regresa al punto de origen o aterriza", + "fr": "N° de série appareil invalide . Revenez au point de départ ou atterrissez", + "ja": "無効な機体シリアルナンバー。帰還するか、着陸してください", + "ko": "유효하지 않은 기체 시리얼 넘버 . RTH 진행 또는 착륙 필요", + "ru": "Неверный серийный номер дрона . Вернитесь домой или приземлитесь", + "tr": "Aracın seri numarası geçersiz. Eve geri dönün veya iniş yapın", + "zh": "飞行器SN异常,请返航或降落" + }, + "fpv_tip_0x1610002D": { + "de": "GPS getrennt . Start nicht möglich. Fluggerät neu starten", + "en": "GPS disconnected. Unable to take off. Restart aircraft", + "es": "GPS no conectado. No se puede despegar. Reinicia la aeronave", + "fr": "GPS déconnecté . Impossible de décoller. Redémarrez l’appareil", + "ja": "GPSが切断されました。離陸できません。機体を再起動してください", + "ko": "GPS 연결 끊김 . 이륙 불가. 기체 재시작 필요", + "ru": "GPS отключена . Взлет невозможен. Перезагрузите дрон", + "tr": "GPS bağlantısı kesildi. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:GPS断开连接,请重启飞行器" + }, + "fpv_tip_0x1610002D_in_the_sky": { + "de": "GPS getrennt . Zum Startpunkt zurückkehren oder landen.", + "en": "GPS disconnected. Return to home or land", + "es": "GPS no conectado. Regresa al punto de origen o aterriza", + "fr": "GPS déconnecté . Revenez au point de départ ou atterrissez", + "ja": "GPSが切断されました。帰還するか、着陸してください", + "ko": "GPS 연결 끊김 . RTH 진행 또는 착륙 필요", + "ru": "GPS отключена . Вернитесь домой или приземлитесь", + "tr": "GPS bağlantısı kesildi. Eve geri dönün veya iniş yapın", + "zh": "GPS断开连接,请返航或降落" + }, + "fpv_tip_0x1610002F": { + "de": "Fehler: Datenrekorder . Start nicht möglich. Fluggerät neu starten", + "en": "Data recorder error. Unable to take off. Restart aircraft", + "es": "Error de la grabadora de datos. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur enregistreur de données . Impossible de décoller. Redémarrez l\\'appareil", + "ja": "データ記録機エラー。離陸できません。機体を再起動してください", + "ko": "데이터 기록기 오류 . 이륙 불가. 기체 재시작 필요", + "ru": "Ошибка записи данных . Взлет невозможен. Перезагрузите дрон", + "tr": "Veri kaydedici hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:数据记录仪异常,请重启飞行器" + }, + "fpv_tip_0x1610002F_in_the_sky": { + "de": "Datenfehler . Zum Startpunkt zurückkehren oder landen.", + "en": "Data recorder error. Return to home or land", + "es": "Error de la grabadora de datos. Regresa al punto de origen o aterriza", + "fr": "Erreur enregistreur de données . Revenez au point de départ ou atterrissez", + "ja": "データ記録機エラー。帰還するか、着陸してください", + "ko": "데이터 기록기 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка регистратора данных . Вернитесь домой или приземлитесь", + "tr": "Veri kaydedici hatası. Eve geri dönün veya iniş yapın", + "zh": "数据记录仪异常,请返航或降落" + }, + "fpv_tip_0x16100030": { + "de": "Fluggerät und Firmware-Version stimmen nicht überein . Start nicht möglich. An Händler vor Ort oder an DJI-Support wenden", + "en": "Aircraft model and firmware version do not match. Unable to take off. Contact your local dealer or DJI Support.", + "es": "El modelo de la aeronave y la versión del firmware no coinciden. No se puede despegar. Ponte en contacto con el distribuidor local o la asistencia técnica de DJI.", + "fr": "Le modèle de l\\'appareil et la version du firmware ne correspondent pas . Impossible de décoller. Contactez votre revendeur local ou l\\'assistance technique DJI", + "ja": "機体モデルとファームウェアバージョンが一致しません。離陸できません。最寄りの代理店またはDJIサポートにお問い合わせください", + "ko": "기체 모델과 펌웨어 버전 불일치 . 이륙 불가. 현지 딜러 또는 DJI 고객지원으로 문의해주세요", + "ru": "Модель дрона не совпадает с версией ПО . Взлет невозможен. Обратитесь к местному представителю или в службу поддержки DJI.", + "tr": "Araç modeli ve yazılım sürümü eşleşmiyor. Kalkış yapamıyor. Yerel satıcınızla ya da DJI Destek ile iletişime geçin.", + "zh": "无法起飞:飞行器机型与固件不匹配,请联系就近代理商或大疆售后服务" + }, + "fpv_tip_0x16100030_in_the_sky": { + "de": "Fluggerät und Firmware-Version stimmen nicht überein . Zum Startpunkt zurückkehren oder landen.", + "en": "Aircraft model and firmware version do not match. Return to home or land", + "es": "El modelo de la aeronave y la versión del firmware no coinciden. Regresa al punto de origen o aterriza", + "fr": "Le modèle de l\\'appareil et la version du firmware ne correspondent pas . Revenez au point de départ ou atterrissez", + "ja": "機体モデルとファームウェアバージョンが一致しません。帰還するか、着陸してください", + "ko": "기체 모델과 펌웨어 버전 불일치 . RTH 진행 또는 착륙 필요", + "ru": "Модель дрона не совпадает с версией ПО . Вернитесь домой или приземлитесь", + "tr": "Araç modeli ve yazılım sürümü eşleşmiyor. Eve geri dönün veya iniş yapın", + "zh": "飞行器机型与固件不匹配,请返航或降落" + }, + "fpv_tip_0x16100031": { + "en": "Unable to take off. Hook is not fully retracted. Make sure hook is retracted and secure", + "zh": "无法起飞:空吊系统挂钩没有收到位,请将挂钩收到位" + }, + "fpv_tip_0x16100032": { + "en": "Winch cable wound in reverse direction. Unable to take off. Manually unwind cable before takeoff", + "zh": "无法起飞:空吊系统线绳反绕,请整理线绳后起飞" + }, + "fpv_tip_0x16100032_in_the_sky": { + "en": "Winch cable wound in reverse direction. Do not operate winch system and land promptly to unwind cable", + "zh": "空吊系统线绳反绕,请勿操作空吊并尽快降落理线" + }, + "fpv_tip_0x16100033": { + "de": "Registrierung mit Klarnamen wurde nicht durchgeführt. Vor dem Flug die Hilfedokumentation beachten und eine Registrierung mit Klarnamen anhand der Anweisungen abschließen", + "en": "Real-name registration is not performed. View Help Documentation and complete real-name registration based on instructions before flight", + "es": "No se ha realizado el registro de nombre real. Echa un vistazo a la documentación de ayuda y completa el registro de nombre real según las instrucciones antes del vuelo", + "fr": "L'enregistrement du nom réel n'est pas effectué. Consultez les documents d'aide et effectuez l'enregistrement du nom réel en fonction des instructions avant le vol", + "ja": "実名の登録が行われていません。飛行前に手順に従ってヘルプドキュメントを参照し、実名の登録を完了してください", + "ko": "실명 등록이 수행되지 않았습니다. 비행 전에 지침에 따라 도움말 문서를 보고 실명 등록을 완료하세요.", + "ru": "Регистрация с использованием настоящего имени не пройдена. Изучите справочную документацию и завершите регистрацию по инструкции перед началом полета", + "tr": "Asıl adla kayıt işlemi gerçekleştirilmedi. Uçuş öncesinde Yardım Belgesine bakın ve talimatlara uygun olarak asıl adla kayıt işlemini tamamlayın", + "zh": "飞机未完成实名登记,请点击查看帮助文档,按照指引完成实名登记后飞行" + }, + "fpv_tip_0x16100034": { + "de": "Registrierung mit Klarnamen wurde abgebrochen. Vor dem Flug die Hilfedokumentation beachten und eine Registrierung mit Klarnamen anhand der Anweisungen abschließen", + "en": "Real-name registration is canceled. View Help Documentation and complete real-name registration based on instructions before flight", + "es": "Se ha cancelado el registro de nombre real. Echa un vistazo a la documentación de ayuda y completa el registro de nombre real según las instrucciones antes del vuelo", + "fr": "L'enregistrement du nom réel est annulé. Consultez les documents d'aide et effectuez l'enregistrement du nom réel en fonction des instructions avant le vol", + "ja": "実名の登録がキャンセルされました。飛行前に手順に従ってヘルプドキュメントを参照し、実名の登録を完了してください", + "ko": "실명 등록이 취소되었습니다. 비행 전에 지침에 따라 도움말 문서를 보고 실명 등록을 완료하세요.", + "ru": "Регистрация с использованием настоящего имени отменена. Изучите справочную документацию и завершите регистрацию по инструкции перед началом полета", + "tr": "Asıl adla kayıt işlemi iptal edildi. Uçuş öncesinde Yardım Belgesine bakın ve talimatlara uygun olarak asıl adla kayıt işlemini tamamlayın", + "zh": "飞行器实名登记状态已注销,请点击查看帮助文档,按照指引完成实名登记后飞行" + }, + "fpv_tip_0x1610003D": { + "de": "Sensorsystem getrennt . Start nicht möglich. Fluggerät neu starten", + "en": "Sensor system disconnected. Unable to take off. Restart aircraft", + "es": "Sistema de sensores no conectado. No se puede despegar. Reinicia la aeronave", + "fr": "Système de capteurs déconnecté . Impossible de décoller. Redémarrez l\\'appareil", + "ja": "センサーシステム未接続。離陸できません。機体を再起動してください", + "ko": "센서 시스템 연결 끊김 . 이륙 불가. 기체 재시작 필요", + "ru": "Система датчиков отключена . Взлет невозможен. Перезагрузите дрон", + "tr": "Sensör sistemi bağlantısı kesildi. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:传感器系统断开,请重启飞行器" + }, + "fpv_tip_0x1610003D_in_the_sky": { + "de": "Sensorsystem getrennt . Zum Startpunkt zurückkehren oder landen.", + "en": "Sensor system disconnected. Return to home or land", + "es": "Sistema de sensores no conectado. Regresa al punto de origen o aterriza", + "fr": "Système de capteurs déconnecté . Revenez au point de départ ou atterrissez", + "ja": "センサーシステム未接続。帰還するか、着陸してください", + "ko": "센서 시스템 연결 끊김 . RTH 진행 또는 착륙 필요", + "ru": "Системы датчиков отключена . Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi bağlantısı kesildi. Eve geri dönün veya iniş yapın", + "zh": "传感器系统断开,请返航或降落" + }, + "fpv_tip_0x1610003E": { + "ar": "", + "de": "Start nicht möglich. Fernsteuerung wird kalibriert. Auf Abschluss der Kalibrierung warten", + "en": "Unable to take off. Calibrating remote controller. Wait for calibration to complete", + "es": "No se puede despegar. Calibrando el control remoto. Espere a que se complete la calibración", + "fr": "Impossible de décoller. Étalonnage de la radiocommande. Attendez que l'étalonnage soit terminé", + "it": "", + "ja": "離陸できません。送信機のキャリブレーション中。キャリブレーションが完了するまでお待ちください", + "ko": "이륙 불가. 조종기 캘리브레이션 중. 캘리브레이션이 완료될 때까지 기다려 주세요", + "pt": "", + "ru": "Не удается выполнить взлет. Калибровка пульта. Дождитесь завершения калибровки", + "tr": "Kalkış yapılamıyor. Uzaktan kumanda kalibre ediliyor. Kalibre işleminin tamamlanmasını bekleyin", + "zh": "无法起飞:遥控器校准中,请完成校准流程" + }, + "fpv_tip_0x16100041": { + "ar": "", + "de": "Start nicht möglich. Steuerknüppel nicht zentriert. Fernsteuerung kalibrieren", + "en": "Unable to take off. Control sticks off-centered. Calibrate remote controller", + "es": "No se puede despegar. Las palancas de control están descentradas. Calibre el control remoto", + "fr": "Impossible de décoller. Joysticks décentrés. Étalonner la radiocommande", + "it": "", + "ja": "離陸できません。操作スティックの中心がずれています。送信機をキャリブレーションしてください", + "ko": "이륙 불가. 조종 스틱이 중앙에 있지 않습니다. 조종기 캘리브레이션", + "pt": "", + "ru": "Не удается выполнить взлет. Ручки управления смещены относительно центра. Выполните калибровку пульта", + "tr": "Kalkış yapılamıyor. Kumanda çubukları merkez dışı. Uzaktan kumandayı kalibre edin", + "zh": "无法起飞:摇杆不在中位,请校准遥控器" + }, + "fpv_tip_0x16100042": { + "ar": "", + "de": "Start nicht möglich. Steuerknüppel-Hardwarefehler. DJI Support kontaktieren.", + "en": "Unable to take off. Control stick hardware error. Contact DJI Support", + "es": "No se puede despegar. Error de hardware de la palanca de control. Póngase en contacto con la Asistencia técnica de DJI", + "fr": "Impossible de décoller. Erreur matérielle du joystick. Contactez le service client DJI", + "it": "", + "ja": "離陸できません。操作スティックのハードウェアエラー。DJIサポートまでお問い合わせください", + "ko": "이륙 불가. 조종 스틱 하드웨어 오류. DJI 고객지원으로 문의하세요", + "pt": "", + "ru": "Не удается выполнить взлет. Аппаратная ошибка ручки управления. Свяжитесь со службой поддержки DJI", + "tr": "Kalkış yapılamıyor. Kontrol çubuğu donanım hatası. DJI Destek ekibiyle iletişime geçin", + "zh": "无法起飞:摇杆硬件异常,请联系售后" + }, + "fpv_tip_0x16100042_in_the_sky": { + "ar": "", + "de": "Steuerknüppel-Hardwarefehler. Umgehend landen. DJI Support kontaktieren.", + "en": "Control stick hardware error. Land promptly. Contact DJI Support", + "es": "Error de hardware de la palanca de control. Aterriza rápidamente. Póngase en contacto con la Asistencia técnica de DJI", + "fr": "Erreur matérielle du joystick. Atterrissez immédiatement. Contactez le service client DJI", + "it": "", + "ja": "操作スティックのハードウェアエラー。直ちに着陸してください。DJIサポートまでお問い合わせください", + "ko": "조종 스틱 하드웨어 오류. 즉시 착륙하세요. DJI 고객지원으로 문의하세요", + "pt": "", + "ru": "Аппаратная ошибка ручки управления. Немедленно выполните посадку. Свяжитесь со службой поддержки DJI", + "tr": "Kontrol çubuğu donanım hatası. Derhal iniş yapın. DJI Destek ekibiyle iletişime geçin", + "zh": "摇杆硬件异常,请尽快降落,并联系售后" + }, + "fpv_tip_0x1610004A": { + "de": "Fehler: Sensorsystem . Start nicht möglich. Fluggerät neu starten", + "en": "Sensor system error. Unable to take off. Restart aircraft", + "es": "Error del sistema de sensores. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur du système de capteurs . Impossible de décoller. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。離陸できません。機体を再起動してください", + "ko": "센서 시스템 오류 . 이륙 불가. 기체 재시작 필요", + "ru": "Ошибка системы датчиков . Взлет невозможен. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x1610004A_in_the_sky": { + "de": "Fehler: Sensorsystem . Zum Startpunkt zurückkehren oder landen.", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système de capteurs . Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか、着陸してください", + "ko": "센서 시스템 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков . Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x1610004B": { + "de": "Fehler: Sensorsystem. Start nicht möglich. Fluggerät neu starten", + "en": "Sensor system error. Unable to take off. Restart aircraft", + "es": "Error del sistema de sensores. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Impossible de décoller. Redémarrez l\\'appareil", + "ja": "センサーシステムエラー。離陸できません。機体を再起動してください", + "ko": "센서 시스템 오류. 이륙 불가. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Невозможно выполнить взлет. Перезагрузите дрон", + "tr": "Sensör sistemi hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x1610004B_in_the_sky": { + "de": "Fehler: Sensorsystem. Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur système capteur. Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x1610004C": { + "ar": "", + "de": "", + "en": "Unable to take off. Remote Controller Calibration Required", + "es": "", + "fr": "", + "it": "", + "ja": "", + "ko": "", + "pt": "", + "ru": "", + "tr": "", + "zh": "无法起飞:遥控器摇杆需要校准" + }, + "fpv_tip_0x1610004D": { + "de": "Datenfehler: Flugregler. Kann nicht abheben. Fluggerät neu starten", + "en": "Flight controller data error. Unable to take off. Restart aircraft", + "es": "Error de datos del controlador de vuelo. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur de données du contrôleur du vol. Impossible de décoller. Redémarrez l\\'appareil", + "ja": "フライトコントローラー データエラー。離陸できません。機体を再起動してください", + "ko": "비행 컨트롤러 데이터 오류. 이륙 불가. 기체 재시작 필요", + "ru": "Ошибка данных полетного контроллера. Взлет невозможен. Перезагрузите дрон", + "tr": "Uçuş kumandası veri hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:飞控数据异常,请重启飞行器" + }, + "fpv_tip_0x1610004D_in_the_sky": { + "de": "Datenfehler . Zum Startpunkt zurückkehren oder landen.", + "en": "Flight controller data error. Return to home or land", + "es": "Error de datos del controlador de vuelo. Regresa al punto de origen o aterriza", + "fr": "Erreur données du contrôleur de vol . Revenez au point de départ ou atterrissez", + "ja": "フライトコントローラー データエラー。帰還するか、着陸してください", + "ko": "비행 컨트롤러 데이터 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка данных полетного контроллера . Вернитесь домой или приземлитесь", + "tr": "Uçuş kumandası veri hatası. Eve geri dönün veya iniş yapın", + "zh": "飞控数据异常,请返航或降落" + }, + "fpv_tip_0x1610004E": { + "de": "Nicht genug Akkus installiert. Kann nicht abheben. Vor dem Start zwei Akkus einlegen", + "en": "Not enough batteries installed. Unable to take off. Insert two batteries before taking off", + "es": "No hay suficientes baterías instaladas. No se puede despegar. Instala dos baterías antes de despegar", + "fr": "Pas assez de batteries installées. Impossible de décoller. Installez deux batteries avant de décoller", + "ja": "装着バッテリーが不足。離陸できません。バッテリーを2つ取り付けてから離陸してください", + "ko": "배터리 개수 부족. 이륙 불가. 이륙하기 전 배터리 2개를 장착해야 함", + "ru": "Не хватает батарей. Взлет невозможен. Установите две батареи для взлета", + "tr": "Yeterli pil takılmamış. Kalkış yapamıyor. Kalkıştan önce iki pil takın", + "zh": "无法起飞:电池数量过少,请插入两块电池再起飞" + }, + "fpv_tip_0x1610004E_in_the_sky": { + "de": "Nicht genügend Akkus. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Insufficient batteries. Return to home or land promptly", + "es": "No hay suficientes baterías. Regrese al punto de origen o aterrice rápidamente", + "fr": "Pas assez de batteries. Retournez au point de départ ou atterrissez rapidement", + "ja": "バッテリー不足。直ちに帰還するか、着陸してください", + "ko": "배터리 부족. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Недостаточный заряд АКБ. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Yetersiz pil. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "电池数量过少,请尽快返航或降落" + }, + "fpv_tip_0x1610004F": { + "de": "Batterieauthentifizierung fehlgeschlagen. Kann nicht abheben. Durch DJI-Akku ersetzen", + "en": "Battery authentication failed. Unable to take off. Replace with DJI battery", + "es": "Error de autenticación de la batería. No se puede despegar. Reemplázala por una batería de DJI", + "fr": "L\\'authentification de la batterie a échoué. Impossible de décoller. Remplacez-la avec une batterie DJI", + "ja": "バッテリーの認証に失敗しました。離陸できません。DJIバッテリーに交換してください", + "ko": "배터리 인증 실패. 이륙 불가. 표준 DJI 배터리로 교체해야 함", + "ru": "Не удалось опознать батарею. Взлет невозможен. Замените ее на аккумулятор DJI", + "tr": "Pil kimlik doğrulaması başarısız. Kalkış yapamıyor. DJI pili ile değiştirin", + "zh": "无法起飞:电池认证失败,请更换DJI官方电池" + }, + "fpv_tip_0x1610004F_in_the_sky": { + "de": "Batterieauthentifizierung fehlgeschlagen. Durch Standard-DJI-Akku ersetzen", + "en": "Battery authentication failed. Replace with standard DJI battery", + "es": "Error de autenticación de la batería. Reemplázala por una batería estándar de DJI", + "fr": "L\\'authentification de la batterie a échoué. Remplacez-la avec une batterie DJI standard", + "ja": "バッテリーの認証に失敗しました。標準のDJIバッテリーと交換してください", + "ko": "배터리 인증 실패. 표준 DJI 배터리로 교체해야 함", + "ru": "Не удалось опознать батарею. Замените ее на стандартный аккумулятор DJI", + "tr": "Pil kimlik doğrulaması başarısız. Standart bir DJI pili ile değiştirin", + "zh": "电池认证失败,请更换DJI官方电池" + }, + "fpv_tip_0x16100051": { + "de": "Großer Spannungsunterschied zwischen Akkus. Start nicht möglich. Akkus durch neue mit ähnlicher Kapazität ersetzen", + "en": "Large voltage difference between batteries. Unable to take off. Replace batteries with new ones of a similar capacity", + "es": "Gran diferencia de voltaje entre las baterías. No se puede despegar. Reemplázalas por baterías nuevas con una capacidad similar", + "fr": "Différence de tension entre les batteries importante. Décollage impossible. Remplacez-les avec des batteries dont le nombre de cycles est similaire", + "ja": "バッテリーの電圧差が大きすぎます。離陸できません。同程度の容量の新品のバッテリーと交換してください", + "ko": "배터리 간 큰 전압 차이. 이륙할 수 없습니다. 비슷한 용량의 신품 배터리로 교체하세요", + "ru": "Большая разница напряжения между аккумуляторами. Невозможно выполнить взлет. Замените аккумуляторы на новые с аналогичной емкостью", + "tr": "Piller arasında yüksek voltaj farkı. Kalkış yapamıyor. Pilleri aynı kapasitedeki yeni pillerle değiştirin", + "zh": "无法起飞:两块电池间压差过大,更换电量相近的电池组继续飞行" + }, + "fpv_tip_0x16100051_in_the_sky": { + "de": "Großer Spannungsunterschied zwischen Akkus. Zum Startpunkt zurückkehren oder landen. Akkus durch neue mit ähnlicher Kapazität ersetzen und erneut versuchen", + "en": "Large voltage difference between batteries. Return to home or land. Replace batteries with new ones of a similar capacity and try again", + "es": "Gran diferencia de voltaje entre las baterías. Regresa al punto de origen o aterriza. Reemplázalas por baterías nuevas con una capacidad similar y vuelve a intentarlo", + "fr": "Différence de tension entre les batteries importante. Revenez au point de départ ou atterrissez. Remplacez les batteries avec des nouvelles d\\'une capacité similaire et réessayez", + "ja": "バッテリーの電圧差が大きすぎます。帰還するか着陸してください。バッテリーを同程度の容量の新品のものと交換して再試行してください", + "ko": "배터리 간 큰 전압 차이. 홈으로 돌아가거나 착륙하세요. 비슷한 용량의 신품 배터리로 교체하고 다시 시도하세요", + "ru": "Большая разница напряжения между аккумуляторами. Вернитесь домой или приземлитесь. Замените аккумуляторы на новые с аналогичной емкостью и повторите попытку", + "tr": "Piller arasında yüksek voltaj farkı. Eve geri dönün veya iniş yapın. Pilleri aynı kapasitedeki yeni pillerle değiştirin ve tekrar deneyin", + "zh": "两块电池间压差过大,请返航或降落,更换电量相近的电池组继续飞行" + }, + "fpv_tip_0x16100053": { + "de": "Firmware-Versionen des Fluggerätemoduls stimmen nicht überein. Kann nicht abheben. Auf neuesten Firmware-Versionen aktualisieren", + "en": "Aircraft module firmware versions do not match. Unable to take off. Update to latest firmware versions.", + "es": "Las versiones del firmware del módulo de la aeronave no coinciden. No se puede despegar. Actualiza a las versiones del firmware más recientes.", + "fr": "Les versions des firmwares des modules de l\\'appareil ne correspondent pas. Impossible de décoller. Mettez-les à jour vers les versions les plus récentes", + "ja": "機体モジュールのファームウェアバージョンが不一致。離陸できません。最新のファームウェアバージョンに更新してください。", + "ko": "기체 모듈 펌웨어 버전 불일치. 이륙 불가. 최신 펌웨어 버전으로 업데이트 필요", + "ru": "Версии ПО модулей дрона не совпадают. Взлет невозможен. Установите последние версии ПО", + "tr": "Araç modül yazılımı sürümleri eşleşmiyor. Kalkış yapamıyor. En güncel yazılım sürümlerine güncelleyin.", + "zh": "无法起飞:飞行器模块间固件不匹配,请升级固件版本" + }, + "fpv_tip_0x16100053_in_the_sky": { + "de": "Firmware-Versionen des Fluggerätemoduls stimmen nicht überein. Update auf die neuesten Firmware-Versionen", + "en": "Aircraft module firmware versions do not match. Update to latest firmware versions", + "es": "Las versiones del firmware del módulo de la aeronave no coinciden. Actualiza a las versiones del firmware más recientes", + "fr": "Les versions des firmwares des modules de l\\'appareil ne correspondent pas. Mettez à jour vers les versions de firmwares les plus récentes", + "ja": "機体モジュールのファームウェアバージョンが不一致。最新のファームウェアバージョンに更新してください", + "ko": "기체 모듈 펌웨어 버전 불일치. 최신 펌웨어 버전으로 업데이트 필요", + "ru": "Версии ПО модулей дрона не совпадают. Установите последние версии", + "tr": "Araç modül yazılımı sürümleri eşleşmiyor. En güncel yazılım sürümlerine güncelleyin", + "zh": "飞行器模块间固件不匹配,请升级固件版本" + }, + "fpv_tip_0x16100054": { + "de": "Fehler: Gimbal . Kann nicht abheben. Bitte DJI-Support kontaktieren.", + "en": "Gimbal error. Unable to take off. Contact DJI Support", + "es": "Error del estabilizador. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de nacelle . Impossible de décoller. Contactez l\\'assistance technique DJI", + "ja": "ジンバルエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "짐벌 오류 . 이륙 불가. DJI 고객지원으로 문의해주세요", + "ru": "Ошибка стабилизатора . Взлет невозможен. Обратитесь в службу поддержки DJI", + "tr": "Gimbal hatası. Kalkış yapamıyor. DJI Destek ile iletişime geçin", + "zh": "无法起飞:云台异常,请联系大疆售后服务" + }, + "fpv_tip_0x16100054_in_the_sky": { + "de": "Gimbalfehler . Zum Startpunkt zurückkehren oder landen.", + "en": "Gimbal error. Return to home or land", + "es": "Error del estabilizador. Regresa al punto de origen o aterriza", + "fr": "Erreur nacelle . Revenez au point de départ ou atterrissez", + "ja": "ジンバルエラー。帰還するか、着陸してください", + "ko": "짐벌 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка стабилизатора . Вернитесь домой или приземлитесь", + "tr": "Gimbal hatası. Eve geri dönün veya iniş yapın", + "zh": "云台异常,返航或降落" + }, + "fpv_tip_0x16100055": { + "de": "Gimbal-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "Gimbal error. Unable to take off. Contact DJI Support", + "es": "Error del estabilizador. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de nacelle. Impossible de décoller. Contactez l\\'assistance technique DJI", + "ja": "ジンバルエラー。離陸できません。DJIサポートにお問い合わせください", + "ko": "짐벌 오류. 이륙 불가. DJI 고객지원으로 문의", + "ru": "Ошибка стабилизатора. Невозможно выполнить взлет. Обратитесь в службу поддержки DJI", + "tr": "Gimbal hatası. Kalkış yapamıyor. DJI Destek ile iletişime geçin", + "zh": "无法起飞:云台异常,请联系大疆售后服务" + }, + "fpv_tip_0x16100055_in_the_sky": { + "de": "Gimbal-Fehler. Zum Startpunkt zurückkehren oder landen", + "en": "Gimbal error. Return to home or land", + "es": "Error del estabilizador. Regresa al punto de origen o aterriza", + "fr": "Erreur nacelle. Revenez au point de départ ou atterrissez", + "ja": "ジンバルエラー。帰還するか着陸してください", + "ko": "짐벌 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка стабилизатора. Вернитесь домой или приземлитесь", + "tr": "Gimbal hatası. Eve geri dönün veya iniş yapın", + "zh": "云台异常,返航或降落" + }, + "fpv_tip_0x16100056": { + "de": "Gimbal-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "Gimbal error. Unable to take off. Contact DJI Support", + "es": "Error del estabilizador. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de nacelle. Impossible de décoller. Contactez l\\'assistance technique DJI", + "ja": "ジンバルエラー。離陸できません。DJIサポートにお問い合わせください", + "ko": "짐벌 오류. 이륙 불가. DJI 고객지원으로 문의", + "ru": "Ошибка стабилизатора. Невозможно выполнить взлет. Обратитесь в службу поддержки DJI", + "tr": "Gimbal hatası. Kalkış yapamıyor. DJI Destek ile iletişime geçin", + "zh": "无法起飞:云台异常,请联系大疆售后服务" + }, + "fpv_tip_0x16100056_in_the_sky": { + "de": "Gimbal-Fehler. Zum Startpunkt zurückkehren oder landen", + "en": "Gimbal error. Return to home or land", + "es": "Error del estabilizador. Regresa al punto de origen o aterriza", + "fr": "Erreur nacelle. Revenez au point de départ ou atterrissez", + "ja": "ジンバルエラー。帰還するか着陸してください", + "ko": "짐벌 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка стабилизатора. Вернитесь домой или приземлитесь", + "tr": "Gimbal hatası. Eve geri dönün veya iniş yapın", + "zh": "云台异常,返航或降落" + }, + "fpv_tip_0x16100057": { + "de": "Gimbal-Fehler. Start nicht möglich. DJI Support kontaktieren", + "en": "Gimbal error. Unable to take off. Contact DJI Support", + "es": "Error del estabilizador. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de nacelle. Impossible de décoller. Contactez l\\'assistance technique DJI", + "ja": "ジンバルエラー。離陸できません。DJIサポートにお問い合わせください", + "ko": "짐벌 오류. 이륙 불가. DJI 고객지원으로 문의", + "ru": "Ошибка стабилизатора. Невозможно выполнить взлет. Обратитесь в службу поддержки DJI", + "tr": "Gimbal hatası. Kalkış yapamıyor. DJI Destek ile iletişime geçin", + "zh": "无法起飞:云台异常,请联系大疆售后服务" + }, + "fpv_tip_0x16100057_in_the_sky": { + "de": "Gimbal-Fehler. Zum Startpunkt zurückkehren oder landen", + "en": "Gimbal error. Return to home or land", + "es": "Error del estabilizador. Regresa al punto de origen o aterriza", + "fr": "Erreur nacelle. Revenez au point de départ ou atterrissez", + "ja": "ジンバルエラー。帰還するか着陸してください", + "ko": "짐벌 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка стабилизатора. Вернитесь домой или приземлитесь", + "tr": "Gimbal hatası. Eve geri dönün veya iniş yapın", + "zh": "云台异常,返航或降落" + }, + "fpv_tip_0x16100058": { + "de": "Gimbal-Firmware wird aktualisiert. Start nicht möglich ...", + "en": "Gimbal firmware updating. Unable to take off...", + "es": "Actualizando el firmware del estabilizador. No se puede despegar...", + "fr": "Mise à jour du firmware de la nacelle en cours. Impossible de décoller .", + "ja": "ジンバル ファームウェア更新中。離陸できません...", + "ko": "짐벌 펌웨어 업데이트 중. 이륙 불가", + "ru": "ПО стабилизатора обновляется. Взлет невозможен", + "tr": "Gimbal yazılımı güncelleniyor. Kalkış yapamıyor…", + "zh": "无法起飞:云台升级中,请稍后" + }, + "fpv_tip_0x16100058_in_the_sky": { + "de": "Aktualisierung der Gimbal-Firmware wird durchgeführt", + "en": "Gimbal firmware update in progress", + "es": "Actualización del firmware del estabilizador en curso", + "fr": "Mise à jour du firmware de la nacelle en cours", + "ja": "ジンバル ファームウェアを更新中", + "ko": "짐벌 펌웨어 업데이트 진행 중", + "ru": "Идет обновление ПО стабилизатора", + "tr": "Gimbal yazılım güncellemesi devam ediyor", + "zh": "云台升级中,请稍后" + }, + "fpv_tip_0x1610005D": { + "de": "Kalibrierung der IMU erfolgreich. Start nicht möglich. Fluggerät muss neu gestartet werden", + "en": "IMU calibration successful. Unable to take off. Restarting aircraft required", + "es": "IMU calibrada. No se puede despegar. Es necesario reiniciar la aeronave", + "fr": "Étalonnage de l\\'IMU réussi. Impossible de décoller. Redémarrage de l\\'appareil requis", + "ja": "IMUキャリブレーションが成功しました。離陸できません。機体の再起動が必要です", + "ko": "IMU 캘리브레이션 성공. 이륙 불가. 기체 재시작 필요", + "ru": "IMU откалиброван. Взлет невозможен. Перезагрузите дрон", + "tr": "IMU kalibrasyonu başarılı. Kalkış yapamıyor. Aracın yeniden başlatılması gerekli", + "zh": "无法起飞:IMU 校准成功,需重启飞行器" + }, + "fpv_tip_0x1610005D_in_the_sky": { + "de": "Kalibrierungsfehler: IMU. Zum Startpunkt zurückkehren oder landen", + "en": "IMU calibration error. Return to home or land", + "es": "Error de calibración de la IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur d\\'étalonnage IMU. Revenez au point de départ ou atterrissez", + "ja": "IMUキャリブレーションエラー。帰還するか、着陸してください", + "ko": "IMU 캘리브레이션 오류. RTH 진행 또는 착륙 필요", + "ru": "Ошибка калибровки IMU. Вернитесь домой или приземлитесь", + "tr": "IMU kalibrasyon hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU 校准异常,请返航或降落" + }, + "fpv_tip_0x1610005E": { + "de": "Fluggerät hat sich beim Start gedreht. Start fehlgeschlagen. Bitte Propeller überprüfen", + "en": "Aircraft rolled during takeoff. Unable to take off. Check whether propellers were installed correctly", + "es": "La aeronave se ha volcado durante el despegue. No se puede despegar. Comprueba si las hélices se han instalado correctamente", + "fr": "L\\'appareil s\\'est retourné pendant le décollage. Le décollage a échoué. Vérifiez si les hélices ont été installées correctement", + "ja": "離陸中に機体が横転。離陸できません。プロペラが正しく取り付けられているか確認してください", + "ko": "이륙 중 기체 전복. 이륙 실패. 프로펠러가 올바르게 설치되었는지 확인해야 함", + "ru": "Дрон наклонился при взлете. Не удалось взлететь. Проверьте, установлены ли пропеллеры корректно", + "tr": "Araç kalkışta yuvarlandı. Kalkış yapamıyor. Pervanelerin düzgün takılıp takılmadığını kontrol edin", + "zh": "无法起飞:起飞时侧翻,请检查桨叶安装是否正确" + }, + "fpv_tip_0x1610005E_in_the_sky": { + "de": "Fluggerät hat sich beim Start gedreht. Bitte Propeller überprüfen", + "en": "Aircraft rolled during takeoff. Check whether propellers are installed correctly", + "es": "La aeronave se ha volcado durante el despegue. Comprueba si las hélices se han instalado correctamente", + "fr": "L\\'appareil a fait un tonneau pendant le décollage. Vérifiez si les hélices ont été installées correctement", + "ja": "離陸中に機体が横転。プロペラが正しく取り付けられているか確認してください", + "ko": "이륙 중 기체 전복. 프로펠러가 올바르게 설치되었는지 확인해야 함", + "ru": "Дрон наклонился при взлете. Проверьте, установлены ли пропеллеры корректно", + "tr": "Araç kalkışta yuvarlandı. Pervanelerin düzgün takılıp takılmadığını kontrol edin", + "zh": "起飞时侧翻,请检查桨叶安装是否正确" + }, + "fpv_tip_0x1610005F": { + "de": "Motor blockiert. Start nicht möglich. Fluggerät ausschalten und Motor prüfen", + "en": "Motor stalled. Unable to take off. Power off aircraft and check whether motor can rotate freely", + "es": "Motor atascado. No se puede despegar. Apaga la aeronave y comprueba si el motor puede rotar con libertad", + "fr": "Le moteur a calé. Impossible de décoller. Éteignez l\\'appareil et vérifiez si le moteur peut tourner librement", + "ja": "モーター停止。離陸できません。機体の電源を切り、モーターが制限なく回転するか確認してください", + "ko": "모터 정지됨. 이륙 불가. 기체의 전원을 끄고 모터가 자유롭게 회전할 수 있는지 확인해야 함", + "ru": "Мотор заклинило. Взлет невозможен. Выключите дрон и убедитесь, что мотор поворачивается свободно", + "tr": "Motor durdu. Kalkış yapamıyor. Aracı kapatın ve motorun rahatça dönüp dönmediğini kontrol edin", + "zh": "无法起飞:电机堵转,关机后检查电机能否自由旋转" + }, + "fpv_tip_0x1610005F_in_the_sky": { + "de": "Motor blockiert. Sofort landen. Schalten Sie das Fluggerät aus und prüfen Sie, ob sich der Motor frei drehen kann .", + "en": "Motor stalled. Land promptly. Power off airfcraft and check whether motor can rotate freely", + "es": "Motor atascado. Aterriza rápidamente. Apaga la aeronave y comprueba si el motor puede rotar con libertad", + "fr": "Le moteur a calé. Atterrissez immédiatement. Éteignez l\\'appareil et vérifiez si le moteur peut tourner librement", + "ja": "モーター停止。直ちに着陸してください。機体の電源を切り、モーターが制限なく回転するか確認してください", + "ko": "모터 정지됨. 즉시 착륙 필요. 기체의 전원을 끄고 모터가 자유롭게 회전할 수 있는지 확인해야 함", + "ru": "Мотор заклинило. Приземлитесь немедленно. Выключите дрон и убедитесь, что мотор поворачивается свободно", + "tr": "Motor durdu. Hemen iniş yapın. Aracı kapatın ve motorun rahatça dönüp dönmediğini kontrol edin", + "zh": "电机堵转,请降落,在关机后检查电机能否自由旋转" + }, + "fpv_tip_0x16100060": { + "de": "Motordrehzahlfehler. Start nicht möglich. Fluggerät neu starten", + "en": "Motor rotation speed error. Unable to take off. Restart aircraft", + "es": "Error de velocidad de rotación del motor. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur de vitesse de rotation du moteur. Impossible de décoller. Redémarrez l\\'appareil", + "ja": "モーター回転速度エラー。離陸できません。機体を再起動してください", + "ko": "모터 회전 속도 오류. 이륙 불가. 기체 재시작 필요", + "ru": "Ошибка скорости вращения мотора. Взлет невозможен. Перезагрузите дрон", + "tr": "Motor dönüş hızı hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:电机转速异常,请重启飞行器" + }, + "fpv_tip_0x16100060_in_the_sky": { + "de": "Motordrehzahlfehler. Fluggerät landen und neu starten", + "en": "Motor rotation speed error. Land and restart aircraft", + "es": "Error de velocidad de rotación del motor. Aterriza y reinicia la aeronave", + "fr": "Erreur de vitesse de rotation du moteur. Atterrissez et redémarrez l\\'appareil", + "ja": "モーター回転速度エラー。着陸して機体を再起動してください", + "ko": "모터 회전 속도 오류. 착륙하고 기체 재시작 필요", + "ru": "Ошибка скорости вращения мотора. Приземлитесь и перезагрузите дрон", + "tr": "Motor dönüş hızı hatası. Aracı indirin ve yeniden başlatın", + "zh": "电机转速异常,请停桨后重启飞行器" + }, + "fpv_tip_0x16100061": { + "de": "Motor im Leerlauf. Start nicht möglich. Bitte Propeller überprüfen", + "en": "Motor idle. Unable to take off. Check whether propellers are detached or installed incorrectly", + "es": "Motor inactivo. No se puede despegar. Comprueba si las hélices se han desconectado o instalado de forma incorrecta", + "fr": "Moteur inactif. Impossible de décoller. Vérifiez si les hélices sont détachées ou mal installées", + "ja": "モーターアイドル状態。離陸できません。プロペラが外れたり、間違って取り付けられていないか確認してください", + "ko": "모터 공회전. 이륙 불가. 프로펠러가 분리되었거나 제대로 설치되지 않았는지 확인해야 함", + "ru": "Мотор неподвижен. Взлет невозможен. Проверьте установку пропеллеров", + "tr": "Motor boşta. Kalkış yapamıyor. Pervanelerin doğru çıkarıldığından veya takıldığından emin olun", + "zh": "无法起飞:电机空转,无法起飞,请检查桨叶是否脱落或未正确安装桨叶" + }, + "fpv_tip_0x16100061_in_the_sky": { + "de": "Motor im Leerlauf. Kann nicht abheben. Bitte Propeller überprüfen. .", + "en": "Motor idle. Unable to take off. Check whether propellers are detached or installed incorrectly", + "es": "Motor inactivo. No se puede despegar. Comprueba si las hélices se han desconectado o instalado de forma incorrecta", + "fr": "Moteur inactif. Impossible de décoller. Vérifiez si les hélices sont détachées ou mal installées", + "ja": "モーターアイドル状態。離陸できません。プロペラが外れたり、間違って取り付けられていないか確認してください", + "ko": "모터 공회전. 이륙 불가. 프로펠러가 분리되었거나 제대로 설치되지 않았는지 확인해야 함", + "ru": "Мотор неподвижен. Взлет невозможен. Проверьте установку пропеллеров", + "tr": "Motor boşta. Kalkış yapamıyor. Pervanelerin doğru çıkarıldığından veya takıldığından emin olun", + "zh": "电机空转,无法起飞,请检查桨叶是否脱落或未正确安装桨叶" + }, + "fpv_tip_0x16100062": { + "de": "Motoren können nicht eingeschaltet werden. Start nicht möglich. Fluggerätstatus prüfen und neu starten", + "en": "Unable to turn on motor. Unable to take off. Check aircraft status and restart", + "es": "No se puede encender el motor. No se puede despegar. Comprueba el estado de la aeronave y reiníciala", + "fr": "Impossible de démarrer les moteurs. Impossible de décoller. Vérifiez l\\'état de l\\'appareil et redémarrez", + "ja": "モーターをオンにできません。離陸できません。機体の状態を確認して再起動してください", + "ko": "모터를 켤 수 없음. 이륙 불가. 기체 상태를 확인하고 다시 시작해야 함", + "ru": "Невозможно включить мотор и взлететь. Проверьте статус дрона и перезагрузите его", + "tr": "Motoru çalıştıramıyor. Kalkış yapamıyor. Araç durumunu kontrol edin ve yeniden başlatın", + "zh": "无法起飞:电机无法启动,请检查飞行器状态并重启飞行器" + }, + "fpv_tip_0x16100062_in_the_sky": { + "de": "Motor(en) können nicht eingeschaltet werden. Fluggerätstatus prüfen und neu starten", + "en": "Unable to turn on aircraft motor(s). Check aircraft status and restart", + "es": "No se puede encender uno o varios motores de la aeronave. Comprueba el estado de la aeronave y reiníciala", + "fr": "Impossible de démarrer les moteurs. Vérifiez l\\'état de l\\'appareil et redémarrez", + "ja": "機体のモーターをオンにできません。機体の状態を確認して再起動してください", + "ko": "기체 모터를 켤 수 없음. 기체 상태를 확인하고 다시 시작해야 함", + "ru": "Невозможно включить мотор (-ы) дрона. Проверьте статус и перезагрузите его", + "tr": "Aracın motor(lar)ını açamıyor. Araç durumunu kontrol edin ve yeniden başlatın", + "zh": "电机无法启动,请检查飞行器状态并重启飞行器" + }, + "fpv_tip_0x16100063": { + "de": "Automatischer Start fehlgeschlagen", + "en": "Auto Takeoff failed. Unable to take off", + "es": "Error de despegue automático. No se puede despegar", + "fr": "Décollage automatique impossible", + "ja": "自動離陸に失敗しました。離陸できません", + "ko": "자동 이륙 실패", + "ru": "Сбой автовзлета", + "tr": "Otomatik Kalkış başarısız. Kalkış yapamıyor", + "zh": "无法起飞:自动起飞失败" + }, + "fpv_tip_0x16100063_in_the_sky": { + "de": "Automatischer Start fehlgeschlagen", + "en": "Auto Takeoff failed", + "es": "Error de despegue automático", + "fr": "Décollage automatique impossible", + "ja": "自動離陸に失敗しました", + "ko": "자동 이륙 실패", + "ru": "Сбой автовзлета", + "tr": "Otomatik Kalkış başarısız", + "zh": "自动起飞失败" + }, + "fpv_tip_0x16100064": { + "de": "Fluggerät hat sich überschlagen . Start nicht möglich. Fluggerät auf ebener Fläche neu starten", + "en": "Aircraft rolled over. Unable to take off. Restart aircraft and ensure it is level before taking off", + "es": "La aeronave se ha volcado. No se puede despegar. Reinicia la aeronave y asegúrate de que esté nivelada antes de despegar", + "fr": "L\\'appareil s\\'est retourné . Impossible de décoller. Redémarrez-le et assurez-vous qu\\'il est sur une surface plane avant de décoller", + "ja": "機体が裏返っています。離陸できません。機体を再起動し、機体が水平なことを確認してから離陸してください", + "ko": "기체 전복됨 . 이륙 불가. 기체 재시작 후 평평한 곳에 놓고 이륙해야 함", + "ru": "Дрон наклонился . Взлет невозможен. Перезагрузите дрон и убедитесь, что он расположен ровно перед взлетом", + "tr": "Araç yuvarlandı. Kalkış yapamıyor. Aracı tekrar çalıştırın ve kalkıştan önce düz olduğundan emin olun", + "zh": "无法起飞:飞行器姿态翻滚,请重启飞行器水平放置后起飞" + }, + "fpv_tip_0x16100064_in_the_sky": { + "de": "Fluggerät hat sich gedreht . Zum Startpunkt zurückkehren oder landen.", + "en": "Aircraft rolled over. Return to home or land", + "es": "La aeronave se ha volcado. Regresa al punto de origen o aterriza", + "fr": "L\\'appareil s\\'est retourné . Revenez au point de départ ou atterrissez", + "ja": "機体が裏返っています。帰還するか、着陸してください", + "ko": "기체 전복됨 . RTH 진행 또는 착륙 필요", + "ru": "Дрон перевернулся . Вернитесь домой или приземлитесь", + "tr": "Araç yuvarlandı. Eve geri dönün veya iniş yapın", + "zh": "飞行器姿态翻滚, 请返航或降落" + }, + "fpv_tip_0x16100065": { + "ar": "", + "de": "Fehler: Firmware-Version des Akkus. Start nicht möglich. Akku austauschen oder auf neueste Firmware-Version aktualisieren", + "en": "Battery firmware version error. Unable to take off. Replace battery or update battery firmware to latest version", + "es": "Error de versión del firmware de la batería. No se puede despegar. Reemplaza la batería o actualiza el firmware de la batería a la versión más reciente", + "fr": "Erreur de version du firmware de la batterie. Impossible de décoller. Remplacez la batterie ou mettez à jour le firmware de la batterie vers la version la plus récente", + "id": "", + "it": "", + "ja": "バッテリーファームウェア バージョンエラー。離陸できません。バッテリーを交換するか、バッテリーファームウェアを最新バージョンに更新してください", + "ko": "배터리 펌웨어 버전 오류. 이륙 불가. 배터리를 교체하거나 최신 펌웨어 버전으로 업데이트 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка версии ПО батареи. Взлет невозможен. Замените батарею или установите последнюю версию ПО", + "th": "", + "tr": "Pil yazılımı sürümü hatası. Kalkış yapamıyor. Pili değiştirin ya da pil yazılımını en güncel sürüme güncelleyin", + "ug": "", + "vi": "", + "zh": "无法起飞:电池固件版本不一致,请更换电池或将电池升级到最新版本", + "zh-Hant": "" + }, + "fpv_tip_0x16100065_in_the_sky": { + "ar": "", + "de": "Fehler bei Firmware-Version des Akkus. Akku austauschen oder auf neueste Firmware-Version aktualisieren", + "en": "Battery firmware version error. Replace battery or update to the latest firmware version", + "es": "Error de versión del firmware de la batería. Reemplaza la batería o actualiza a la versión del firmware más reciente", + "fr": "Erreur de version du firmware de la batterie. Remplacez la batterie ou mettez à jour vers la version la plus récente", + "id": "", + "it": "", + "ja": "バッテリーファームウェア バージョンエラー。バッテリーを交換するか最新のファームウェアバージョンに更新してください", + "ko": "배터리 펌웨어 버전 오류. 배터리를 교체하거나 최신 펌웨어 버전으로 업데이트 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка версии ПО батареи. Замените ее или установите последнюю версию ПО", + "th": "", + "tr": "Pil yazılımı sürümü hatası. Pili değiştirin ya da pil yazılımını en güncel sürüme güncelleyin", + "ug": "", + "vi": "", + "zh": "电池固件版本不一致,请更换电池或将电池升级到最新版本", + "zh-Hant": "" + }, + "fpv_tip_0x16100066": { + "de": "RTK-Signal schwach. Start nicht möglich. Zum Starten in einen offenen Bereich gehen oder RTK ausschalten", + "en": "RTK signal weak. Unable to take off. Move to an open area for takeoff or turn off RTK", + "es": "Señal RTK débil. No se puede despegar. Desplázate a un espacio abierto para despegar o desactiva RTK", + "fr": "Signal RTK faible. Impossible de décoller. Déplacez-vous vers une zone dégagée pour décoller ou désactivez le RTK", + "ja": "RTK信号 弱。離陸できません。開けたエリアに移動して離陸するか、RTKをオフにしてください", + "ko": "RTK 신호 약함. 이륙 불가. 개방된 장소로 이동해 이륙하거나 RTK를 꺼야 함", + "ru": "Слабый сигнал RTK. Взлет невозможен. Переместитесь в открытое место для взлета или выкл. RTK", + "tr": "RTK sinyali zayıf. Kalkış yapamıyor. Kalkış için açık bir alana gidin ya da RTK’yı kapatın", + "zh": "无法起飞:RTK 信号差,请至空旷地起飞,或关闭RTK功能" + }, + "fpv_tip_0x16100066_in_the_sky": { + "de": "RTK-Signal schwach. Zum Starten in einen offenen Bereich gehen oder RTK ausschalten", + "en": "RTK signal weak. Move to an open area for takeoff or turn off RTK", + "es": "Señal RTK débil. Desplázate a un espacio abierto para despegar o desactiva RTK", + "fr": "Signal RTK faible. Déplacez-vous vers une zone dégagée pour décoller ou désactivez le RTK", + "ja": "RTK信号 弱。開けたエリアに移動して離陸するか、RTKをオフにしてください", + "ko": "RTK 신호 약함. 개방된 장소로 이동해 이륙하거나 RTK를 꺼야 함", + "ru": "Слабый сигнал RTK. Переместитесь в открытое место для взлета или выкл. RTK", + "tr": "RTK sinyali zayıf. Kalkış için açık bir alana gidin ya da RTK’yı kapatın", + "zh": "RTK 信号差,请至空旷地起飞,或关闭RTK功能" + }, + "fpv_tip_0x16100067": { + "de": "Fehler: Kompass . Start nicht möglich. Kompass neu kalibrieren", + "en": "Compass interference. Unable to take off. Calibrate compass", + "es": "Interferencias en la brújula. No se puede despegar. Calibra la brújula", + "fr": "Interférence du compas . Impossible de décoller. Étalonnez le compas", + "ja": "コンパスの干渉。離陸できません。コンパスをキャリブレーション", + "ko": "콤파스 간섭 . 이륙 불가. 콤파스 캘리브레이션 필요", + "ru": "Помехи компаса . Взлет невозможен. Откалибруйте его", + "tr": "Pusula müdahalesi. Kalkış yapamıyor. Pusulayı kalibre edin", + "zh": "无法起飞:指南针受到干扰,请校准指南针" + }, + "fpv_tip_0x16100067_in_the_sky": { + "de": "Kompassstörung. Von der Störquelle wegbewegen", + "en": "Compass interference. Move away from interference source", + "es": "Interferencias en la brújula. Aléjese de la fuente de interferencia", + "fr": "Interférences avec le compas. Éloignez-vous de la source d'interférence", + "ja": "コンパスの干渉。干渉源から遠ざけてください", + "ko": "콤파스 간섭. 간섭원으로부터 멀리 이동하세요", + "ru": "Помехи в работе компаса. Переместите дрон подальше от источника помех", + "tr": "Pusula paraziti. Parazit kaynağından uzaklaşın", + "zh": "指南针受到干扰,请远离干扰源飞行" + }, + "fpv_tip_0x16100068": { + "de": "Kurzschluss am ESC. Start nicht möglich. Fluggerät neu starten", + "en": "ESC short-circuited. Unable to take off. Restart aircraft", + "es": "Cortocircuito de ESC. No se puede despegar. Reinicia la aeronave", + "fr": "ESC court-circuité. Impossible de décoller. Redémarrez l\\'appareil", + "ja": "ESC短絡。離陸できません。機体を再起動してください", + "ko": "ESC 합선. 이륙 불가. 기체 재시작 필요", + "ru": "Короткое замыкание ESC. Взлет невозможен. Перезагрузите дрон", + "tr": "ESC kısa devresi. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:电调短路,请重启飞行器" + }, + "fpv_tip_0x16100068_in_the_sky": { + "de": "Kurzschluss am ESC. Fluggerät neu starten .", + "en": "ESC short-circuited. Restart aircraft", + "es": "Cortocircuito de ESC. Reinicia la aeronave", + "fr": "Court-circuit ESC. Redémarrez l\\'appareil", + "ja": "ESC短絡。機体を再起動してください", + "ko": "ESC 합선. 기체를 다시 시작해야 함", + "ru": "Короткое замыкание ESC. Перезагрузите дрон", + "tr": "ESC kısa devresi. Aracı yeniden başlatın", + "zh": "电调短路,请重启飞行器" + }, + "fpv_tip_0x16100069": { + "de": "Fehler: Gimbal-Selbsttest. Start nicht möglich. Fluggerät neu starten", + "en": "ESC auto-check error. Unable to take off. Restart aircraft", + "es": "Error de comprobación automática de ESC. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur vérif. auto de l\\'ESC. Impossible de décoller. Redémarrez l\\'appareil", + "ja": "ESC自動確認エラー。離陸できません。機体を再起動してください", + "ko": "ESC 자체 점검 오류. 이륙 불가. 기체 재시작 필요", + "ru": "Ошибка автопроверки ESC. Взлет невозможен. Перезагрузите дрон", + "tr": "ESC otomatik kontrol hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:电子调速器自检异常,请重启飞行器" + }, + "fpv_tip_0x16100069_in_the_sky": { + "de": "Fehler: ESC Selbsttest. Umgehend zum Startpunkt zurückkehren.", + "en": "ESC auto-check error. Return to home or land", + "es": "Error de comprobación automática de ESC. Regresa al punto de origen o aterriza", + "fr": "Erreur vérif. auto de l\\'ESC. Revenez au point de départ ou atterrissez", + "ja": "ESC自動確認エラー。帰還するか、着陸してください", + "ko": "ESC 자체 점검 오류. RTH 진행 또는 착륙 필요", + "ru": "Ошибка автопроверки ESC. Вернитесь домой или приземлитесь", + "tr": "ESC otomatik kontrol hatası. Eve geri dönün veya iniş yapın", + "zh": "电子调速器自检异常,请返航或降落" + }, + "fpv_tip_0x1610006A": { + "de": "Inkompatibler Akku. Akku austauschen", + "en": "Incompatible battery. Replace battery", + "es": "Batería incompatible. Reemplaza la batería.", + "fr": "Batterie non compatible. Remplacez la batterie", + "ja": "互換性のないバッテリー。バッテリーを交換してください", + "ko": "호환되지 않는 배터리. 배터리 교체 필요", + "ru": "Несовместимая АКБ. Замените АКБ", + "tr": "Uyumsuz pil. Pili değiştirin", + "zh": "电池不匹配,请更换电池" + }, + "fpv_tip_0x1610006B": { + "de": "Start nicht möglich. Firmware-Aktualisierung des Akkus erforderlich", + "en": "Unable to take off. Battery firmware update required", + "es": "No se puede despegar. Es necesario actualizar el firmware de la batería.", + "fr": "Impossible de décoller. Mise à jour du firmware de la batterie nécessaire", + "ja": "離陸できません。バッテリーのファームウェア更新が必要です", + "ko": "이륙 불가. 배터리 펌웨어 업데이트 필요", + "ru": "Не удается выполнить взлет. Требуется обновление прошивки АКБ", + "tr": "Kalkış yapılamıyor. Pil ürün yazılımı güncellemesi gerekiyor", + "zh": "无法起飞:电池固件需要升级" + }, + "fpv_tip_0x1610006B_in_the_sky": { + "de": "Fehler: Firmware des Akkus. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Battery firmware error. Return to home or land promptly", + "es": "Error de firmware de la batería. Regresa al punto de origen o aterriza rápidamente.", + "fr": "Erreur du firmware de la batterie. Revenez au point de départ ou atterrissez rapidement", + "ja": "バッテリーファームウェアエラー。直ちにホームに帰還するか着陸してください", + "ko": "배터리 펌웨어 오류. 즉시 홈으로 돌아가거나 착륙하세요.", + "ru": "Ошибка прошивки АКБ. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Pil ürün yazılımı hatası. Derhal başlangıç noktasına geri dönün veya iniş yapın", + "zh": "电池固件异常,请尽快返航或降落" + }, + "fpv_tip_0x1610006C": { + "de": "Start nicht möglich. Schwerwiegender Akkufehler", + "en": "Unable to take off. Severe battery error", + "es": "No se puede despegar. Error grave de la batería", + "fr": "Impossible de décoller. Erreur de batterie grave", + "ja": "離陸できません。重大なバッテリーエラー", + "ko": "이륙 불가. 심각한 배터리 오류", + "ru": "Не удается выполнить взлет. Серьезная ошибка аккумулятора", + "tr": "Kalkış yapılamıyor. Ciddi pil hatası", + "zh": "无法起飞:电池严重异常" + }, + "fpv_tip_0x1610006C_in_the_sky": { + "de": "Schwerwiegender Akkufehler. Automatische Landung …", + "en": "Severe battery error. Auto landing...", + "es": "Error grave de la batería. Realizando aterrizaje automático…", + "fr": "Erreur de batterie grave. Atterrissage auto en cours", + "ja": "重大なバッテリーエラー。自動着陸中...", + "ko": "심각한 배터리 오류. 자동 착륙 중…", + "ru": "Серьезная ошибка аккумулятора. Автоматическая посадка…", + "tr": "Ciddi pil hatası. Otomatik iniş...", + "zh": "电池严重异常:强制降落中" + }, + "fpv_tip_0x1610006D": { + "de": "Start nicht möglich. Leistung eingeschränkt. Akkuwarnmeldung auf Problemursache prüfen", + "en": "Unable to take off. Power restricted. Check battery warning for issue reason", + "es": "No se puede despegar. Potencia restringida. Compruebe la advertencia de la batería para conocer el motivo del problema", + "fr": "Impossible de décoller. Puissance limitée. Vérifiez l'avertissement de la batterie pour la raison du problème", + "ja": "離陸できません。電力が制限されています。バッテリー警告で問題の原因を確認してください", + "ko": "이륙 불가. 전원 제한 상태. 배터리 경고에서 문제의 원인을 확인하세요", + "ru": "Не удается выполнить взлет. Мощность ограничена. Проверьте предупреждение от АКБ, чтобы узнать причину проблемы", + "tr": "Kalkış yapılamıyor. Güç kısıtlı. Sorunun nedeni için pil uyarısını kontrol edin", + "zh": "无法起飞:已限制功率,原因请参考电池告警" + }, + "fpv_tip_0x1610006D_in_the_sky": { + "de": "Leistung und Fluglage eingeschränkt. Umgehend zum Startpunkt zurückkehren. Akkuwarnmeldung auf Problemursache prüfen", + "en": "Power and flight attitude restricted. Return to home promptly. Check battery warning for issue reason", + "es": "Potencia y altitud de vuelo restringidas. Regrese al punto de origen cuanto antes. Compruebe la advertencia de la batería para conocer el motivo del problema", + "fr": "Puissance et assiette de vol restreintes. Revenez au point de départ immédiatement. Vérifiez l'avertissement de la batterie pour la raison du problème", + "ja": "電力と飛行姿勢が制限されています。すぐに帰還してください。バッテリー警告で問題の原因を確認してください", + "ko": "전원 및 비행 고도 제한 상태. 즉시 리턴 투 홈을 실행하세요. 배터리 경고에서 문제의 원인을 확인하세요", + "ru": "Мощность и высота полета ограничены. Как можно скорее вернитесь на базу. Проверьте предупреждение от АКБ, чтобы узнать причину проблемы", + "tr": "Güç ve uçuş hareketi kısıtlı. Derhal başlangıç noktasına dönün. Sorunun nedeni için pil uyarısını kontrol edin", + "zh": "已限制功率和飞行姿态,请尽快返航,原因请参考电池告警" + }, + "fpv_tip_0x16100070": { + "en": "Not Applicable. This string has been deleted", + "zh": "还在用么?160没用这个了" + }, + "fpv_tip_0x16100070_in_the_sky": { + "en": "Not Applicable. This string has been deleted", + "zh": "还在用么?160没用这个了" + }, + "fpv_tip_0x16100071": { + "de": "GPS getrennt . Start nicht möglich. Fluggerät neu starten", + "en": "GPS error. Unable to take off. Restart aircraft", + "es": "Error de GPS. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur du GPS . Impossible de décoller. Redémarrez l\\'appareil", + "ja": "GPSエラー。離陸できません。機体を再起動してください", + "ko": "GPS 오류 . 이륙 불가. 기체 재시작 필요", + "ru": "Ошибка GPS . Взлет невозможен. Перезагрузите дрон", + "tr": "GPS hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:GPS异常,请重启飞行器" + }, + "fpv_tip_0x16100071_in_the_sky": { + "de": "Fehler: GPS . Zum Startpunkt zurückkehren oder landen.", + "en": "GPS error. Return to home or land", + "es": "Error de GPS. Regresa al punto de origen o aterriza", + "fr": "Erreur GPS . Revenez au point de départ ou atterrissez", + "ja": "GPSエラー。帰還するか、着陸してください", + "ko": "GPS 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка GPS . Вернитесь домой или приземлитесь", + "tr": "GPS hatası. Eve geri dönün veya iniş yapın", + "zh": "GPS异常,请降落或返航" + }, + "fpv_tip_0x16100072": { + "de": "Gimbal wird kalibriert . Start nicht möglich", + "en": "Gimbal calibrating. Unable to take off", + "es": "Calibrando el estabilizador. No se puede despegar", + "fr": "Étalonnage de la nacelle . Impossible de décoller", + "ja": "ジンバルキャリブレーション中。離陸できません", + "ko": "짐벌 캘리브레이션 중 . 이륙 불가", + "ru": "Идет калибровка стабилизатора . Взлет невозможен", + "tr": "Gimbal kalibre ediliyor. Kalkış yapamıyor", + "zh": "无法起飞:云台校准中,请稍后起飞" + }, + "fpv_tip_0x16100072_in_the_sky": { + "de": "Kalibrierungsfehler: Gimbal. Zum Startpunkt zurückkehren oder landen", + "en": "Gimbal calibration error. Return to home or land", + "es": "Error de calibración del estabilizador. Regresa al punto de origen o aterriza", + "fr": "Erreur d\\'étalonnage de la nacelle. Revenez au point de départ ou atterrissez", + "ja": "ジンバル キャリブレーション エラー。帰還するか、着陸してください", + "ko": "짐벌 캘리브레이션 오류. RTH 진행 또는 착륙 필요", + "ru": "Ошибка калибровки стабилизатора. Вернитесь домой или приземлитесь", + "tr": "Gimbal kalibrasyon hatası. Eve geri dönün veya iniş yapın", + "zh": "云台校准异常,请返航或降落" + }, + "fpv_tip_0x16100073": { + "de": "Startbedingungen nicht erfüllt. Start nicht möglich. Firmware veraltete oder Flugroute wird in Fluggerät hochgeladen", + "en": "Takeoff conditions not met. Unable to take off. Firmware out-of-date or flight route uploading to aircraft", + "es": "No se cumplen las condiciones de despegue. No se puede despegar. Firmware obsoleto o cargando ruta de vuelo a la aeronave", + "fr": "Conditions de décollage non satisfaites. Impossible de décoller. Le firmware de l\\'appareil est obsolète ou la trajectoire de vol est en cours de transfert vers l\\'appareil", + "ja": "離陸条件が満たされていません。離陸できません。ファームウェアが古いか、飛行ルートを機体にアップロード中です", + "ko": "이륙 조건 충족 안 됨. 이륙 불가. 오래된 펌웨어거나 비행 경로가 기체에 업로드되는 중", + "ru": "Условия взлета не соблюдены. Взлет невозможен. Устаревшая версия ПО или маршрут полета загружается в дрон", + "tr": "Kalkış koşulları uygun değil. Kalkış yapamıyor. Yazılım güncel değil ya da uçuş rotası araca yükleniyor", + "zh": "无法起飞:当前状态不支持起飞。固件版本过低或正在上传航线至飞行器" + }, + "fpv_tip_0x16100073_in_the_sky": { + "de": "Veraltete Firmware oder Flugroute wird gerade zum Fluggerät übertragen. Zum Startpunkt zurückkehren oder landen", + "en": "Firmware out of date or flight route uploading to aircraft. Return to home or land", + "es": "Firmware obsoleto o cargando ruta de vuelo a la aeronave. Regresa al punto de origen o aterriza", + "fr": "Firmware obsolète ou trajectoire en cours de transfert vers l\\'appareil. Revenez au point de départ ou atterrissez", + "ja": "ファームウェアが古いか、飛行ルートを機体にアップロード中です。帰還するか、着陸してください", + "ko": "오래된 펌웨어거나 기체에 비행 경로가 업로드되는 중. RTH 진행 또는 착륙 필요", + "ru": "Старая версия ПО или маршрута полета загружается в дрон. Вернитесь домой или приземлитесь", + "tr": "Yazılım güncel değil ya da uçuş rotası araca yükleniyor. Eve geri dönün veya iniş yapın", + "zh": "固件版本过低或正在上传航线至飞行器,请返航或降落" + }, + "fpv_tip_0x16100074": { + "de": "Fehler: Start nicht möglich. Fluggerät neu starten", + "en": "Takeoff altitude error. Unable to take off. Restart aircraft", + "es": "Error de altitud en el despegue. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur d\\'altitude au décollage. Impossible de décoller. Redémarrez l\\'appareil", + "ja": "離陸高度エラー。離陸できません。機体を再起動してください", + "ko": "이륙 고도 오류. 이륙 불가. 기체 재시작 필요", + "ru": "Ошибка высоты взлета. Взлет невозможен. Перезагрузите дрон", + "tr": "Kalkış irtifa hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:飞行器起飞高度异常,请重启飞行器" + }, + "fpv_tip_0x16100074_in_the_sky": { + "de": "Startfehler. Flugzeug neu starten", + "en": "Takeoff altitude error. Restart aircraft", + "es": "Error de altitud en el despegue. Reinicia la aeronave", + "fr": "Erreur d\\'altitude de décollage. Redémarrez l\\'appareil", + "ja": "離陸高度エラー。機体を再起動してください", + "ko": "이륙 고도 오류. 기체를 다시 시작해야 함", + "ru": "Ошибка высоты взлета. Перезагрузите дрон", + "tr": "Kalkış irtifa hatası. Aracı yeniden başlatın", + "zh": "飞行器起飞高度异常,请重启飞行器" + }, + "fpv_tip_0x16100075": { + "de": "ESC-Firmware-Versionen stimmen nicht überein. Start nicht möglich. Auf die neuesten Firmware-Versionen aktualisieren", + "en": "ESC firmware versions do not match. Unable to take off. Update to latest firmware version", + "es": "Las versiones del firmware de ESC no coinciden. No se puede despegar. Actualiza a la versión del firmware más reciente", + "fr": "Les versions des firmwares des ESC ne correspondent pas. Impossible de décoller. Mettez-les à jour vers les versions les plus récentes", + "ja": "ESCファームウェア バージョン不一致。離陸できません。最新のファームウェアバージョンに更新してください", + "ko": "ESC 펌웨어 버전 불일치. 이륙 불가. 최신 펌웨어 버전으로 업데이트 필요", + "ru": "Версии ПО ESC не совпадают. Взлет невозможен. Установите последнюю версию", + "tr": "ESC yazılım sürümleri eşleşmiyor. Kalkış yapamıyor. En güncel yazılım sürümüne güncelleyin", + "zh": "无法起飞:电调版本不一致,请更新飞行器固件" + }, + "fpv_tip_0x16100075_in_the_sky": { + "de": "ESC-Firmware-Versionen stimmen nicht überein. Auf die neuesten Firmware-Versionen aktualisieren", + "en": "ESC firmware versions do not match. Update to latest firmware versions", + "es": "Las versiones del firmware de ESC no coinciden. Actualiza a las versiones del firmware más recientes", + "fr": "Les versions des firmwares des ESC ne correspondent pas. Mettez à jour vers les versions de firmwares les plus récentes", + "ja": "ESCファームウェア バージョン不一致。最新のファームウェアバージョンに更新してください", + "ko": "ESC 펌웨어 버전 불일치. 최신 펌웨어 버전으로 업데이트해야 함", + "ru": "Версии ПО ESC не совпадают. Установите последние версии", + "tr": "ESC yazılım sürümleri eşleşmiyor. En güncel yazılım sürümlerine güncelleyin", + "zh": "电调版本不一致,请更新飞行器固件" + }, + "fpv_tip_0x16100076": { + "de": "IMU-Fehler . Start nicht möglich. An DJI-Support wenden", + "en": "IMU error. Unable to take off. Contact DJI Support", + "es": "Error de IMU. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur IMU. Impossible de décoller. Contacter le service client DJI", + "ja": "IMU エラー。離陸できません。DJI サポートまでお問い合わせください", + "ko": "IMU 오류 . 이륙 불가. DJI 고객지원으로 문의해주세요", + "ru": "Ошибка IMU . Взлет невозможен. Обратитесь в службу поддержки DJI", + "tr": "IMU hatası. Kalkış yapamıyor. DJI Destek ile iletişime geçin", + "zh": "无法起飞:IMU异常,请联系大疆售后服务" + }, + "fpv_tip_0x16100076_in_the_sky": { + "de": "Fehler: IMU . Zum Startpunk zurückkehren oder landen.", + "en": "IMU error. Return to home or land", + "es": "Error de IMU. Regresa al punto de origen o aterriza", + "fr": "Erreur IMU . Revenez au point de départ ou atterrissez", + "ja": "IMUエラー。帰還するか、着陸してください", + "ko": "IMU 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка IMU . Вернитесь домой или приземлитесь", + "tr": "IMU hatası. Eve geri dönün veya iniş yapın", + "zh": "IMU异常,请返航或降落" + }, + "fpv_tip_0x16100078": { + "de": "Kompassfehler. Start nicht möglich. An DJI-Support wenden", + "en": "Compass error. Unable to take off. Contact DJI Support", + "es": "Error de brújula. No se puede despegar. Ponte en contacto con la asistencia técnica de DJI", + "fr": "Erreur de compas. Impossible de décoller. Contactez l\\'assistance technique DJI", + "ja": "コンパスエラー。離陸できません。DJIサポートまでお問い合わせください", + "ko": "콤파스 오류. 이륙 불가. DJI 고객지원으로 문의해주세요", + "ru": "Ошибка компаса. Взлет невозможен. Обратитесь в службу поддержки DJI", + "tr": "Pusula hatası. Kalkış yapamıyor. DJI Destek ile iletişime geçin", + "zh": "无法起飞:指南针异常,请联系大疆售后服务" + }, + "fpv_tip_0x16100078_in_the_sky": { + "de": "Kompassfehler. Zum Startpunkt zurückkehren oder landen", + "en": "Compass error. Return to home or land", + "es": "Error de brújula. Regresa al punto de origen o aterriza", + "fr": "Erreur compas. Revenez au point de départ ou atterrissez", + "ja": "コンパスエラー。帰還するか、着陸してください", + "ko": "콤파스 오류. RTH 진행 또는 착륙 필요", + "ru": "Ошибка компаса. Вернитесь домой или приземлитесь", + "tr": "Pusula hatası. Eve geri dönün veya iniş yapın", + "zh": "指南针异常,请返航或降落" + }, + "fpv_tip_0x1610007A": { + "de": "ESC-Piepton. Start nicht möglich. ESC-Piepton vor Start deaktivieren", + "en": "ESC beeping. Unable to take off. Turn off ESC beeping before takeoff", + "es": "ESC pitando. No se puede despegar. Apaga el pitido ESC antes del despegue", + "fr": "Alerte sonore de l'ESC. Impossible de décoller. Désactivez l'alerte sonore de l'ESC avant le décollage", + "ja": "ESCビープ音が鳴動しています。離陸できません。離陸前にESCビープ音をオフにしてください", + "ko": "ESC 신호음 작동 중. 이륙 불가. 이륙 전 ESC 신호음을 끄세요.", + "ru": "ESC издает звуковой сигнал. Не удается выполнить взлет. Отключите звуковой сигнал ESC перед взлетом", + "tr": "ESC bip sesi çıkarıyor. Kalkış yapılamıyor. Kalkıştan önce ESC bip sesini kapatın", + "zh": "无法起飞:电调鸣叫中,关闭后可正常飞行" + }, + "fpv_tip_0x1610007A_in_the_sky": { + "de": "ESC piept. Zum Startpunkt zurückkehren oder landen", + "en": "ESC beeping. Return to home or land", + "es": "ESC pitando. Regresa al punto de origen o aterriza", + "fr": "Alarme sonore de l\\'ESC. Revenez au point de départ ou atterrissez", + "ja": "ESCビープ音鳴動中。帰還するか、着陸してください", + "ko": "ESC 신호음 작동 중. RTH 진행 또는 착륙 필요", + "ru": "ESC сигналит. Вернитесь домой или приземлитесь", + "tr": "ESC uyarı sesi. Eve geri dönün veya iniş yapın", + "zh": "电调异常鸣叫中,请返航或降落" + }, + "fpv_tip_0x1610007B": { + "de": "ESC überhitzt. Start nicht möglich. Fluggerät ausschalten und warten, bis sich die Temperatur wieder normalisiert hat", + "en": "ESC overheated. Unable to take off. Power off aircraft and wait for temperature to return to normal", + "es": "ESC sobrecalentado. No se puede despegar. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad", + "fr": "Surchauffe de l\\'ESC. Impossible de décoller. Éteignez l\\'appareil et attendez que la température revienne à la normale", + "ja": "ESC高温。離陸できません。機体の電源を切り、通常の温度に戻るまで待ってください", + "ko": "ESC 과열됨. 이륙 불가. 기체 전원을 끄고 정상 온도로 내려갈 때까지 기다려야 함", + "ru": "Перегрев ESC. Взлет невозможен. Выключите дрон и дождитесь его остывания", + "tr": "ESC aşırı ısındı. Kalkış yapamıyor. Aracı kapatın ve sıcaklığın normale dönmesini bekleyin", + "zh": "无法起飞:电调温度过高,请关机至恢复正常温度" + }, + "fpv_tip_0x1610007B_in_the_sky": { + "de": "ESC überhitzt. Sofort landen. Fluggerät ausschalten und warten, bis sich die Temperatur wieder normalisiert hat .", + "en": "ESC overheated. Land promptly. Power off aircraft and wait for temperature to return to normal", + "es": "ESC sobrecalentado. Aterriza rápidamente. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad", + "fr": "Surchauffe ESC. Atterrissez immédiatement. Éteignez l\\'appareil et attendez que la température revienne à la normale", + "ja": "ESC高温。直ちに着陸してください。機体の電源を切り、通常の温度に戻るまで待ってください", + "ko": "ESC 과열됨. 즉시 착륙 필요. 기체 전원을 끄고 정상 온도로 내려갈 때까지 기다려야 함", + "ru": "Перегрев ESC. Приземлитесь немедленно. Выключите дрон и дождитесь остывания", + "tr": "ESC aşırı ısındı. Hemen iniş yapın. Aracı kapatın ve sıcaklığın normale dönmesini bekleyin", + "zh": "电调温度过高,请降落,并关机冷却至恢复正常温度" + }, + "fpv_tip_0x1610007C": { + "ar": "", + "de": "", + "en": "Battery installed incorrectly. Detach battery and reinstall it", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "电池安装不到位,请重新拔插电池", + "zh-Hant": "" + }, + "fpv_tip_0x1610007D": { + "de": "Aufprall erkannt. Start fehlgeschlagen und Fluggerät gelandet. Fluggerät neu starten", + "en": "Impact detected. Takeoff failed and aircraft landed. Unable to take off. Restart aircraft", + "es": "Impacto detectado. Error de despegue. La aeronave ha aterrizado. No se puede despegar. Reinicia la aeronave", + "fr": "Impact détecté. Le décollage a échoué et l\\'appareil a atterri. Redémarrez l\\'appareil", + "ja": "衝撃を検出。離陸に失敗し、機体が着陸しました。離陸できません。機体を再起動してください", + "ko": "충격 감지됨. 이륙 실패 후 기체 착륙함. 기체 재시작 필요", + "ru": "Обнаружен удар. Сбой взлета, дрон приземлился. Перезагрузите аппарат", + "tr": "Etki tespit edildi. Kalkış başarısız ve araç indi. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:检测到被撞击,飞行器已停止飞行,请重启飞行器" + }, + "fpv_tip_0x1610007D_in_the_sky": { + "de": "Aufprall erkannt. Fluggerät gelandet. Fluggerät neu starten", + "en": "Impact detected. Aircraft landed. Restart aircraft", + "es": "Impacto detectado. La aeronave ha aterrizado. Reinicia la aeronave", + "fr": "Impact détecté. L\\'appareil a atterrit. Redémarrez l\\'appareil", + "ja": "衝撃を検出。機体が着陸しました。機体を再起動してください", + "ko": "충격 감지됨. 기체 착륙함. 기체를 다시 시작해야 함", + "ru": "Обнаружен удар. Дрон приземлился. Перезагрузите его", + "tr": "Etki tespit edildi. Araç indi. Aracı yeniden başlatın", + "zh": "检测到被撞击,飞行器已停止飞行,请重启飞行器" + }, + "fpv_tip_0x1610007F": { + "de": "Aufprall erkannt. Start nicht möglich. Fluggerät neu starten", + "en": "Impact detected. Unable to take off. Restart aircraft", + "es": "Impacto detectado. No se puede despegar. Reinicia la aeronave", + "fr": "Impact détecté. Impossible de décoller. Redémarrez l\\'appareil", + "ja": "衝撃を検出。離陸できません。機体を再起動してください", + "ko": "충격 감지됨. 이륙 불가. 기체 재시작 필요", + "ru": "Обнаружен удар. Не удалось взлететь. Перезагрузите дрон", + "tr": "Etki tespit edildi. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:检测到飞行器发生过撞击,请重启飞行器" + }, + "fpv_tip_0x1610007F_in_the_sky": { + "de": "Aufprall erkannt. Zum Startpunkt zurückkehren oder landen", + "en": "Impact detected. Return to home or land", + "es": "Impacto detectado. Regresa al punto de origen o aterriza", + "fr": "Impact détecté. Revenez au point de départ ou atterrissez", + "ja": "衝撃を検出。帰還するか、着陸してください", + "ko": "충격 감지됨. RTH 진행 또는 착륙 필요", + "ru": "Столкновение дрона. Вернитесь домой или приземлитесь", + "tr": "Etki tespit edildi. Eve geri dönün veya iniş yapın", + "zh": "检测到飞行器发生过撞击,请返航或降落" + }, + "fpv_tip_0x16100080": { + "de": "Kontrollfehler: Höhenlage. Start nicht möglich. Fluggerät neu starten", + "en": "Aircraft altitude control error. Unable to take off. Restart aircraft", + "es": "Error de control de la altitud de la aeronave. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur de contrôle de l\\'altitude de l\\'appareil. Impossible de décoller. Redémarrez l\\'appareil", + "ja": "機体高度制御エラー。離陸できません。機体を再起動してください", + "ko": "기체 고도 제어 오류. 이륙 불가. 기체 재시작 필요", + "ru": "Ошибка управления высотой дрона. Взлет невозможен. Перезагрузите дрон", + "tr": "Araç irtifa kontrol hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:飞行器高度控制异常,请重启飞行器" + }, + "fpv_tip_0x16100080_in_the_sky": { + "de": "Kontrollfehler: Höhenlage. Zum Startpunkt zurückkehren oder landen", + "en": "Aircraft altitude control error. RTH or land", + "es": "Error de control de la altitud de la aeronave. RPO o aterriza", + "fr": "Erreur de contrôle de l\\'altitude de l\\'appareil. Revenez au point de départ ou atterrissez", + "ja": "機体高度制御エラー。RTHを行うか、着陸してください", + "ko": "기체 고도 제어 오류. RTH 진행 또는 착륙 필요", + "ru": "Ошибка изменения высоты дрона. Вернитесь домой или приземлитесь", + "tr": "Araç irtifa kontrol hatası. Eve dönün ya da iniş yapın", + "zh": "飞行器高度控制异常,请返航或降落" + }, + "fpv_tip_0x16100081": { + "de": "Firmware-Version des Akkus veraltet. Start nicht möglich. Auf die neueste Firmware-Version aktualisieren", + "en": "Battery firmware out-of-date. Unable to take off. Update to latest firmware version", + "es": "Firmware de la batería obsoleto. No se puede despegar. Actualiza a la versión del firmware más reciente", + "fr": "Firmware de la batterie obsolète. Impossible de décoller. Mettez à jour vers la version la plus récente", + "ja": "古いバッテリーファームウェアです。離陸できません。最新のファームウェアバージョンに更新してください", + "ko": "오래된 배터리 펌웨어. 이륙 불가. 최신 펌웨어 버전으로 업데이트해야 함", + "ru": "Устаревшая версия ПО батареи . Взлет невозможен. Установите последнюю версию ПО", + "tr": "Pil yazılımı güncel değil. Kalkış yapamıyor. En güncel yazılım sürümüne güncelleyin", + "zh": "无法起飞:电池固件版本过低,请更新飞行器固件" + }, + "fpv_tip_0x16100081_in_the_sky": { + "de": "Firmware-Version des Akkus veraltet. Zum Startpunkt zurückkehren oder landen. Auf die neueste Firmware-Version aktualisieren", + "en": "Battery firmware version out of date. Return to home or land. Update to latest firmware version", + "es": "Versión del firmware de la batería obsoleta. Regresa al punto de origen o aterriza. Actualiza a la versión del firmware más reciente", + "fr": "Version du firmware de la batterie obsolète. Revenez au point de départ ou atterrissez. Mettez à jour vers la version la plus récente", + "ja": "バッテリーのファームウェアバージョンが古くなっています。帰還するか、着陸してください。最新のファームウェアバージョンに更新してください", + "ko": "오래된 배터리 펌웨어 버전. RTH 진행 또는 착륙 필요. 최신 펌웨어 버전으로 업데이트해야 함", + "ru": "Старая версия ПО батареи. Вернитесь домой или приземлитесь. Установите последнюю версию ПО", + "tr": "Pil yazılım sürümü güncel değil. Eve geri dönün veya iniş yapın. En güncel yazılım sürümüne güncelleyin", + "zh": "电池固件版本过低,请返航或降落,并更新飞行器固件" + }, + "fpv_tip_0x16100082": { + "de": "Zu großer Spannungsunterschied zwischen den Akkus. Start nicht möglich. Akkuwartung notwendig", + "en": "Large voltage different between battery cells. Unable to take off. Battery maintenance required", + "es": "Gran diferencia de voltaje entre las células de batería. No se puede despegar. La batería requiere mantenimiento", + "fr": "Différence de tension entre les cellules de la batterie importante. Impossible de décoller. Opération de maintenance de la batterie requise", + "ja": "バッテリーセルの電圧差が大きすぎます。離陸できません。バッテリーのメンテナンスが必要です", + "ko": "배터리 셀 간 전압차 너무 큼. 이륙 불가. 배터리 유지 보수 필요", + "ru": "Обнаружена большая разница между напряжением элементов аккумулятора. Требуется техосмотр батареи", + "tr": "Pil hücreleri arasındaki voltaj farkı yüksek. Kalkış yapamıyor. Pil bakımı gerekli", + "zh": "无法起飞:电池电芯压差过大,请对电池进行保养" + }, + "fpv_tip_0x16100082_in_the_sky": { + "de": "Zu großer Spannungsunterschied zwischen den Akkus. Start nicht möglich. Akkuwartung notwendig", + "en": "Large difference in battery cell voltage detected. Return to home or land. Battery maintenance required", + "es": "Se ha detectado una gran diferencia de voltaje entre las células de batería. Regresa al punto de origen o aterriza. La batería requiere mantenimiento", + "fr": "Différence de tension entre les cellules de la batterie importante. Revenez au point de départ ou atterrissez. Maintenance de la batterie requise", + "ja": "バッテリーセルに大きい電圧差が検出されました。帰還するか、着陸してください。バッテリーのメンテナンスが必要です", + "ko": "배터리 셀 전압의 큰 차이가 감지됨. RTH 진행 또는 착륙 필요. 배터리 유지 보수 필요", + "ru": "Обнаружена большая разница между напряжением элементов аккумулятора. Требуется техосмотр батареи", + "tr": "Pil hücreleri arasında yüksek voltaj farkı tespit edildi. Eve geri dönün veya iniş yapın. Pil bakımı gerekli", + "zh": "电池电芯压差过大,请返航或降落,再对电池进行保养" + }, + "fpv_tip_0x16100083": { + "de": "Akkufehler. Start nicht möglich. Sicherstellen, dass Akkus bis zum Anschlag eingeschoben sind und beide Akkus fest sitzen", + "en": "Battery installed incorrectly. Unable to take off. Turn battery locker to its limit and ensure both batteries are installed correctly", + "es": "Batería instalada de forma incorrecta. No se puede despegar. Gira el seguro de la batería hasta el tope y asegúrate de que las dos baterías estén instaladas correctamente", + "fr": "Batterie mal installée. Impossible de décoller. Tournez le verrou de la batterie jusqu\\'à sa limite et assurez-vous que les deux batteries sont installées correctement", + "ja": "バッテリーが正しく取り付けられていません。離陸できません。バッテリーロッカーを限界まで回し、両方のバッテリーが正しく取り付けられていることを確認してください", + "ko": "배터리 설치 잘못됨. 이륙 불가. 배터리 잠금장치를 최대한으로 회전시키고 배터리가 모두 잘 설치되었는지 확인 필요", + "ru": "Батарея установлена некорректно. Взлет невозможен. Закройте защелку батареи до упора и убедитесь, что оба аккумулятора установлены корректно", + "tr": "Pil hatalı takılmış. Kalkış yapamıyor. Pil kilidini sonuna kadar çevirin ve her iki pilin de düzgün şekilde yerleştirildiğinden emin olun", + "zh": "无法起飞:电池安装不到位,请将电池锁紧旋钮旋转到位" + }, + "fpv_tip_0x16100083_in_the_sky": { + "de": "Akku falsch eingesetzt/installiert. Zum Startpunkt zurückkehren oder landen. Die Akkusperre maximal setzen und sicherstellen, dass beide Akkus fest sitzen bzw. installiert sind .", + "en": "Battery installed incorrectly. Return to home or land. Turn battery locker to its limit and ensure both batteries are installed correctly", + "es": "Batería instalada de forma incorrecta. Regresa al punto de origen o aterriza. Gira el seguro de la batería hasta el tope y asegúrate de que las dos baterías estén instaladas correctamente", + "fr": "Batterie mal installée. Revenez au point de départ ou atterrissez. Tournez le verrou de la batterie jusqu\\'à sa limite et assurez-vous que les deux batteries sont installées correctement", + "ja": "バッテリーが正しく取り付けられていません。帰還するか、着陸してください。バッテリーロッカーを限界まで回し、両方のバッテリーが正しく取り付けられていることを確認してください", + "ko": "배터리 설치 잘못됨. RTH 또는 착륙 필요. 배터리 잠금장치를 최대한으로 회전시키고 배터리가 모두 잘 설치되었는지 확인 필요", + "ru": "Батарея установлена некорректно. Вернитесь домой или приземлитесь. Закройте защелку батареи до упора и убедитесь, что оба аккумулятора установлены корректно", + "tr": "Pil hatalı takılmış. Eve geri dönün veya iniş yapın. Pil kilidini sonuna kadar çevirin ve her iki pilin de düzgün şekilde yerleştirildiğinden emin olun", + "zh": "电池安装不到位,请返航或降落,并检查电池锁紧旋是否钮旋转到位" + }, + "fpv_tip_0x16100084": { + "ar": "", + "de": "Fehler: oberer Lüfter. Start nicht möglich. Überprüfen, ob der obere Lüfter blockiert ist", + "en": "Upper fan error. Unable to take off. Check whether upper fan is stalled", + "es": "Error del ventilador superior. No se puede despegar. Compruebe si el ventilador superior está atascado", + "fr": "Erreur du ventilateur supérieur. Impossible de décoller. Vérifiez si le ventilateur supérieur est bloqué", + "id": "", + "it": "", + "ja": "上部ファンエラー。離陸できません。上部ファンが停止していないかを確認してください", + "ko": "상단 팬 오류입니다. 이륙 불가. 상단 팬이 멈췄는지 확인하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка верхнего вентилятора. Не удается выполнить взлет. Убедитесь, что верхний вентилятор не заклинило", + "th": "", + "tr": "Üst fan hatası. Kalkış yapılamıyor. Üst fanın arızalanarak durup durmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "无法起飞:上风扇异常,请检查飞行器上风扇是否有堵转", + "zh-Hant": "" + }, + "fpv_tip_0x16100084_in_the_sky": { + "ar": "", + "de": "Fehler: oberer Lüfter. Zum Startpunkt zurückkehren oder landen. Überprüfen, ob der obere Lüfter blockiert ist", + "en": "Upper fan error. Return to home or land. Check whether upper fan is stalled", + "es": "Error del ventilador superior. Regrese al punto de origen o aterrice. Compruebe si el ventilador superior está atascado", + "fr": "Erreur du ventilateur supérieur. Revenez au point de départ ou atterrissez. Vérifiez si le ventilateur supérieur est bloqué", + "id": "", + "it": "", + "ja": "上部ファンエラー。RTHまたは着陸させてください。上部ファンが停止していないかを確認してください", + "ko": "상단 팬 오류입니다. 홈으로 돌아가거나 착륙하세요. 상단 팬이 멈췄는지 확인하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка верхнего вентилятора. Вернитесь домой или приземлитесь. Убедитесь, что верхний вентилятор не заклинило", + "th": "", + "tr": "Üst fan hatası. Eve geri dönün veya iniş yapın. Üst fanın arızalanarak durup durmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "上风扇异常,请返航或降落,再检查飞行器上风扇是否有堵转", + "zh-Hant": "" + }, + "fpv_tip_0x16100085": { + "de": "Fluggerät überhitzt. Start nicht möglich. Fluggerät ausschalten und warten, bis sich die Temperatur wieder normalisiert hat", + "en": "Aircraft overheated. Unable to take off. Power off aircraft and wait for temperature to return to normal", + "es": "Aeronave sobrecalentada. No se puede despegar. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad", + "fr": "Surchauffe de l\\'appareil. Impossible de décoller. Éteignez-le et attendez que la température revienne à la normale", + "ja": "機体が高温。離陸できません。機体の電源を切り、通常の温度に戻るまで待ってください", + "ko": "기체 과열됨. 이륙 불가. 기체 전원을 끄고 정상 온도로 내려갈 때까지 기다려야 함", + "ru": "Перегрев дрона. Взлет невозможен. Выключите дрон и дождитесь, пока он остынет", + "tr": "Araç aşırı ısındı. Kalkış yapamıyor. Aracı kapatın ve sıcaklığın normale dönmesini bekleyin", + "zh": "无法起飞:飞行器过热,请关闭飞行器至恢复正常温度" + }, + "fpv_tip_0x16100085_in_the_sky": { + "de": "Flugzeuge überhitzt. Zum Startpunkt zurückkehren oder landen. Fluggerät ausschalten und warten, bis sich die Temperatur wieder normalisiert hat .", + "en": "Aircraft overheated. Return to home or land. Power off aircraft and wait for temperature to return to normal", + "es": "Aeronave sobrecalentada. Regresa al punto de origen o aterriza. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad", + "fr": "Surchauffe de l\\'appareil. Revenez au point de départ ou atterrissez. Éteignez-le et attendez que la température revienne à la normale", + "ja": "機体が高温。帰還するか、着陸してください。機体の電源を切り、通常の温度に戻るまで待ってください", + "ko": "기체 과열됨. RTH 또는 착륙 필요. 기체 전원을 끄고 정상 온도로 내려갈 때까지 기다려야 함", + "ru": "Перегрев дрона. Вернитесь домой или приземлитесь. Выключите дрон и дождитесь, пока он остынет", + "tr": "Araç aşırı ısındı. Eve geri dönün veya iniş yapın. Aracı kapatın ve sıcaklığın normale dönmesini bekleyin", + "zh": "飞行器过热,请返航或降落,再关闭飞行器至恢复正常温度" + }, + "fpv_tip_0x16100087": { + "de": "Motoren-Notstopp eingeleitet . Start nicht möglich", + "en": "Emergency Propeller Stop triggered. Unable to take off", + "es": "Se ha activado la parada de emergencia de la hélice. No se puede despegar", + "fr": "Arrêt d\\'urgence des hélices activé . Impossible de décoller.", + "ja": "プロペラ緊急停止が作動しました。離陸できません", + "ko": "비상 프로펠러 정지 작동됨 . 이륙 불가", + "ru": "Активирована экстренная остановка пропеллеров . Взлет невозможен", + "tr": "Acil Durum Pervane Durdurma tetiklendi. Kalkış yapamıyor", + "zh": "无法起飞:已触发紧急停桨" + }, + "fpv_tip_0x16100087_in_the_sky": { + "de": "Motoren-Notstopp eingeleitet", + "en": "Emergency Propeller Stop triggered", + "es": "Se ha activado la parada de emergencia de la hélice", + "fr": "Arrêt d\\'urgence des hélices activé", + "ja": "プロペラ緊急停止が作動しました", + "ko": "비상 프로펠러 정지 작동됨", + "ru": "Активирована экстренная остановка пропеллеров", + "tr": "Acil Durum Pervane Durdurma tetiklendi", + "zh": "已触发紧急停浆" + }, + "fpv_tip_0x16100088": { + "de": "Start nicht möglich. Fernsteuerung wird kalibriert. Kalibrierung zuerst beenden", + "en": "Unable to take off. Calibrating remote controller. Exit calibration first", + "es": "No se puede despegar. Calibrando el control remoto. Salir primero de la calibración", + "fr": "Impossible de décoller. Étalonnage de la radiocommande. Quitter d’abord l’étalonnage", + "ja": "離陸できません。送信機をキャリブレーション中です。まずキャリブレーションを終了してください", + "ko": "이륙 불가. 조종기 캘리브레이션 중. 먼저 캘리브레이션을 종료하세요", + "ru": "Невозможно взлететь. Калибровка пульта. Сначала выйдите из калибровки", + "tr": "Kalkış yapılamıyor. Uzaktan kumanda kalibre ediliyor. Önce kalibrasyondan çıkın", + "zh": "无法起飞:遥控器校准中,请先退出校准状态" + }, + "fpv_tip_0x16100088_in_the_sky": { + "de": "Start nicht möglich. Fernsteuerung wird kalibriert. Kalibrierung zuerst beenden", + "en": "Unable to take off. Calibrating remote controller. Exit calibration first", + "es": "No se puede despegar. Calibrando el control remoto. Salir primero de la calibración", + "fr": "Impossible de décoller. Étalonnage de la radiocommande. Quitter d’abord l’étalonnage", + "ja": "離陸できません。送信機をキャリブレーション中です。まずキャリブレーションを終了してください", + "ko": "이륙 불가. 조종기 캘리브레이션 중. 먼저 캘리브레이션을 종료하세요", + "ru": "Невозможно взлететь. Калибровка пульта. Сначала выйдите из калибровки", + "tr": "Kalkış yapılamıyor. Uzaktan kumanda kalibre ediliyor. Önce kalibrasyondan çıkın", + "zh": "无法起飞:遥控器校准中,请先退出校准状态" + }, + "fpv_tip_0x16100089": { + "ar": "", + "de": "Start nicht möglich. Fernsteuerung nicht an das aktuelle Fluggerät gekoppelt oder Kopplungsstatus muss noch bestätigt werden. Verknüpfte Fernsteuerung verwenden oder Fluggerät mit aktueller Fernsteuerung verknüpfen", + "en": "Unable to take off. Remote controller not bound/still confirming binding status. Use bound remote controller or bind aircraft to current remote controller", + "es": "No se puede despegar. Control remoto no vinculado/estado de vinculación aún en confirmación. Usa el control remoto vinculado o vincula la aeronave al control remoto actual", + "fr": "Unable to take off. Radiocommande non liée à l'appareil/en attente de confirmation de liaison. Use bound remote controller or bind aircraft to current remote controller", + "id": "", + "it": "", + "ja": "離陸できません。送信機が紐付けされていない/紐付けステータスを確認中。バインドされている送信機を使用するか、機体を現在の送信機にバインドします", + "ko": "이륙 불가. 조종기 바인딩 안 됨/바인딩 상태 확인 중. 바인딩된 조종기를 사용하거나 기체를 현재 조종기에 바인딩하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Не удается выполнить взлет. Пульт управления не привязан к дрону, или статус привязки пока не подтвержден. Используйте привязанный пульт дистанционного управления или привяжите дрон к текущему пульту дистанционного управления", + "th": "", + "tr": "Kalkış yapılamıyor. Uzaktan kumanda bağlanmadı/hala bağlanma durumunu onaylıyor. Bağlı uzaktan kumandayı kullanın veya hava aracını geçerli uzaktan kumandaya bağlayın", + "ug": "", + "vi": "", + "zh": "无法起飞:绑定设备不匹配或正在校验中,请使用绑定遥控器或绑定当下遥控器。", + "zh-Hant": "" + }, + "fpv_tip_0x16100089_in_the_sky": { + "de": "Fehler beim Abheben. Fehler beim Überprüfen der Fernsteuerung. Verknüpfte Fernsteuerung verwenden oder Fluggerät mit aktueller Fernsteuerung verknüpfen", + "en": "Takeoff error. Failed to verify remote controller. Use bound remote controller or bind aircraft to current remote controller", + "es": "Error de despegue. No se ha podido verificar el control remoto. Usa el control remoto vinculado o vincula la aeronave al control remoto actual", + "fr": "Erreur au décollage Failed to verify remote controller. Use bound remote controller or bind aircraft to current remote controller", + "ja": "離陸エラーです。送信機の検証に失敗しました。バインドされている送信機を使用するか、機体を現在の送信機にバインドします", + "ko": "이륙 오류. 조종기 인증 실패. 바인딩된 조종기를 사용하거나 기체를 현재 조종기에 바인딩하세요", + "ru": "Ошибка при взлете. Не удалось проверить пульт ДУ. Используйте привязанный пульт дистанционного управления или привяжите дрон к текущему пульту дистанционного управления", + "tr": "Kalkış hatası. Uzaktan kumanda onaylanamadı. Bağlı uzaktan kumandayı kullanın veya hava aracını geçerli uzaktan kumandaya bağlayın", + "zh": "异常起飞:遥控器绑定校验失败,请使用绑定遥控器或绑定当下遥控器。" + }, + "fpv_tip_0x1610008A": { + "de": "Fehler: Flugregler . Start nicht möglich. Fluggerät neu starten", + "en": "Flight controller unit error. Unable to take off. Restart aircraft", + "es": "Error de la unidad del controlador de vuelo. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur de l\\'unité de contrôle du vol . Impossible de décoller. Redémarrez l\\'appareil", + "ja": "フライトコントローラー ユニットエラー。離陸できません。機体を再起動してください", + "ko": "비행 컨트롤러 장치 오류 . 이륙 불가. 기체 재시작 필요", + "ru": "Ошибка блока полетного контроллера . Взлет невозможен. Перезагрузите дрон", + "tr": "Uçuş kontrol birimi hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:飞控系统组件异常,请重启飞行器" + }, + "fpv_tip_0x1610008A_in_the_sky": { + "de": "Fehler der Flugsteuerungseinheit . Zum Startpunkt zurückkehren oder landen.", + "en": "Flight controller unit error. Return to home or land", + "es": "Error de la unidad del controlador de vuelo. Regresa al punto de origen o aterriza", + "fr": "Erreur unité du contrôleur de vol . Revenez au point de départ ou atterrissez", + "ja": "フライトコントローラー ユニットエラー。帰還するか、着陸してください", + "ko": "비행 컨트롤러 장치 오류 . RTH 진행 또는 착륙 필요", + "ru": "Ошибка полетного контроллера . Вернитесь домой или приземлитесь", + "tr": "Uçuş kontrol birimi hatası. Eve geri dönün veya iniş yapın", + "zh": "飞控系统组件异常,请返航或降落" + }, + "fpv_tip_0x1610008F": { + "de": "Fluggerät-Antenne: Fehler bei der Suche nach Satellitensignal. Start nicht möglich. Zum Start in einen offenen Bereich gehen", + "en": "Aircraft antenna satellite signal searching error. Unable to take off. Move to an open area for takeoff", + "es": "Error de búsqueda de señal satelital de la antena de la aeronave. No se puede despegar. Desplázate a un espacio abierto para despegar", + "fr": "Erreur de recherche du signal satellite de l\\'antenne de l\\'appareil. Décollage impossible. Déplacez-vous vers une zone dégagée pour décoller", + "ja": "機体アンテナ衛星信号検索エラー。離陸できません。開けたエリアに移動して離陸してください", + "ko": "기체 안테나 위성 신호 검색 오류. 이륙할 수 없습니다. 이륙을 위해 개방 영역으로 이동하세요", + "ru": "Ошибка поиска сигнала спутника для антенны дрона. Невозможно выполнить взлет. Переместитесь на открытый участок для взлета", + "tr": "Araç anteni uydu sinyal arama hatası. Kalkış yapamıyor. Kalkış için açık bir alana gidin", + "zh": "无法起飞:机载天线搜星质量较差,请至空旷地起飞" + }, + "fpv_tip_0x1610008F_in_the_sky": { + "de": "Fluggerät-Antenne: Fehler bei der Suche nach Satellitensignal. Mit Vorsicht fliegen", + "en": "Aircraft antenna satellite signal searching error. Fly with caution", + "es": "Error de búsqueda de señal satelital de la antena de la aeronave. Vuela con cuidado", + "fr": "Erreur de recherche du signal satellite de l\\'antenne de l\\'appareil. Volez avec précaution", + "ja": "機体アンテナ衛星信号検索エラー。慎重に飛行してください", + "ko": "기체 안테나 위성 신호 검색 오류. 주의해서 비행하세요", + "ru": "Ошибка поиска сигнала спутника для антенны дрона. Будьте внимательны при полете", + "tr": "Araç anteni uydu sinyal arama hatası. Dikkatli uçurun", + "zh": "机载天线搜星质量较差,请谨慎飞行" + }, + "fpv_tip_0x16100090": { + "de": "Fehler: Sensorsystem . Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs . Redémarrez l\\'appareil", + "ja": "センサー システムエラー。機体を再起動してください", + "ko": "센서 시스템 오류 . 기체 재시동", + "ru": "Ошибка системы датчиков . Перезапустите дрон", + "tr": "Sensör sistemi hatası. Aracı yeniden başlatın", + "zh": "无法起飞:传感器系统异常,请重启飞行器" + }, + "fpv_tip_0x16100090_in_the_sky": { + "de": "Fehler: Sensorsystem . Zum Startpunkt zurückkehren oder landen", + "en": "Sensor system error. Return to home or land", + "es": "Error del sistema de sensores. Regresa al punto de origen o aterriza", + "fr": "Erreur du système de capteurs . Revenez au point de départ ou atterrissez", + "ja": "センサーシステムエラー。帰還するか着陸して下さい", + "ko": "센서 시스템 오류 . 홈으로 돌아가거나 착륙", + "ru": "Ошибка системы датчиков . Вернитесь домой или приземлитесь", + "tr": "Sensör sistemi hatası. Eve geri dönün veya iniş yapın", + "zh": "传感器系统异常,请返航或降落" + }, + "fpv_tip_0x16100091": { + "de": "Flug im aktuellen Bereich verboten . Start nicht möglich", + "en": "Flight prohibited in current area. Unable to take off", + "es": "Está prohibido volar en la zona actual. No se puede despegar", + "fr": "Vol interdit dans cette zone . Impossible de décoller", + "ja": "現在のエリアの飛行は禁止されています。離陸できません", + "ko": "현재 구역에서 비행 금지 . 이륙 불가", + "ru": "Полет запрещен в данной области . Взлет невозможен", + "tr": "Mevcut alanda uçuş yasaktır. Kalkış yapamıyor", + "zh": "无法起飞:该飞行器无法在此区域飞行" + }, + "fpv_tip_0x16100091_in_the_sky": { + "de": "Fliegen in diesem Bereich verboten (alarmierend). Zum Startpunkt zurückkehren oder landen.", + "en": "Flying prohibited in current area. Return to home or land", + "es": "Está prohibido volar en la zona actual. Regresa al punto de origen o aterriza", + "fr": "Vol interdit dans cette zone . Revenez au point de départ ou atterrissez", + "ja": "現在のエリアの飛行は禁止されています。帰還するか、着陸してください", + "ko": "현재 구역에서 비행 금지 . RTH 진행 또는 착륙 필요", + "ru": "Полет запрещен в данной области . Вернитесь домой или приземлитесь", + "tr": "Mevcut alanda uçuş yasaktır. Eve geri dönün veya iniş yapın", + "zh": "该飞行器无法在此区域飞行,请返航或降落" + }, + "fpv_tip_0x16100091_in_the_sky_special": { + "de": "Fliegen in diesem Bereich nicht möglich. Max. Flughöhe auf %1$s m beschränkt", + "en": "Unable to fly in this area. Max flight altitude limited to %1$s m", + "es": "No se puede volar en esta zona. Altitud de vuelo máxima limitada a %1$s m", + "fr": "Impossible de voler dans cette zone. Altitude en vol max limitée à %1$s m", + "ja": "このエリアでは飛行できません。最大飛行高度が%1$s mに制限されています", + "ko": "이 지역에서 비행 불가. 최고 비행 고도가 %1$sm로 제한됨.", + "ru": "Полет в этой области невозможен. Максимальная высота полета ограничена до %1$s м", + "tr": "Bu bölgede uçulamıyor. Maks. uçuş irtifası %1$s m ile sınırlıdır", + "zh": "该飞行器无法在此区域飞行,限高%1$s m" + }, + "fpv_tip_0x16100092": { + "de": "Fehler: Akkukapazität. Start nicht möglich. Akkuwartung notwendig", + "en": "Battery capacity error. Unable to take off. Battery maintenance required", + "es": "Error de capacidad de la batería. No se puede despegar. La batería requiere mantenimiento", + "fr": "Erreur de capacité de la batterie. Impossible de décoller. Opération de maintenance de la batterie requise", + "ja": "バッテリー容量エラー。離陸できません。バッテリーのメンテナンスが必要です", + "ko": "배터리 용량 오류. 이륙 불가. 배터리 유지 보수 필요", + "ru": "Ошибка емкости батареи. Взлет невозможен. Требуется ее техосмотр", + "tr": "Pil kapasitesi hatası. Kalkış yapamıyor. Pil bakımı gerekli", + "zh": "无法起飞:电池电量异常,请进行电池保养" + }, + "fpv_tip_0x16100092_in_the_sky": { + "de": "Fehler: Akkukapazität. Start nicht möglich. Akkuwartung notwendig", + "en": "Battery capacity error. Return to home or land. Battery maintenance required", + "es": "Error de capacidad de la batería. Regresa al punto de origen o aterriza. La batería requiere mantenimiento", + "fr": "Erreur de capacité de la batterie. Revenez au point de départ ou atterrissez", + "ja": "バッテリー容量エラー。帰還するか、着陸してください。バッテリーのメンテナンスが必要です", + "ko": "배터리 용량 오류. RTH 진행 또는 착륙 필요. 배터리 유지 보수 필요", + "ru": "Ошибка емкости батареи. Вернитесь домой или приземлитесь. Требуется техосмотр батареи", + "tr": "Pil kapasitesi hatası. Eve geri dönün veya iniş yapın. Pil bakımı gerekli", + "zh": "电池电量异常,请返航或降落,再进行电池保养" + }, + "fpv_tip_0x16100095": { + "de": "Unable to take off. Set Hover mode before flying", + "en": "Unable to take off. Set Hover mode before flying", + "es": "Unable to take off. Set Hover mode before flying", + "fr": "Unable to take off. Set Hover mode before flying", + "ja": "Unable to take off. Set Hover mode before flying", + "ko": "Unable to take off. Set Hover mode before flying", + "ru": "Unable to take off. Set Hover mode before flying", + "tr": "Unable to take off. Set Hover mode before flying", + "zh": "无法起飞:请在起飞前设置飞行器悬停模式" + }, + "fpv_tip_0x16100096": { + "de": "%battery_index Fehler Akkustromversorgung. Fluggerät landet automatisch", + "en": "%battery_index Battery power supply error. Aircraft auto landing", + "es": "%battery_index Error de la fuente de alimentación de la batería. Aterrizaje automático de la aeronave", + "fr": "%battery_index Erreur d’alimentation de la batterie. Atterrissage automatique de l’appareil", + "ja": "%battery_indexバッテリー電源エラー。機体が自動着陸中", + "ko": "%battery_index 배터리 전력 공급 장치 오류. 기체 자동 착륙", + "ru": "%battery_index Ошибка питания АКБ. Автоматическая посадка дрона", + "tr": "%battery_index Pil güç kaynağı hatası. Hava aracı otomatik iniş yapıyor", + "zh": "%battery_index电池供电异常,飞行器强制降落" + }, + "fpv_tip_0x16100099": { + "de": "Fehler: Gimbal. Start nicht möglich. Überprüfen, ob sich der Gimbal frei drehen kann und Fluggerät neu starten", + "en": "Gimbal starting error. Unable to take off. Check whether gimbal can rotate freely and restart aircraft", + "es": "Error de inicio del estabilizador. No se puede despegar. Comprueba si el estabilizador puede rotar con libertad y reinicia la aeronave", + "fr": "Erreur de démarrage de la nacelle. Impossible de décoller. Vérifiez si la nacelle peut tourner librement et redémarrez l\\'appareil", + "ja": "ジンバル開始エラー。離陸できません。ジンバルが制限なく回転するか確認して、機体を再起動してください", + "ko": "짐벌 시작 오류. 이륙 불가. 짐벌이 자유롭게 회전할 수 있는지 확인하고 기체를 다시 시작해야 함", + "ru": "Ошибка запуска стабилизатора. Взлет невозможен. Проверьте, поворачивается ли стабилизатор свободно, и перезапустите дрон", + "tr": "Gimbal başlatma hatası. Kalkış yapamıyor. Gimbalın rahatça hareket edip etmediğini kontrol edin ve aracı yeniden başlatın", + "zh": "无法起飞:云台启动异常,请检查云台是否能自由转动,再重启飞行器" + }, + "fpv_tip_0x16100099_in_the_sky": { + "de": "Gimbal-Startfehler. Zum Startpunkt zurückkehren oder landen. Überprüfen, ob sich der Gimbal frei drehen kann und starten Sie das Fluggerät neu .", + "en": "Gimbal startup error. Return to home or land. Check whether gimbal can rotate freely and restart aircraft", + "es": "Error de inicio del estabilizador. Regresa al punto de origen o aterriza. Comprueba si el estabilizador puede rotar con libertad y reinicia la aeronave", + "fr": "Erreur de démarrage de la nacelle. Revenez au point de départ ou atterrissez. Vérifiez si la nacelle peut tourner librement et redémarrez l\\'appareil", + "ja": "ジンバル開始エラー。帰還するか、着陸してください。ジンバルが制限なく回転するか確認して、機体を再起動してください", + "ko": "짐벌 시작 오류. RTH 진행 또는 착륙 필요. 짐벌이 자유롭게 회전할 수 있는지 확인하고 기체를 다시 시작해야 함", + "ru": "Ошибка запуска стабилизатора. Вернитесь домой или приземлитесь. Проверьте, поворачивается ли стабилизатор свободно, и перезапустите дрон", + "tr": "Gimbal başlatma hatası. Eve geri dönün veya iniş yapın. Gimbalın rahatça hareket edip etmediğini kontrol edin ve aracı yeniden başlatın", + "zh": "云台启动异常,请返航或降落,再检查云台是否能自由转动,再重启飞行器" + }, + "fpv_tip_0x1610009A": { + "de": "Starke Vibrationen am Gimbal. Start nicht möglich. Bitte Gimbal überprüfen und Fluggerät neu starten", + "en": "Excessive gimbal vibration. Unable to take off. Check whether gimbal can rotate freely or is damaged. Restart aircraft", + "es": "Vibración del estabilizador excesiva. No se puede despegar. Comprueba si el estabilizador puede rotar con libertad o si está dañado. Reinicia la aeronave", + "fr": "Vibrations excessives de la nacelle. Impossible de décoller. Vérifiez si la nacelle peut tourner librement ou si elle est endommagée. Redémarrez l\\'appareil", + "ja": "ジンバルの過剰な振動。離陸できません。ジンバルが制限なく回転するか、または損傷していないか確認してください。機体を再起動してください", + "ko": "과도한 짐벌 진동. 이륙 불가. 짐벌이 자유롭게 회전할 수 있는지 또는 손상되었는지 확인 필요. 기체를 다시 시작해야 함", + "ru": "Избыточная вибрация стабилизатора. Взлет невозможен. Убедитесь, что стабилизатор поворачивается свободно и не поврежден. Перезагрузите дрон", + "tr": "Gimbal aşırı titriyor. Kalkış yapamıyor. Gimbalın rahatça hareket edip etmediğini ve hasar görüp görmediğini kontrol edin. Aracı yeniden başlatın", + "zh": "无法起飞:云台异常振动,请检查云台是否能自由转动、是否受损,再重启飞行器" + }, + "fpv_tip_0x1610009A_in_the_sky": { + "de": "Exzessive Vibrationen am Gimbal. Zum Startpunkt zurückkehren oder landen. Bitte Gimbal überprüfen und Fluggerät neu starten", + "en": "Excessive gimbal vibration. Return to home or land. Check whether gimbal can rotate freely or is damaged. Restart aircraft", + "es": "Vibración del estabilizador excesiva. Regresa al punto de origen o aterriza. Comprueba si el estabilizador puede rotar con libertad o si está dañado. Reinicia la aeronave", + "fr": "Vibrations excessives de la nacelle. Revenez au point de départ ou atterrissez. Vérifiez si la nacelle peut tourner librement ou si elle est endommagée. Redémarrez l\\'appareil", + "ja": "ジンバルの過剰な振動。帰還するか、着陸してください。ジンバルが制限なく回転するか、または損傷していないか確認してください。機体を再起動してください", + "ko": "과도한 짐벌 진동. RTH 진행 또는 착륙 필요. 짐벌이 자유롭게 회전할 수 있는지 또는 손상되었는지 확인 필요. 기체를 다시 시작해야 함", + "ru": "Избыточная вибрация стабилизатора. Вернитесь домой или приземлитесь. Убедитесь, что стабилизатор поворачивается свободно и не поврежден. Перезагрузите дрон", + "tr": "Gimbal aşırı titriyor. Eve geri dönün veya iniş yapın. Gimbalın rahatça hareket edip etmediğini ve hasar görüp görmediğini kontrol edin. Aracı yeniden başlatın", + "zh": "云台异常振动,请返航或降落,再检查云台是否能自由转动、是否受损,再重启飞行器" + }, + "fpv_tip_0x1610009F": { + "ar": "", + "de": "Gerätefehler: Flugregler. Start nicht möglich. Fluggerät neu starten", + "en": "Flight controller unit error. Unable to take off. Restart aircraft", + "es": "Error de la unidad del controlador de vuelo. No se puede despegar. Reinicia la aeronave", + "fr": "Erreur de l\\'unité de contrôle du vol. Impossible de décoller. Redémarrez l\\'appareil", + "it": "", + "ja": "フライトコントローラー ユニットエラー。離陸できません。機体を再起動してください", + "ko": "비행 컨트롤러 장치 오류. 이륙 불가. 기체 재시작 필요", + "pt": "", + "ru": "Ошибка блока полетного контроллера. Невозможно выполнить взлет. Перезагрузите дрон", + "tr": "Uçuş kontrol birimi hatası. Kalkış yapamıyor. Aracı yeniden başlatın", + "zh": "无法起飞:飞控系统组件异常,请重启飞行器" + }, + "fpv_tip_0x1610009F_in_the_sky": { + "de": "Gerätefehler: Flugregler. Zum Startpunkt zurückkehren oder landen", + "en": "Flight controller unit error. Return to home or land", + "es": "Error de la unidad del controlador de vuelo. Regresa al punto de origen o aterriza", + "fr": "Erreur unité du contrôleur de vol. Revenez au point de départ ou atterrissez", + "ja": "フライトコントローラーユニットエラー。帰還するか着陸してください", + "ko": "비행 컨트롤러 장치 오류. 리턴 투 홈 진행 또는 착륙 필요", + "ru": "Ошибка блока полетного контроллера. Вернитесь домой или приземлитесь", + "tr": "Uçuş kontrol birimi hatası. Eve geri dönün veya iniş yapın", + "zh": "飞控系统组件异常,请返航或降落" + }, + "fpv_tip_0x161000A0": { + "de": "GEO-Modulfehler. Start nicht möglich", + "en": "GEO module error. Unable to take off", + "es": "", + "fr": "Erreur du module GEO. Décollage impossible", + "ja": "GEOモジュールエラー。離陸できません", + "ko": "GEO 모듈 오류. 이륙 불가", + "ru": "Ошибка модуля GEO. Невозможно выполнить взлет", + "tr": "", + "zh": "无法起飞:限飞模块组件异常" + }, + "fpv_tip_0x161000A0_in_the_sky": { + "de": "GEO-Modulfehler . Umgehend zum Startpunkt zurückkehren oder landen", + "en": "GEO module error . Return to home or land promptly", + "es": "", + "fr": "Erreur du module GEO . Revenez au point de départ ou atterrissez", + "ja": "GEOモジュールエラー。直ちに帰還するか着陸してください", + "ko": "GEO 모듈 오류 . 홈으로 돌아가거나 신속히 착륙하세요", + "ru": "Ошибка модуля GEO . Вернитесь в исходное положение или приземлитесь как можно скорее", + "tr": "", + "zh": "限飞模块组件异常,请返航或降落" + }, + "fpv_tip_0x161000A1": { + "de": "Umgehend landen und prüfen, ob die Rahmenarm-Hülse ordnungsgemäß befestigt ist.", + "en": "Unable to take off. Check whether frame arm sleeves are tightened securely", + "es": "No se puede despegar. Comprueba si las fundas del brazo del bastidor están bien apretadas", + "fr": "Atterrissez rapidement et vérifiez si les manchons des bras du châssis sont bien serrés", + "ja": "離陸できません。フレームアームスリーブがしっかりと固定されているかを確認してください", + "ko": "즉시 착륙하여 프레임 암 슬리브가 단단히 조여졌는지 확인하세요.", + "ru": "Немедленно приземлитесь и проверьте, надежно ли закреплены рукава балок рамы", + "tr": "Kalkış yapamıyor. Çerçeve kollarının bileziklerinin emniyetli bir şekilde sıkılıp sıkılmadığını kontrol edin", + "zh": "无法起飞:请检查机臂套筒是否固定到位" + }, + "fpv_tip_0x161000A1_in_the_sky": { + "de": "Umgehend landen und prüfen, ob die Rahmenarm-Hülse ordnungsgemäß befestigt ist.", + "en": "Land promptly and check whether frame arm sleeves are tightened securely", + "es": "Aterriza rápidamente y comprueba si las fundas del brazo del bastidor están bien apretadas", + "fr": "Atterrissez rapidement et vérifiez si les manchons des bras sont bien serrés", + "ja": "直ちに着陸し、フレームアームスリーブがしっかりと固定されているかを確認してください", + "ko": "즉시 착륙하여 프레임 암 슬리브가 단단히 조여졌는지 확인하세요.", + "ru": "Немедленно приземлитесь и проверьте, надежно ли закреплены рукава балок рамы", + "tr": "Hemen iniş yap ve çerçeve kollarının bileziklerinin emniyetli bir şekilde sıkılıp sıkılmadığını kontrol edin", + "zh": "请尽快降落并检查机臂套筒是否固定到位" + }, + "fpv_tip_0x161000A2": { + "ar": "", + "de": "Fehler: unterer Lüfter. Start nicht möglich. Überprüfen, ob der untere Lüfter blockiert ist", + "en": "Lower fan error. Unable to take off. Check whether lower fan is stalled", + "es": "Error del ventilador inferior. No se puede despegar. Compruebe si el ventilador inferior está atascado", + "fr": "Erreur du ventilateur inférieur. Impossible de décoller. Vérifiez si le ventilateur inférieur est bloqué", + "id": "", + "it": "", + "ja": "下部ファンエラー。離陸できません。下部ファンが停止していないかを確認してください", + "ko": "하단 팬 오류입니다. 이륙 불가. 하단 팬이 멈췄는지 확인하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка нижнего вентилятора. Не удается выполнить взлет. Убедитесь, что нижний вентилятор не заклинило", + "th": "", + "tr": "Alt fan hatası. Kalkış yapılamıyor. Alt fanın arızalanarak durup durmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "无法起飞:下风扇异常,请检查飞行器下风扇是否有堵转", + "zh-Hant": "" + }, + "fpv_tip_0x161000A2_in_the_sky": { + "ar": "", + "de": "Fehler: unterer Lüfter. Zum Startpunkt zurückkehren oder landen. Überprüfen, ob der untere Lüfter blockiert ist", + "en": "Lower fan error. Return to home or land. Check whether lower fan is stalled", + "es": "Error del ventilador inferior. Regrese al punto de origen o aterrice. Compruebe si el ventilador inferior está atascado", + "fr": "Erreur du ventilateur inférieur. Revenez au point de départ ou atterrissez. Vérifiez si le ventilateur inférieur est bloqué", + "id": "", + "it": "", + "ja": "下部ファンエラー。RTHまたは着陸させてください。下部ファンが停止していないかを確認してください", + "ko": "하단 팬 오류입니다. 홈으로 돌아가거나 착륙하세요. 하단 팬이 멈췄는지 확인하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка нижнего вентилятора. Вернитесь домой или приземлитесь. Убедитесь, что нижний вентилятор не заклинило", + "th": "", + "tr": "Alt fan hatası. Eve geri dönün veya iniş yapın. Alt fanın arızalanarak durup durmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "下风扇异常,请返航或降落,再检查飞行器下风扇是否有堵转", + "zh-Hant": "" + }, + "fpv_tip_0x161000A3": { + "ar": "", + "de": "", + "en": "Unable to take off. Disconnect aircraft from USB and try again", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "无法起飞,请断开飞机 USB 连接后重试", + "zh-Hant": "" + }, + "fpv_tip_0x161000A4": { + "de": "Start nicht möglich. Fluggerät auf sich bewegender Plattform", + "en": "Unable to take off. Aircraft on moving platform", + "es": "No se puede despegar. La aeronave está en una plataforma móvil.", + "fr": "Impossible de décoller. L'appareil se trouve sur une plate-forme en mouvement", + "ja": "離陸できません。機体が移動プラットフォーム上にあります", + "ko": "이륙 불가. 기체가 이동 플랫폼에 있음", + "ru": "Не удается выполнить взлет. Дрон на движущейся платформе", + "tr": "Kalkış yapılamıyor. Hava aracı hareketli platform üzerinde", + "zh": "无法起飞:飞行器处于移动平台" + }, + "fpv_tip_0x161000A4_in_the_sky": { + "de": "Fehler: Flugregler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Flight controller error. Return to home or land promptly", + "es": "Error del controlador de vuelo. Regresa al punto de origen o aterriza rápidamente.", + "fr": "Erreur du contrôleur de vol. Revenez au point de départ ou atterrissez rapidement", + "ja": "フライトコントローラーエラー。直ちにホームに帰還するか着陸してください", + "ko": "비행 컨트롤러 오류. 즉시 홈으로 돌아가거나 착륙하세요.", + "ru": "Ошибка полетного контроллера. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Uçuş kontrol sistemi hatası. Derhal başlangıç noktasına geri dönün veya iniş yapın", + "zh": "飞控系统异常,请尽快返航或降落" + }, + "fpv_tip_0x161000A5": { + "de": "Start nicht möglich. Propeller gefaltet", + "en": "Unable to take off. Propellers folded", + "es": "No se puede despegar. Hélices plegadas.", + "fr": "Impossible de décoller. Hélices repliées", + "ja": "離陸できません。プロペラが折りたたんだ状態です", + "ko": "이륙 불가. 프로펠러 접힘", + "ru": "Не удается выполнить взлет. Пропеллеры сложены", + "tr": "Kalkış yapılamıyor. Pervaneler katlanmış durumda", + "zh": "无法起飞:桨叶未展开" + }, + "fpv_tip_0x161000A5_in_the_sky": { + "de": "Fehler: Flugregler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Flight controller error. Return to home or land promptly", + "es": "Error del controlador de vuelo. Regresa al punto de origen o aterriza rápidamente.", + "fr": "Erreur du contrôleur de vol. Revenez au point de départ ou atterrissez rapidement", + "ja": "フライトコントローラーエラー。直ちにホームに帰還するか着陸してください", + "ko": "비행 컨트롤러 오류. 즉시 홈으로 돌아가거나 착륙하세요.", + "ru": "Ошибка полетного контроллера. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Uçuş kontrol sistemi hatası. Derhal başlangıç noktasına geri dönün veya iniş yapın", + "zh": "飞控系统异常,请尽快返航或降落" + }, + "fpv_tip_0x161000A6": { + "de": "Akku der Fernsteuerung schwach. Kann nicht abheben. Akku aufladen", + "en": "Remote controller battery low. Unable to take off. Recharge battery", + "es": "Batería del control remoto baja. No se puede despegar. Recárgala", + "fr": "Batterie de la radiocommande faible. Décollage impossible. Rechargez la batterie", + "ja": "送信機バッテリー残量低下。離陸できません。バッテリーを充電してください", + "ko": "조종기 배터리 부족. 이륙 불가. 배터리 충전 필요", + "ru": "Низкий заряд аккумулятора пульта ДУ. Взлет невозможен. Зарядите аккумулятор", + "tr": "Uzaktan kumanda pili düşük. Kalkış yapılamıyor. Pili yeniden şarj edin", + "zh": "无法起飞:遥控器电量过低,请给遥控器充电" + }, + "fpv_tip_0x161000A6_in_the_sky": { + "de": "Akku der Fernsteuerung schwach. Sofort zurückkehren oder landen", + "en": "Remote controller battery low. Return to home or land promptly", + "es": "Batería del control remoto baja. Regresa al punto de origen o aterriza rápidamente", + "fr": "Batterie de la radiocommande faible. Retournez au point de départ ou atterrissez rapidement", + "ja": "送信機バッテリー残量低下。直ちに帰還するか着陸してください", + "ko": "조종기 배터리 부족. 즉시 RTH 또는 착륙 필요", + "ru": "Низкий заряд аккумулятора пульта ДУ. Вернитесь домой или приземлитесь немедленно", + "tr": "Uzaktan kumanda pili düşük. Eve geri dönün veya düzgün iniş yapın", + "zh": "遥控器电量过低,请尽快返航或降落" + }, + "fpv_tip_0x161000A7": { + "de": "Start nicht möglich. Fehler beim Überprüfen der Fernsteuerung. Max. Anzahl von temporären Flügen erreicht. Verknüpfte Fernsteuerung verwenden oder mit einer anderen Fernsteuerung verknüpfen", + "en": "Unable to take off. Failed to verify remote controller. Max number of temporary flights reached. Use bound remote controller or bind to another remote controller", + "es": "No se puede despegar. No se ha podido verificar el control remoto. Se ha alcanzado el número máximo de vuelos temporales. Utiliza el control remoto vinculado o vincula el dispositivo a otro control remoto", + "fr": "Impossible de décoller. Échec de la vérification de la radiocommande. Nombre maximal de vols temporaires atteint. Utilisez la radiocommande associée ou associez l’appareil à une autre radiocommande", + "ja": "離陸できません。送信機の確認に失敗しました。一時的な飛行の最大回数に達しました。紐付けされた送信機を使用するか、別の送信機と紐付けしてください", + "ko": "이륙 불가. 조종기 인증 실패. 임시 비행 횟수 최대 한도에 도달했습니다. 바인딩된 조종기를 사용하거나 다른 조종기에 바인딩하십시오", + "ru": "Не удается выполнить взлет. Не удалось проверить пульт ДУ. Достигнуто максимальное количество временных полетов. Используйте привязанный пульт дистанционного управления или привяжите к другому пульту дистанционного управления", + "tr": "Kalkış yapılamıyor. Uzaktan kumanda onaylanamadı. Maks. geçici uçuş sayısına ulaşıldı. Bağlı uzaktan kumandayı kullanın veya başka bir uzaktan kumandaya bağlanın", + "zh": "无法起飞:遥控器绑定校验失败,临时起飞次数耗尽,请使用绑定遥控器或者换绑" + }, + "fpv_tip_0x161000A7_in_the_sky": { + "de": "Fehler des Flugreglers. Zum Startpunkt zurückkehren oder umgehend landen", + "en": "Flight controller error. Return to home or land promptly", + "es": "Error del controlador de vuelo. Regresa al punto de origen o aterriza cuando antes.", + "fr": "Erreur du contrôleur de vol. Retourner au point de départ ou atterrir rapidement", + "ja": "フライトコントローラーエラー。直ちに帰還するか、着陸してください", + "ko": "비행 컨트롤러 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Ошибка полетного контроллера. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Uçuş kumandası hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "飞控系统异常,请尽快返航或降落" + }, + "fpv_tip_0x161000A9": { + "de": "Propeller im Zeitlupenmodus. Start nicht möglich", + "en": "Propellers in slow motion mode. Unable to take off", + "es": "Hélices en modo Slow Motion. No se puede despegar", + "fr": "Hélices en mode ralenti. Impossible de décoller", + "ja": "プロペラがスローモーションモードです。離陸できません", + "ko": "프로펠러가 슬로 모션 모드에 있음. 이륙 불가", + "ru": "Пропеллеры в замедленном режиме. Не удается выполнить взлет", + "tr": "Pervaneler ağır çekim modunda. Kalkış yapılamıyor", + "zh": "无法起飞:飞行器处于慢转桨模式" + }, + "fpv_tip_0x161000A9_in_the_sky": { + "de": "Propellerbewegungsfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Propeller motion error. Return to home or land promptly", + "es": "Error de movimiento de las hélices. Regrese al punto de origen o aterrice rápidamente", + "fr": "Erreur de mouvement de l'hélice. Retournez au point de départ ou atterrissez rapidement", + "ja": "プロペラのモーションエラー。直ちに帰還するか、着陸してください", + "ko": "프로펠러 모션 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Ошибка движения пропеллера. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Pervane hareket hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "飞行器异常慢转桨,请尽快返航或降落" + }, + "fpv_tip_0x161000AA": { + "de": "GEO-Modulfehler. Start nicht möglich", + "en": "GEO module error. Unable to take off", + "es": "Error del módulo GEO. No se puede despegar", + "fr": "Erreur du module GEO. Impossible de décoller", + "ja": "GEOモジュールエラー。離陸できません", + "ko": "GEO 모듈 오류. 이륙 불가", + "ru": "Ошибка модуля GEO. Не удается выполнить взлет", + "tr": "GEO modülü hatası. Kalkış yapılamıyor", + "zh": "无法起飞:限飞模块组件异常" + }, + "fpv_tip_0x161000AA_in_the_sky": { + "de": "GEO-Modulfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "GEO module error. Return to home or land promptly", + "es": "Error del módulo GEO. Regrese al punto de origen o aterrice rápidamente", + "fr": "Erreur du module GEO. Retournez au point de départ ou atterrissez rapidement", + "ja": "GEOモジュールエラー。直ちに帰還するか、着陸してください", + "ko": "GEO 모듈 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Ошибка модуля GEO. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "GEO modülü hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "限飞模块组件异常,请尽快返航或降落" + }, + "fpv_tip_0x161000AB": { + "de": "FlySafe-Datenbankfehler. Start nicht möglich", + "en": "Fly Safe database error. Unable to take off", + "es": "Error de la base datos VuelaSeguro. No se puede despegar", + "fr": "Erreur de la base de données Fly Safe. Impossible de décoller", + "ja": "安全飛行データベースのエラー。離陸できません", + "ko": "안전 비행 데이터베이스 오류. 이륙 불가", + "ru": "Ошибка базы данных Fly Safe. Не удается выполнить взлет", + "tr": "Güvenli Uçuş veri tabanı hatası. Kalkış yapılamıyor", + "zh": "无法起飞:飞行安全数据库异常" + }, + "fpv_tip_0x161000AB_in_the_sky": { + "de": "FlySafe-Datenbankfehler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Fly Safe database error. Return to home or land promptly", + "es": "Error de la base datos VuelaSeguro. Regrese al punto de origen o aterrice rápidamente", + "fr": "Erreur de la base de données Fly Safe. Retournez au point de départ ou atterrissez rapidement", + "ja": "安全飛行データベースのエラー。直ちに帰還するか、着陸してください", + "ko": "안전 비행 데이터베이스 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Ошибка базы данных Fly Safe. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Güvenli Uçuş veri tabanı hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "飞行安全数据库异常,请尽快返航或降落" + }, + "fpv_tip_0x161000AC": { + "de": "Fehler: Flugregler. Start nicht möglich", + "en": "Flight control system error. Unable to take off", + "es": "Error en el sistema de control de vuelo. No se puede despegar", + "fr": "Erreur du système de contrôle du vol. Impossible de décoller", + "ja": "フライトコントロールシステムのエラー。離陸できません", + "ko": "비행 제어 시스템 오류. 이륙 불가", + "ru": "Ошибка системы управления полетом. Не удается выполнить взлет", + "tr": "Uçuş kontrol sistemi hatası. Kalkış yapılamıyor", + "zh": "无法起飞:飞控系统异常" + }, + "fpv_tip_0x161000AC_in_the_sky": { + "de": "Fehler: Flugregler. Umgehend landen", + "en": "Flight control system error. Land promptly", + "es": "Error en el sistema de control de vuelo. Aterriza rápidamente", + "fr": "Erreur du système de contrôle du vol. Atterrissez immédiatement.", + "ja": "フライトコントロールシステムのエラー。直ちに着陸してください", + "ko": "비행 제어 시스템 오류. 즉시 착륙해주세요.", + "ru": "Ошибка системы управления полетом. Немедленно выполните посадку", + "tr": "Uçuş kontrol sistemi hatası. Derhal iniş yapın", + "zh": "飞控系统异常,请尽快降落" + }, + "fpv_tip_0x161000AF": { + "de": "Flugsteuerungssystem wird initialisiert. Start nicht möglich", + "en": "Initializing flight control system. Unable to take off", + "es": "Iniciando el sistema controlador de vuelo. No se puede despegar", + "fr": "Initialisation du système de contrôle du vol. Impossible de décoller", + "ja": "フライトコントロールシステムを初期化中です。離陸できません", + "ko": "비행 제어 시스템 초기화 중. 이륙 불가", + "ru": "Инициализация системы управления полетом. Не удается выполнить взлет", + "tr": "Uçuş kontrol sistemi başlatılıyor. Kalkış yapılamıyor", + "zh": "无法起飞:飞控系统初始化中" + }, + "fpv_tip_0x161000AF_in_the_sky": { + "de": "Initialisierungsfehler bei Flugsteuerungssystem. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Flight control system initialization error. Return to home or land promptly", + "es": "Error de inicio del sistema controlador de vuelo. Regrese al punto de origen o aterrice rápidamente", + "fr": "Erreur d'initialisation du système de contrôle du vol. Retournez au point de départ ou atterrissez rapidement", + "ja": "フライトコントロールシステムの初期化エラー。直ちに帰還するか、着陸してください", + "ko": "비행 제어 시스템 초기화 오류. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Ошибка инициализации системы управления полетом. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Uçuş kontrol sistemi başlatma hatası. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "飞控系统异常初始化,请尽快返航或降落" + }, + "fpv_tip_0x161000B1": { + "de": "Statusfehler Landegestell. Automatische Verriegelung des Landegestells aufheben und Taste „Transform“ drücken, um das Landegestell zurückzusetzen.", + "en": "Landing gear status error. Try to release Landing Gear Auto Lock and press the transform button to reset the landing gear", + "es": "Error de estado del tren de aterrizaje. Pruebe a liberar el bloqueo automático del tren de aterrizaje y pulse el botón de transformación para restablecer el tren de aterrizaje", + "fr": "Erreur de statut du train d’atterrissage. Essayer de relâcher le verrouillage automatique du train d'atterrissage et appuyer sur le bouton de transformation pour réinitialiser le train d'atterrissage", + "ja": "ランディングギアの状態エラー。ランディングギアの自動ロックを解除し、変形ボタンを押して、ランディングギアをリセットしてみてください", + "ko": "랜딩 기어 상태 오류. 랜딩 기어 자동 잠금을 해제하고 변속 버튼을 눌러 랜딩 기어를 재설정하세요.", + "ru": "Ошибка статуса шасси. Попробуйте отключить автоматическую блокировку шасси и нажмите кнопку трансформации, чтобы выполнить сброс шасси", + "tr": "İniş takımı durumu hatası. İniş Takımları Otomatik Kilitlemesini serbest bırakmayı deneyin ve iniş takımlarını sıfırlamak için değiştirme düğmesine basın", + "zh": "起落架状态异常,请尝试解除起落架锁定,并点击变形按键尝试复位" + }, + "fpv_tip_0x161000B1_in_the_sky": { + "de": "Statusfehler Landegestell. Taste „Transform“ drücken, um das Landegestell zurückzusetzen.", + "en": "Landing gear status error. Try to press the transform button to reset the landing gear", + "es": "Error de estado del tren de aterrizaje. Pruebe a pulsar el botón de transformación para restablecer el tren de aterrizaje", + "fr": "Erreur de statut du train d’atterrissage. Essayer d'appuyer sur le bouton de transformation pour réinitialiser le train d'atterrissage", + "ja": "ランディングギアの状態エラー。変形ボタンを押してランディングギアをリセットしてみてください", + "ko": "랜딩 기어 상태 오류. 변속 버튼을 눌러 랜딩 기어를 재설정하세요.", + "ru": "Ошибка статуса шасси. Попробуйте нажать кнопку трансформации, чтобы выполнить сброс шасси", + "tr": "İniş takımı durumu hatası. İniş takımlarını sıfırlamak için değiştirme düğmesine basmayı deneyin", + "zh": "起落架状态异常,请尝试点击变形按键复位" + }, + "fpv_tip_0x161000B2": { + "de": "Start nicht möglich. Landegestell wird transformiert...", + "en": "Unable to take off. Landing gear transforming...", + "es": "No se puede despegar. Transformando el tren de aterrizaje...", + "fr": "Impossible de décoller. Transformation du train d’atterrissage en cours...", + "ja": "離陸できません。ランディングギアの変形中...", + "ko": "이륙 불가. 랜딩 기어 변속 중...", + "ru": "Не удается выполнить взлет. Трансформация шасси...", + "tr": "Kalkış yapılamıyor. İniş takımları değişiyor...", + "zh": "无法起飞:起落架变形中" + }, + "fpv_tip_0x161000B3": { + "de": "Start nicht möglich. Landegestell im Transportmodus. Gimbal-Kamera zum Transformieren entfernen", + "en": "Unable to take off. Landing gear in Travel mode. Remove gimbal camera to transform", + "es": "No se puede despegar. Tren de aterrizaje en modo Viaje. Retire la cámara del estabilizador para la transformación", + "fr": "Impossible de décoller. Train d’atterrissage en mode Transport. Retirer la caméra de la nacelle pour transformation", + "ja": "離陸できません。ランディングギアがトラベルモード。ジンバルカメラを取り外して変形させてください", + "ko": "이륙 불가. 랜딩 기어가 트래블 모드에 있습니다. 변속을 위해 짐벌 카메라를 제거하세요", + "ru": "Не удается выполнить взлет. Шасси в режиме движения. Снимите камеру с гиростабилизатором для трансформации", + "tr": "Kalkış yapılamıyor. İniş takımı seyahat modunda. Dönüştürmek için gimbal kamerasını çıkarın", + "zh": "无法起飞:起落架已进入运输模式,等待摘除云台" + }, + "fpv_tip_0x161000B4": { + "ar": "", + "de": "", + "en": "Remote ID broadcast error. Failed to obtain remote controller location. Unable to take off", + "es": "", + "fr": "", + "it": "", + "ja": "", + "ko": "", + "pt": "", + "ru": "", + "tr": "", + "zh": "无法起飞:Remote ID 播报异常,无法获取遥控器位置" + }, + "fpv_tip_0x161000B5": { + "ar": "", + "de": "", + "en": "Remote ID module error. Unable to take off. Contact DJI Support", + "es": "", + "fr": "", + "it": "", + "ja": "", + "ko": "", + "pt": "", + "ru": "", + "tr": "", + "zh": "无法起飞,Remote ID 模块异常,请联系售后服务" + }, + "fpv_tip_0x161000B6": { + "ar": "", + "de": "", + "en": "Average battery power output too low. Unable to take off. Reduce payload or replace with fully charged batteries", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "无法起飞:电池平均功率过低,请降低载重或更换满电电池", + "zh-Hant": "" + }, + "fpv_tip_0x161000B7": { + "en": "Payload exceeded max allowable weight. Reduce payload or fully charge battery", + "zh": "已超最大允许载重,请降低载重或补充至满电" + }, + "fpv_tip_0x161000B7_in_the_sky": { + "en": "Payload exceeded max allowable weight. Return to home or land promptly", + "zh": "已超最大允许载重,请尽快返航或降落" + }, + "fpv_tip_0x161000B8": { + "ar": "", + "de": "", + "en": "Obstacle detected near aircraft. Unable to take off", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "无法起飞:飞行器周围有障碍物", + "zh-Hant": "" + }, + "fpv_tip_0x161000BD": { + "ar": "", + "de": "", + "en": "Parachute built-in battery voltage too low. Unable to take off", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "电池温度过高,无法起飞", + "zh-Hant": "" + }, + "fpv_tip_0x161000BE": { + "ar": "", + "de": "", + "en": "Incompatible battery models. Unable to take off", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "无法起飞:电池类型不匹配", + "zh-Hant": "" + }, + "fpv_tip_0x161000BF": { + "ar": "", + "de": "", + "en": "Single battery flight not enabled. Unable to take off", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "无法起飞:单电池模式未打开", + "zh-Hant": "" + }, + "fpv_tip_0x161000C0": { + "de": "Start nicht möglich. Gimbal-Kamera mit derzeitiger Befestigung wird nicht unterstützt. Firmware des Fluggeräts aktualisieren", + "en": "Unable to take off. Gimbal camera with current mount not supported. Update aircraft firmware", + "es": "No se puede despegar. Montura actual de la cámara con estabilizador no compatible. Actualizar firmware de la aeronave", + "fr": "Impossible de décoller. La caméra de la nacelle avec le support actuel n’est pas prise en charge. Mettre à jour le firmware de l’appareil", + "ja": "離陸できません。現在のマウントでのジンバルカメラには対応していません。機体のファームウェアを更新してください", + "ko": "이륙 불가. 현재 마운트의 짐벌 카메라는 지원되지 않습니다. 기체 펌웨어를 업데이트하세요", + "ru": "Не удается выполнить взлет. Камера с гиростабилизатором с текущим креплением не поддерживается. Обновите прошивку дрона", + "tr": "Kalkış yapılamıyor. Geçerli montajlı gimbal kamerası desteklenmiyor. Hava aracı ürün yazılımını güncelleyin", + "zh": "无法起飞:不支持当前卡口云台,请升级飞行器固件" + }, + "fpv_tip_0x161000C4": { + "de": "Start nicht möglich. Automatische ESC-Prüfung läuft ...", + "en": "Unable to take off. Auto checking ESC...", + "es": "No se puede despegar. Comprobando automáticamente ESC...", + "fr": "Impossible de décoller. Vérification automatique ESC en cours", + "ja": "離陸できません。ESCを自動確認中...", + "ko": "이륙 불가. ESC 자동 확인 중...", + "ru": "Не удается выполнить взлет. Автоматическая проверка ESC...", + "tr": "Kalkış yapılamıyor. ESC otomatik olarak kontrol ediliyor...", + "zh": "无法起飞:电调自检中" + }, + "fpv_tip_0x161000C7": { + "de": "Akkutemperatur unter 10 °C. Start nicht möglich", + "en": "Battery temperature lower than 10°C. Unable to take off", + "es": "Temperatura de la batería inferior a 10 °C. No se puede despegar", + "fr": "Température de la batterie inférieure à 10 °C. Impossible de décoller", + "ja": "バッテリー温度が10℃未満です。離陸できません", + "ko": "배터리 온도가 10°C 미만입니다. 이륙 불가", + "ru": "Температура аккумулятора ниже 10 °C. Не удается выполнить взлет", + "tr": "Pil sıcaklığı 10 °C'den düşük. Kalkış yapılamıyor", + "zh": "无法起飞:电池温度低于10度" + }, + "fpv_tip_0x161000C7_in_the_sky": { + "de": "Akkutemperatur unter 10 °C. Umgehend zum Startpunkt zurückkehren oder landen.", + "en": "Battery temperature lower than 10°C. Return to home or land promptly", + "es": "Temperatura de la batería inferior a 10 °C. Regresa al punto de origen o aterriza rápidamente", + "fr": "Température de la batterie inférieure à 10 °C. Retournez au point de départ ou atterrissez rapidement", + "ja": "バッテリー温度が10℃未満です。直ちに帰還するか、着陸してください", + "ko": "배터리 온도가 10°C 미만입니다. 즉시 리턴 투 홈을 실행하거나 착륙하세요.", + "ru": "Температура аккумулятора ниже 10 °C. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Pil sıcaklığı 10 °C'den düşük. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "电池温度低于10度,尽快返航或降落" + }, + "fpv_tip_0x161000C8": { + "de": "Start fehlgeschlagen.Überprüfen, ob das Fluggerät mit dem DJI Assistant verbunden ist oder gerade aktualisiert wird.", + "en": "Unable to take off. Check whether aircraft is connected to DJI Assistant or system is updating", + "es": "No se puede despegar. Comprueba si la aeronave está conectada a DJI Assistant o si el sistema se está actualizando", + "fr": "Impossible de décoller. Vérifiez si l\\'appareil est connecté à DJI Assistant ou si une mise à jour est en cours", + "ja": "離陸できません。機体がDJI Assistantに接続されているか、またはシステムが更新中か確認してください", + "ko": "이륙 불가. 기체가 DJI Assistant에 연결 또는 시스템 업데이트 상태 확인 필요", + "ru": "Не удалось взлететь. Нарушено соединение DJI Assistant с дроном либо идет обновление системы", + "tr": "Kalkış yapamıyor. Aracın DJI Assistant’a bağlı olup olmadığını veya sistem güncellemesinin devam edip etmediğini kontrol edin", + "zh": "无法起飞:请确认usb是否已连接或者系统正在升级中" + }, + "fpv_tip_0x161000C8_in_the_sky": { + "de": "Überprüfen, ob das Fluggerät mit dem DJI Assistant verbunden ist oder das System aktualisiert wird.", + "en": "Check whether aircraft is connected to DJI Assistant or system is updating", + "es": "Comprueba si la aeronave está conectada a DJI Assistant o si el sistema se está actualizando", + "fr": "Vérifiez si l\\'appareil est connecté à DJI Assistant ou si une mise à jour est en cours", + "ja": "機体がDJI Assistantに接続されているか、またはシステムが更新中か確認してください", + "ko": "기체가 DJI Assistant에 연결되었는지 또는 시스템 업데이트 상태 확인 필요", + "ru": "Проверьте, не подключен ли дрон к DJI Assistant или не обновляется ли система", + "tr": "Aracın DJI Assistant’a bağlı olup olmadığını veya sistem güncellemesinin devam edip etmediğini kontrol edin", + "zh": "请确认usb是否已连接或者系统正在升级中" + }, + "fpv_tip_0x161000C9": { + "de": "Start nicht möglich. Überprüfen, ob das Fluggerät mit dem DJI Assistant verbunden ist oder das System aktualisiert wird.", + "en": "Unable to take off. Check whether aircraft is connected to DJI Assistant or system is updating", + "es": "No se puede despegar. Comprueba si la aeronave está conectada a DJI Assistant o si el sistema se está actualizando", + "fr": "Impossible de décoller. Vérifiez si l\\'appareil est connecté à DJI Assistant ou si une mise à jour est en cours", + "ja": "離陸できません。機体がDJI Assistantに接続されているか、またはシステムが更新中か確認してください", + "ko": "이륙 불가. 기체가 DJI Assistant에 연결되었는지 또는 시스템 업데이트 상태 확인 필요", + "ru": "Невозможно выполнить взлет. Проверьте, не подключен ли дрон к DJI Assistant или не обновляется ли система", + "tr": "Kalkış yapamıyor. Aracın DJI Assistant’a bağlı olup olmadığını veya sistem güncellemesinin devam edip etmediğini kontrol edin", + "zh": "无法起飞:请确认usb是否已连接或者系统正在升级中" + }, + "fpv_tip_0x161000C9_in_the_sky": { + "de": "Überprüfen, ob das Fluggerät mit dem DJI Assistant verbunden ist oder das System aktualisiert wird.", + "en": "Check whether aircraft is connected to DJI Assistant or system is updating", + "es": "Comprueba si la aeronave está conectada a DJI Assistant o si el sistema se está actualizando", + "fr": "Vérifiez si l\\'appareil est connecté à DJI Assistant ou si une mise à jour est en cours", + "ja": "機体がDJI Assistantに接続されているか、またはシステムが更新中か確認してください", + "ko": "기체가 DJI Assistant에 연결되었는지 또는 시스템 업데이트 상태 확인 필요", + "ru": "Проверьте, не подключен ли дрон к DJI Assistant или не обновляется ли система", + "tr": "Aracın DJI Assistant’a bağlı olup olmadığını veya sistem güncellemesinin devam edip etmediğini kontrol edin", + "zh": "请确认usb是否已连接或者系统正在升级中" + }, + "fpv_tip_0x161000F1": { + "de": "Start nicht möglich. Überprüfen, ob der vordere rechte Rahmenausleger vollständig auseinandergefaltet ist", + "en": "Unable to take off. Check whether front right frame arm is fully unfolded", + "es": "No se puede despegar. Compruebe si el brazo del bastidor delantero derecho está completamente desplegado", + "fr": "Impossible de décoller. Vérifiez si le bras avant droit est complètement déplié", + "it": "", + "ja": "離陸できません。右前フレームアームが完全に展開されているかを確認してください", + "ko": "이륙 불가. 전방 우측 프레임 암이 완전히 펼쳐졌는지 점검하세요.", + "pt": "", + "ru": "Не удается выполнить взлет. Проверьте, полностью ли разложен передний правый рычаг рамы.", + "tr": "Kalkış yapılamıyor. Ön sağ çerçeve kolunun tamamen açılıp açılmadığını kontrol edin", + "zh": "无法起飞:请检查右前机臂是否展开并固定到位" + }, + "fpv_tip_0x161000F1_in_the_sky": { + "de": "Fehler: vorderer rechter Rahmenausleger. Umgehend landen", + "en": "Front right frame arm error. Land promptly", + "es": "Error del brazo del bastidor delantero derecho. Aterriza rápidamente", + "fr": "Erreur de bras avant droit. Atterrissez immédiatement.", + "it": "", + "ja": "右前フレームアームのエラー。直ちに着陸してください", + "ko": "전방 우측 프레임 암 오류. 즉시 착륙해주세요.", + "pt": "", + "ru": "Ошибка переднего правого рычага рамы. Немедленно выполните посадку", + "tr": "Ön sağ çerçeve kolu hatası. Derhal iniş yapın", + "zh": "右前机臂异常,请尽快降落" + }, + "fpv_tip_0x161000F2": { + "de": "Start nicht möglich. Überprüfen, ob der vordere linke Rahmenausleger vollständig auseinandergefaltet ist", + "en": "Unable to take off. Check whether front left frame arm is fully unfolded", + "es": "No se puede despegar. Compruebe si el brazo del bastidor delantero izquierdo está completamente desplegado", + "fr": "Impossible de décoller. Vérifiez si le bras avant gauche est complètement déplié", + "it": "", + "ja": "離陸できません。左前フレームアームが完全に展開されているかを確認してください", + "ko": "이륙 불가. 전방 좌측 프레임 암이 완전히 펼쳐졌는지 점검하세요.", + "pt": "", + "ru": "Не удается выполнить взлет. Проверьте, полностью ли разложен передний левый рычаг рамы.", + "tr": "Kalkış yapılamıyor. Ön sol çerçeve kolunun tamamen açılıp açılmadığını kontrol edin", + "zh": "无法起飞:请检查左前机臂是否展开并固定到位" + }, + "fpv_tip_0x161000F2_in_the_sky": { + "de": "Fehler: vorderer linker Rahmenausleger. Umgehend landen", + "en": "Front left frame arm error. Land promptly", + "es": "Error del brazo del bastidor delantero izquierdo. Aterriza rápidamente", + "fr": "Erreur de bras avant gauche. Atterrissez immédiatement.", + "it": "", + "ja": "左前フレームアームのエラー。直ちに着陸してください", + "ko": "전방 좌측 프레임 암 오류. 즉시 착륙해주세요.", + "pt": "", + "ru": "Ошибка переднего левого рычага рамы. Немедленно выполните посадку", + "tr": "Ön sol çerçeve kolu hatası. Derhal iniş yapın", + "zh": "左前机臂异常,请尽快降落" + }, + "fpv_tip_0x161000F3": { + "de": "Start nicht möglich. Überprüfen, ob der hintere linke Rahmenausleger vollständig auseinandergefaltet ist", + "en": "Unable to take off. Check whether back left frame arm is fully unfolded", + "es": "No se puede despegar. Compruebe si el brazo del bastidor trasero izquierdo está completamente desplegado", + "fr": "Impossible de décoller. Vérifiez si le bras arrière gauche est complètement déplié", + "it": "", + "ja": "離陸できません。左後フレームアームが完全に展開されているかを確認してください", + "ko": "이륙 불가. 후방 좌측 프레임 암이 완전히 펼쳐졌는지 점검하세요.", + "pt": "", + "ru": "Не удается выполнить взлет. Проверьте, полностью ли разложен задний левый рычаг рамы.", + "tr": "Kalkış yapılamıyor. Arka sol çerçeve kolunun tamamen açılıp açılmadığını kontrol edin", + "zh": "无法起飞:请检查左后机臂是否展开并固定到位" + }, + "fpv_tip_0x161000F3_in_the_sky": { + "de": "Fehler: hinterer linker Rahmenausleger. Umgehend landen", + "en": "Back left frame arm error. Land promptly", + "es": "Error del brazo del bastidor trasero izquierdo. Aterriza rápidamente", + "fr": "Erreur de bras avant gauche arrière. Atterrissez immédiatement.", + "it": "", + "ja": "左後フレームアームのエラー。直ちに着陸してください", + "ko": "후방 좌측 프레임 암 오류. 즉시 착륙해주세요.", + "pt": "", + "ru": "Ошибка заднего левого рычага рамы. Немедленно выполните посадку", + "tr": "Arka sol çerçeve kolu hatası. Derhal iniş yapın", + "zh": "左后机臂异常,请尽快降落" + }, + "fpv_tip_0x161000F4": { + "de": "Start nicht möglich. Überprüfen, ob der hintere rechte Rahmenausleger vollständig auseinandergefaltet ist", + "en": "Unable to take off. Check whether back right frame arm is fully unfolded", + "es": "No se puede despegar. Compruebe si el brazo del bastidor trasero derecho está completamente desplegado", + "fr": "Impossible de décoller. Vérifiez si le bras arrière droit est complètement déplié", + "it": "", + "ja": "離陸できません。右後フレームアームが完全に展開されているかを確認してください", + "ko": "이륙 불가. 후방 우측 프레임 암이 완전히 펼쳐졌는지 점검하세요.", + "pt": "", + "ru": "Не удается выполнить взлет. Проверьте, полностью ли разложен задний правый рычаг рамы.", + "tr": "Kalkış yapılamıyor. Arka sağ çerçeve kolunun tamamen açılıp açılmadığını kontrol edin", + "zh": "无法起飞:请检查右后机臂是否展开并固定到位" + }, + "fpv_tip_0x161000F4_in_the_sky": { + "de": "Fehler: hinterer rechter Rahmenausleger. Umgehend landen", + "en": "Back right frame arm error. Land promptly", + "es": "Error del brazo del bastidor trasero derecho. Aterriza rápidamente", + "fr": "Erreur de bras avant droit arrière. Atterrissez immédiatement.", + "it": "", + "ja": "右後フレームアームのエラー。直ちに着陸してください", + "ko": "후방 우측 프레임 암 오류. 즉시 착륙해주세요.", + "pt": "", + "ru": "Ошибка заднего правого рычага рамы. Немедленно выполните посадку", + "tr": "Arka sağ çerçeve kolu hatası. Derhal iniş yapın", + "zh": "右后机臂异常,请尽快降落" + }, + "fpv_tip_0x161000F5": { + "de": "Fehler: Flugregler. Start nicht möglich", + "en": "Flight control system error. Unable to take off", + "es": "Error en el sistema de control de vuelo. No se puede despegar", + "fr": "Erreur du système de contrôle du vol. Impossible de décoller", + "ja": "フライトコントロールシステムのエラー。離陸できません", + "ko": "비행 제어 시스템 오류. 이륙 불가", + "ru": "Ошибка системы управления полетом. Не удается выполнить взлет", + "tr": "Uçuş kontrol sistemi hatası. Kalkış yapılamıyor", + "zh": "无法起飞:飞控系统异常" + }, + "fpv_tip_0x161000F5_in_the_sky": { + "de": "Fehler: Flugregler. Umgehend landen", + "en": "Flight control system error. Land promptly", + "es": "Error en el sistema de control de vuelo. Aterriza rápidamente", + "fr": "Erreur du système de contrôle du vol. Atterrissez immédiatement.", + "ja": "フライトコントロールシステムのエラー。直ちに着陸してください", + "ko": "비행 제어 시스템 오류. 즉시 착륙해주세요.", + "ru": "Ошибка системы управления полетом. Немедленно выполните посадку", + "tr": "Uçuş kontrol sistemi hatası. Derhal iniş yapın", + "zh": "飞控系统异常,请尽快降落" + }, + "fpv_tip_0x161000F6": { + "de": "Fehler: Flugregler. Start nicht möglich", + "en": "Flight control system error. Unable to take off", + "es": "Error en el sistema de control de vuelo. No se puede despegar", + "fr": "Erreur du système de contrôle du vol. Impossible de décoller", + "ja": "フライトコントロールシステムのエラー。離陸できません", + "ko": "비행 제어 시스템 오류. 이륙 불가", + "ru": "Ошибка системы управления полетом. Не удается выполнить взлет", + "tr": "Uçuş kontrol sistemi hatası. Kalkış yapılamıyor", + "zh": "无法起飞:飞控系统异常" + }, + "fpv_tip_0x161000F6_in_the_sky": { + "de": "Fehler: Flugregler. Umgehend landen", + "en": "Flight control system error. Land promptly", + "es": "Error en el sistema de control de vuelo. Aterriza rápidamente", + "fr": "Erreur du système de contrôle du vol. Atterrissez immédiatement.", + "ja": "フライトコントロールシステムのエラー。直ちに着陸してください", + "ko": "비행 제어 시스템 오류. 즉시 착륙해주세요.", + "ru": "Ошибка системы управления полетом. Немедленно выполните посадку", + "tr": "Uçuş kontrol sistemi hatası. Derhal iniş yapın", + "zh": "飞控系统异常,请尽快降落" + }, + "fpv_tip_0x161000F7": { + "ar": "", + "de": "Initialisierung des Sensorsystems läuft", + "en": "Sensor system initialization in progress", + "es": "Inicio de sistema de sensores en curso", + "fr": "Initialisation du système de capteurs en cours", + "it": "", + "ja": "センサーシステムを初期中", + "ko": "센서 시스템 초기화 진행 중", + "pt": "", + "ru": "Выполняется инициализация сенсорной системы", + "tr": "Sensör sistemi başlatma işlemi devam ediyor", + "zh": "无法起飞:感知系统初始化中" + }, + "fpv_tip_0x161000F7_in_the_sky": { + "ar": "", + "de": "Fehler: Sensorsystem. Umgehend landen oder mit Vorsicht fliegen", + "en": "Sensor system error. Land promptly or fly with caution", + "es": "Error del sistema de sensores. Aterriza rápidamente o vuela con cuidado", + "fr": "Erreur du système de capteurs. Atterrissez rapidement ou pilotez avec précaution", + "it": "", + "ja": "センサーシステムのエラー。直ちに着陸するか、慎重に飛行してください", + "ko": "센서 시스템 오류. 즉시 착륙 또는 비행 시 주의 필요", + "pt": "", + "ru": "Ошибка системы датчиков. Немедленно выполните посадку или соблюдайте осторожность при полете", + "tr": "Sensör sistem hatası. Derhal iniş yapın veya aracı dikkatli uçurun", + "zh": "感知系统异常,请尽快降落或谨慎飞行" + }, + "fpv_tip_0x161000F8": { + "ar": "", + "de": "Initialisierung des Sensorsystems läuft", + "en": "Sensor system initialization in progress", + "es": "Inicio de sistema de sensores en curso", + "fr": "Initialisation du système de capteurs en cours", + "it": "", + "ja": "センサーシステムを初期中", + "ko": "센서 시스템 초기화 진행 중", + "pt": "", + "ru": "Выполняется инициализация сенсорной системы", + "tr": "Sensör sistemi başlatma işlemi devam ediyor", + "zh": "无法起飞:感知系统初始化中" + }, + "fpv_tip_0x161000F8_in_the_sky": { + "ar": "", + "de": "Fehler: Sensorsystem. Umgehend landen", + "en": "Sensor system error. Land promptly", + "es": "Error del sistema de sensores. Aterriza rápidamente", + "fr": "Erreur du système de capteurs. Atterrissez immédiatement.", + "it": "", + "ja": "センサーシステムエラー。直ちに着陸してください", + "ko": "센서 시스템 오류. 즉시 착륙해주세요.", + "pt": "", + "ru": "Ошибка системы датчиков. Немедленно выполните посадку", + "tr": "Sensör sistemi hatası. Derhal iniş yapın", + "zh": "感知系统异常,请尽快降落" + }, + "fpv_tip_0x161000F9": { + "de": "Start nicht möglich. Schwaches Fernsteuerungssignal. In der Nähe der Fernsteuerung starten", + "en": "Unable to take off. Remote controller signal weak. Take off near remote controller", + "es": "No se puede despegar. Señal del control remoto débil. Despega cerca del control remoto.", + "fr": "Impossible de décoller. Le signal de la radiocommande est faible. Décollez près de la radiocommande", + "ja": "離陸できません。送信機信号 弱。送信機の近くで離陸してください", + "ko": "이륙 불가. 조종기 신호 약함. 조종기 근처에서 이륙하세요.", + "ru": "Не удается выполнить взлет. Слабый сигнал пульта управления. Взлетайте рядом с пультом дистанционного управления", + "tr": "Kalkış yapılamıyor. Uzaktan kumanda sinyali zayıf. Uzaktan kumandanın yanında kalkış yapın", + "zh": "无法起飞:遥控器信号弱,开启增强图传后请靠近飞行器起飞" + }, + "fpv_tip_0x161000F9_in_the_sky": { + "de": "Fehler: Flugregler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Flight controller error. Return to home or land promptly", + "es": "Error del controlador de vuelo. Regresa al punto de origen o aterriza rápidamente.", + "fr": "Erreur du contrôleur de vol. Revenez au point de départ ou atterrissez rapidement", + "ja": "フライトコントローラーエラー。直ちにホームに帰還するか着陸してください", + "ko": "비행 컨트롤러 오류. 즉시 홈으로 돌아가거나 착륙하세요.", + "ru": "Ошибка полетного контроллера. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Uçuş kontrol sistemi hatası. Derhal başlangıç noktasına geri dönün veya iniş yapın", + "zh": "飞控系统异常,请尽快返航或降落" + }, + "fpv_tip_0x161000FA": { + "de": "Start nicht möglich. Schwaches Fernsteuerungssignal. In der Nähe der Fernsteuerung starten", + "en": "Unable to take off. Remote controller signal weak. Take off near remote controller", + "es": "No se puede despegar. Señal del control remoto débil. Despega cerca del control remoto.", + "fr": "Impossible de décoller. Le signal de la radiocommande est faible. Décollez près de la radiocommande", + "ja": "離陸できません。送信機信号 弱。送信機の近くで離陸してください", + "ko": "이륙 불가. 조종기 신호 약함. 조종기 근처에서 이륙하세요.", + "ru": "Не удается выполнить взлет. Слабый сигнал пульта управления. Взлетайте рядом с пультом дистанционного управления", + "tr": "Kalkış yapılamıyor. Uzaktan kumanda sinyali zayıf. Uzaktan kumandanın yanında kalkış yapın", + "zh": "无法起飞:遥控器信号弱,开启增强图传后请靠近飞行器起飞" + }, + "fpv_tip_0x161000FA_in_the_sky": { + "de": "Fehler: Flugregler. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Flight controller error. Return to home or land promptly", + "es": "Error del controlador de vuelo. Regresa al punto de origen o aterriza rápidamente.", + "fr": "Erreur du contrôleur de vol. Revenez au point de départ ou atterrissez rapidement", + "ja": "フライトコントローラーエラー。直ちにホームに帰還するか着陸してください", + "ko": "비행 컨트롤러 오류. 즉시 홈으로 돌아가거나 착륙하세요.", + "ru": "Ошибка полетного контроллера. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Uçuş kontrol sistemi hatası. Derhal başlangıç noktasına geri dönün veya iniş yapın", + "zh": "飞控系统异常,请尽快返航或降落" + }, + "fpv_tip_0x161000FB": { + "ar": "", + "de": "Start nicht möglich. Propeller beschädigt. DJI Support kontaktieren.", + "en": "Unable to take off. Propeller damaged. Contact DJI Support", + "es": "No se puede despegar. Hélice dañada. Póngase en contacto con la Asistencia técnica de DJI", + "fr": "Impossible de décoller. Hélice endommagée. Contactez le service client DJI", + "id": "", + "it": "", + "ja": "離陸できません。プロペラが破損しています。DJIサポートまでお問い合わせください", + "ko": "이륙 불가. 프로펠러가 손상되었습니다. DJI 고객지원으로 문의하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Не удается выполнить взлет. Пропеллер поврежден. Свяжитесь со службой поддержки DJI", + "th": "", + "tr": "Kalkış yapılamıyor. Pervane hasar gördü. DJI Destek birimiyle iletişime geçin", + "ug": "", + "vi": "", + "zh": "无法起飞:桨叶损坏,请联系售后服务", + "zh-Hant": "" + }, + "fpv_tip_0x161000FC": { + "ar": "", + "de": "Start nicht möglich. Standortauswahl von DJI Dock läuft", + "en": "Unable to take off. DJI Dock in site selection process", + "es": "No se puede despegar. DJI Dock en el proceso de selección del sitio", + "fr": "Impossible de décoller. DJI Dock dans le processus de sélection du site", + "id": "", + "it": "", + "ja": "離陸できません。DJI Dockがサイトを選択中です", + "ko": "이륙 불가. DJI Dock이 장소 선택 중입니다", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Не удается выполнить взлет. DJI Dock в процессе выбора площадки", + "th": "", + "tr": "Kalkış yapılamıyor. Yer seçimi sürecinde DJI Dock", + "ug": "", + "vi": "", + "zh": "无法起飞:机场选址中", + "zh-Hant": "" + }, + "fpv_tip_0x161000FD": { + "de": "Abheben nicht möglich. Fluggerät befindet sich außerhalb des benutzerdefinierten Aufgabenbereichs oder näher als 10 Meter an der Bereichsgrenze", + "en": "Unable to take off. Aircraft is outside of custom task area or within 10 meters of the area boundary", + "es": "No se puede despegar. La aeronave se encuentra fuera del área de tareas personalizada o a menos de 10 metros del límite del área", + "fr": "Décollage impossible. L'appareil se trouve en dehors de la zone d'intervention personnalisée ou à moins de 10 mètres de la limite de la zone", + "ja": "離陸できません。航空機は、カスタム作業エリア外にあるか、またはエリア境界から10メートル以内にあります", + "ko": "이륙 불가. 비행체가 맞춤 작업 영역 밖이거나 영역 경계선의 10미터 이내에 있습니다.", + "ru": "Взлет невозможен. Дрон находится за пределами настроенного пользователем участка выполняемого задания или в пределах 10 метров от границы участка", + "tr": "Kalkış yapılamıyor. Uçak, özel görev alanının dışında veya alan sınırının 10 metre yakınında", + "zh": "无法起飞,请在自定义作业区内或远离边界10m以上" + }, + "fpv_tip_0x161000FD_in_the_sky": { + "de": "Aufgabe im benutzerdefinierten Einsatzgebiet ausführen", + "en": "Execute task in custom task area", + "es": "Ejecutar trabajo en la zona de trabajo personalizada", + "fr": "Exécuter la tâche dans la zone de tâche personnalisée", + "ja": "カスタムタスクエリアでタスクを実行してください", + "ko": "맞춤 설정 작업 영역에서 작업을 실행하세요.", + "ru": "Выполните задачу в пользовательской области задач", + "tr": "Görevi özel görev alanında yürütün", + "zh": "请在自定义作业区内作业" + }, + "fpv_tip_0x161000a1": { + "de": "Umgehend landen und prüfen, ob die Rahmenarm-Hülse ordnungsgemäß befestigt ist.", + "en": "Unable to take off. Check whether frame arm sleeves are tightened securely", + "es": "No se puede despegar. Comprueba si las fundas del brazo del bastidor están bien apretadas", + "fr": "Atterrissez rapidement et vérifiez si les manchons des bras du châssis sont bien serrés", + "ja": "直ちに着陸し、フレームアームスリーブがしっかりと固定されているかを確認してください", + "ko": "즉시 착륙하여 프레임 암 슬리브가 단단히 조여졌는지 확인하세요.", + "ru": "", + "tr": "", + "zh": "无法起飞:请检查机臂套筒是否固定到位" + }, + "fpv_tip_0x161000a2": { + "ar": "", + "de": "Fehler: unterer Lüfter. Start nicht möglich. Überprüfen, ob der untere Lüfter blockiert ist", + "en": "Lower fan error. Unable to take off. Check whether lower fan is stalled", + "es": "Error del ventilador inferior. No se puede despegar. Compruebe si el ventilador inferior está atascado", + "fr": "Erreur du ventilateur inférieur. Impossible de décoller. Vérifiez si le ventilateur inférieur est bloqué", + "id": "", + "it": "", + "ja": "下部ファンエラー。離陸できません。下部ファンが停止していないかを確認してください", + "ko": "하단 팬 오류입니다. 이륙 불가. 하단 팬이 멈췄는지 확인하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка нижнего вентилятора. Не удается выполнить взлет. Убедитесь, что нижний вентилятор не заклинило", + "th": "", + "tr": "Alt fan hatası. Kalkış yapılamıyor. Alt fanın arızalanarak durup durmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "无法起飞:下风扇异常,请检查飞行器下风扇是否有堵转", + "zh-Hant": "" + }, + "fpv_tip_0x161000a2_in_the_sky": { + "ar": "", + "de": "Fehler: unterer Lüfter. Zum Startpunkt zurückkehren oder landen. Überprüfen, ob der untere Lüfter blockiert ist", + "en": "Lower fan error. Return to home or land. Check whether lower fan is stalled", + "es": "Error del ventilador inferior. Regrese al punto de origen o aterrice. Compruebe si el ventilador inferior está atascado", + "fr": "Erreur du ventilateur inférieur. Revenez au point de départ ou atterrissez. Vérifiez si le ventilateur inférieur est bloqué", + "id": "", + "it": "", + "ja": "下部ファンエラー。RTHまたは着陸させてください。下部ファンが停止していないかを確認してください", + "ko": "하단 팬 오류입니다. 홈으로 돌아가거나 착륙하세요. 하단 팬이 멈췄는지 확인하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка нижнего вентилятора. Вернитесь домой или приземлитесь. Убедитесь, что нижний вентилятор не заклинило", + "th": "", + "tr": "Alt fan hatası. Eve geri dönün veya iniş yapın. Alt fanın arızalanarak durup durmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "下风扇异常,请返航或降落,再检查飞行器下风扇是否有堵转", + "zh-Hant": "" + }, + "fpv_tip_0x161000a6": { + "de": "Akku der Fernsteuerung schwach. Kann nicht abheben. Akku aufladen", + "en": "Remote controller battery low. Unable to take off. Recharge battery", + "es": "Batería del control remoto baja. No se puede despegar. Recárgala", + "fr": "Batterie de la radiocommande faible. Décollage impossible. Rechargez la batterie", + "it": "", + "ja": "送信機バッテリー残量低下。離陸できません。バッテリーを充電してください", + "ko": "조종기 배터리 부족. 이륙 불가. 배터리 충전 필요", + "pt": "", + "ru": "Низкий заряд аккумулятора пульта ДУ. Взлет невозможен. Зарядите аккумулятор", + "tr": "Uzaktan kumanda pili düşük. Kalkış yapılamıyor. Pili yeniden şarj edin", + "zh": "无法起飞:遥控器电量过低,请给遥控器充电" + }, + "fpv_tip_0x161000a6_in_the_sky": { + "de": "Akku der Fernsteuerung schwach. Sofort zurückkehren oder landen", + "en": "Remote controller battery low. Return to home or land promptly", + "es": "Batería del control remoto baja. Regresa al punto de origen o aterriza rápidamente", + "fr": "Batterie de la radiocommande faible. Retournez au point de départ ou atterrissez rapidement", + "it": "", + "ja": "送信機バッテリー残量低下。直ちに帰還するか着陸してください", + "ko": "조종기 배터리 부족. 즉시 RTH 또는 착륙 필요", + "pt": "", + "ru": "Низкий заряд аккумулятора пульта ДУ. Вернитесь домой или приземлитесь немедленно", + "tr": "Uzaktan kumanda pili düşük. Eve geri dönün veya düzgün iniş yapın", + "zh": "遥控器电量过低,请尽快返航或降落" + }, + "fpv_tip_0x161000b4": { + "en": "Remote ID broadcast error. Failed to obtain remote controller location. Unable to take off", + "zh": "无法起飞:Remote ID 播报异常,无法获取遥控器位置" + }, + "fpv_tip_0x161000b5": { + "en": "Remote ID module error. Unable to take off. Contact DJI Support", + "zh": "无法起飞,Remote ID 模块异常,请联系售后服务" + }, + "fpv_tip_0x161000c0": { + "de": "Start nicht möglich: Ausführungen des linken und des rechten Akkus stimmen nicht überein. Akku ersetzen, damit Ausführungen identisch sind", + "en": "Unable to take off: left battery and right battery models do not match. Replace battery for model consistency", + "es": "No se puede despegar: los modelos de batería izquierda y derecha no coinciden. Sustituya la batería para mantener la uniformidad del modelo", + "fr": "Impossible de décoller : les modèles de batterie de gauche et de droite ne correspondent pas. Remplacer la batterie pour que les modèles soient identiques", + "ja": "離陸できません: 左バッテリーと右バッテリーのモデルが一致しません。モデルの一貫性を保つためにバッテリーを交換してください", + "ko": "이륙 불가: 왼쪽 배터리와 오른쪽 배터리 모델이 일치하지 않습니다. 모델 일관성을 위해 배터리를 교체하세요", + "ru": "Не удается выполнить взлет: модели левой батареи и правой батареи не совпадают. Замените батарею для соответствия модели", + "tr": "Kalkış yapılamıyor: Sol pil ve sağ pil modelleri uyuşmuyor. Model tutarlılığı için pili değiştirin", + "zh": "无法起飞:左右电池型号不一致,请更换电池保持一致" + }, + "fpv_tip_0x161000c0_in_the_sky": { + "de": "Ausführungen des linken und des rechten Akkus stimmen nicht überein. Fluggerät sofort landen und Akku ersetzen", + "en": "Left battery and right battery models do not match. Land aircraft immediately and replace battery", + "es": "Los modelos de batería izquierda y derecha no coinciden. Aterrice la aeronave de inmediato y sustituya la batería", + "fr": "Les modèles de batterie de gauche et de droite ne correspondent pas. Faites atterrir l'appareil immédiatement et remplacez la batterie", + "ja": "左バッテリーと右バッテリーのモデルが一致しません。機体を直ちに着陸させ、バッテリーを交換してください", + "ko": "왼쪽 배터리와 오른쪽 배터리 모델이 일치하지 않습니다. 기체를 즉시 착륙시켜 배터리를 교체하세요", + "ru": "Модели левой батареи и правой батареи не совпадают. Немедленно посадите дрон и замените батарею", + "tr": "Sol pil ve sağ pil modelleri uyuşmuyor. Aracı hemen indirin ve pili değiştirin", + "zh": "左右电池型号不一致,请尽快降落更换电池" + }, + "fpv_tip_0x1611000A": { + "de": "Signal verloren. Rückkehrfunktion (RTH) aktiv", + "en": "Signal lost. RTH in progress", + "es": "Se ha perdido la señal. RPO en curso", + "fr": "Perte de signal. RTH en cours", + "ja": "信号ロストです。RTHが進行中です", + "ko": "신호 끊김. RTH 진행 중", + "ru": "Сигнал потерян. Выполняется возврат домой", + "tr": "Sinyal kayboldu. Eve Dönüş sürüyor", + "zh": "失联返航中" + }, + "fpv_tip_0x1611004F": { + "de": "Akkuauthentifizierung fehlgeschlagen", + "en": "Battery authentication failed", + "es": "Error de autenticación de la batería", + "fr": "Échec de l'authentification de la batterie", + "ja": "バッテリー認証に失敗しました", + "ko": "배터리 인증에 실패했습니다", + "ru": "Не удалось опознать АКБ", + "tr": "Pil kimlik doğrulaması başarısız oldu", + "zh": "电池认证失败" + }, + "fpv_tip_0x1612000B": { + "de": "Flughöhe zu hoch. Verwendung von Propellern für große Flughöhen empfohlen", + "en": "Altitude too high. Using high-altitude propellers recommended", + "es": "Altitud demasiado alta. Se recomienda el uso de hélices de gran altitud", + "fr": "Altitude trop élevée. Utilisation d'hélices à haute altitude recommandée", + "ja": "飛行高度が高すぎます。高高度向けプロペラの使用をお勧めします", + "ko": "고도가 너무 높습니다. 높은 고도 프로펠러 사용을 권장합니다", + "ru": "Дрон летит слишком высоко. Рекомендуется использовать высотные пропеллеры", + "tr": "İrtifa çok yüksek. Yüksek irtifa pervanelerinin kullanılması önerilir", + "zh": "海拔过高,推荐使用高原桨" + }, + "fpv_tip_0x1612000C": { + "de": "Flughöhe zu hoch. Ausschließlich Propeller für große Flughöhen verwenden", + "en": "Altitude too high. Use high-altitude propellers only", + "es": "Altitud demasiado alta. Utilice únicamente hélices de gran altitud", + "fr": "Altitude trop élevée. Utilisez uniquement des hélices à haute altitude", + "ja": "飛行高度が高すぎます。高高度向けプロペラのみを使用してください", + "ko": "고도가 너무 높습니다. 높은 고도 프로펠러만 사용하세요", + "ru": "Дрон летит слишком высоко. Используйте только высотные пропеллеры", + "tr": "İrtifa çok yüksek. Yalnızca yüksek irtifa pervaneleri kullanın", + "zh": "海拔过高,请务必使用高原桨" + }, + "fpv_tip_0x1612000D": { + "de": "Maximale Flughöhe erreicht. Auf Flugsicherheit und Flughöhe achten", + "en": "Reaching maximum flight altitude. Pay attention to flight safety and altitude", + "es": "Se está alcanzando la altitud de vuelo máxima. Preste atención a la seguridad y la altitud de vuelo", + "fr": "Altitude en vol maximale bientôt atteinte. Faites attention à la sécurité en vol et à l'altitude", + "ja": "最大飛行高度に近づいています。飛行安全性と高度に注意してください", + "ko": "최고 비행 고도에 도달합니다. 비행 안전과 고도에 유의하세요", + "ru": "Достижение максимальной высоты полета. Обращайте внимание на безопасность полета и высоту", + "tr": "Maksimum uçuş irtifasına ulaşılıyor. Uçuş güvenliğine ve irtifaya dikkat edin", + "zh": "海拔即将超过最大飞行高度,请注意飞行安全并控制高度" + }, + "fpv_tip_0x16120010": { + "de": "Nähert sich dem Boden. Mit Vorsicht fliegen", + "en": "Approaching ground. Fly with caution", + "es": "Acercándose al suelo. Vuela con cuidado", + "fr": "Approche du sol. Pilotez avec précaution", + "ja": "地面に接近中です。慎重に飛行してください", + "ko": "지면 접근 중. 비행 시 주의 필요", + "ru": "Приближение к поверхности. Соблюдайте осторожность при полете", + "tr": "Yere yaklaşılıyor. Dikkatlice uçun", + "zh": "接近地面,谨慎飞行" + }, + "fpv_tip_0x16200101": { + "de": "Fluggerät mit USB-Gerät verbunden. Start nicht möglich", + "en": "Aircraft connected to USB device. Unable to take off", + "es": "Aeronave conectada a dispositivo USB. No se puede despegar", + "fr": "Appareil connecté à un périphérique USB. Impossible de décoller", + "ja": "機体がUSB機器に接続されています。離陸できません", + "ko": "기체가 USB 기기에 연결됨. 이륙 불가", + "ru": "Дрон подключен к устройству USB. Не удается выполнить взлет", + "tr": "Araç USB cihazına bağlı. Kalkış yapılamıyor", + "zh": "无法起飞:已连接USB" + }, + "fpv_tip_0x16200101_in_the_sky": { + "de": "Fehler: USB-Anschluss. Mit Vorsicht fliegen", + "en": "USB port error. Fly with caution", + "es": "Error del puerto USB. Vuela con cuidado", + "fr": "Erreur de port USB. Pilotez avec précaution", + "ja": "USBポートのエラー。慎重に飛行してください", + "ko": "USB 포트 오류. 비행 시 주의 필요", + "ru": "Ошибка порта USB. Соблюдайте осторожность при полете", + "tr": "USB bağlantı noktası hatası. Aracınızı dikkatli uçurun", + "zh": "USB接口异常,请谨慎飞行" + }, + "fpv_tip_0x16200102": { + "de": "Protokolle werden gelöscht. Start nicht möglich", + "en": "Clearing logs. Unable to take off", + "es": "Borrando los registros. No se puede despegar", + "fr": "Effacement des journaux. Impossible de décoller", + "ja": "ログを消去中。離陸できません", + "ko": "로그 지우는 중. 이륙 불가", + "ru": "Очистка журналов. Не удается выполнить взлет", + "tr": "Günlükler siliniyor. Kalkış yapılamıyor", + "zh": "无法起飞:清除日志中" + }, + "fpv_tip_0x16200102_in_the_sky": { + "de": "Protokolle werden gelöscht. Mit Vorsicht fliegen", + "en": "Clearing logs. Fly with caution", + "es": "Borrando los registros. Vuela con cuidado", + "fr": "Effacement des journaux. Pilotez avec précaution", + "ja": "ログを消去中。慎重に飛行してください", + "ko": "로그 지우는 중. 비행 시 주의 필요", + "ru": "Очистка журналов. Соблюдайте осторожность при полете", + "tr": "Günlükler siliniyor. Aracınızı dikkatli uçurun", + "zh": "清除日志中,请谨慎飞行" + }, + "fpv_tip_0x16200103": { + "de": "Aktualisiere Firmware. Start nicht möglich", + "en": "Updating firmware. Unable to take off", + "es": "Actualizando el firmware. No se puede despegar", + "fr": "Màj du firmware... Impossible de décoller", + "ja": "ファームウェアを更新中。離陸できません", + "ko": "펌웨어 업데이트 중. 이륙 불가", + "ru": "Выполняется обновление прошивки. Не удается выполнить взлет", + "tr": "Ürün yazılımı güncelleniyor. Kalkış yapılamıyor", + "zh": "无法起飞:固件升级中" + }, + "fpv_tip_0x16200103_in_the_sky": { + "de": "Aktualisiere Firmware. Mit Vorsicht fliegen", + "en": "Updating firmware. Fly with caution", + "es": "Actualizando el firmware. Vuela con cuidado", + "fr": "Màj du firmware... Pilotez avec précaution", + "ja": "ファームウェアを更新中。慎重に飛行してください", + "ko": "펌웨어 업데이트 중. 비행 시 주의 필요", + "ru": "Выполняется обновление прошивки. Соблюдайте осторожность при полете", + "tr": "Ürün yazılımı güncelleniyor. Aracınızı dikkatli uçurun", + "zh": "固件升级中,请谨慎飞行" + }, + "fpv_tip_0x16200104": { + "ar": "", + "de": "Start nicht möglich. Firmware-Aktualisierung erforderlich oder Aktualisierung läuft", + "en": "Unable to take off. Firmware update required or update in progress", + "es": "No se puede despegar. Es necesario actualizar el firmware o hay una actualización en curso", + "fr": "Impossible de décoller. Mise à jour du firmware requise ou mise à jour en cours", + "id": "", + "it": "", + "ja": "離陸できません。ファームウェアの強制更新が必要か、更新が進行中です", + "ko": "이륙 불가. 펌웨어 업데이트가 필요하거나 업데이트가 진행 중입니다", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Не удается выполнить взлет. Требуется обновление прошивки или выполняется обновление", + "th": "", + "tr": "Kalkış yapılamıyor. Ürün yazılımı güncellemesi gerekli veya güncelleme devam ediyor", + "ug": "", + "vi": "", + "zh": "无法起飞:固件需要升级或正在升级中", + "zh-Hant": "" + }, + "fpv_tip_0x16200104_in_the_sky": { + "ar": "", + "de": "Obligatorische Firmware-Aktualisierung wird durchgeführt. Mit Vorsicht fliegen", + "en": "Firmware update required. Fly with caution", + "es": "Actualización obligatoria del firmware en curso. Vuela con cuidado", + "fr": "Mise à jour obligatoire du firmware en cours. Pilotez avec précaution", + "id": "", + "it": "", + "ja": "ファームウェアを強制更新中。慎重に飛行してください", + "ko": "필수 펌웨어 업데이트 진행 중. 비행 시 주의 필요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Идет обязательное обновление прошивки. Соблюдайте осторожность при полете", + "th": "", + "tr": "Zorunlu ürün yazılımı güncellemesi devam ediyor. Aracınızı dikkatli uçurun", + "ug": "", + "vi": "", + "zh": "固件强制升级中,请谨慎飞行", + "zh-Hant": "" + }, + "fpv_tip_0x16200201": { + "de": "FlySafe-Datenbank wird aktualisiert. Start nicht möglich", + "en": "Updating Fly Safe database. Unable to take off", + "es": "Actualizado la base de datos Vuela Seguro. No se puede despegar", + "fr": "Mise à jour de la base de données Fly Safe. Impossible de décoller", + "ja": "安全飛行データベースを更新中。離陸できません", + "ko": "비행 안전 데이터베이스 업데이트 중. 이륙 불가", + "ru": "Выполняется обновление базы данных \"Безопасность полетов\". Не удается выполнить взлет", + "tr": "Güvenli Uçuş veritabanı güncelleniyor. Kalkış yapılamıyor", + "zh": "无法起飞:限飞数据库升级中" + }, + "fpv_tip_0x16200201_in_the_sky": { + "de": "FlySafe-Datenbank wird aktualisiert. Mit Vorsicht fliegen", + "en": "Updating Fly Safe database. Fly with caution", + "es": "Actualizado la base de datos Vuela Seguro. Vuela con cuidado", + "fr": "Mise à jour de la base de données Fly Safe. Pilotez avec précaution", + "ja": "安全飛行データベースを更新中。慎重に飛行してください", + "ko": "비행 안전 데이터베이스 업데이트 중. 비행 시 주의 필요", + "ru": "Выполняется обновление базы данных \"Безопасность полетов\". Соблюдайте осторожность при полете", + "tr": "Güvenli Uçuş veritabanı güncelleniyor. Aracınızı dikkatli uçurun", + "zh": "限飞数据库升级中,请谨慎飞行" + }, + "fpv_tip_0x16200202": { + "de": "Kalibrierungsfehler: Sichtsensoren. Start nicht möglich", + "en": "Vision sensor calibration error. Unable to take off", + "es": "Error de calibración del sensor visual. No se puede despegar", + "fr": "Erreur d'étalonnage du capteur optique. Impossible de décoller", + "ja": "ビジョンセンサーのキャリブレーションエラー。離陸できません", + "ko": "비전 센서 캘리브레이션 오류. 이륙 불가", + "ru": "Ошибка калибровки датчика обзора. Не удается выполнить взлет", + "tr": "Görüş sensörü kalibrasyon hatası. Kalkış yapılamıyor", + "zh": "无法起飞:视觉传感器标定异常" + }, + "fpv_tip_0x16200202_in_the_sky": { + "de": "Kalibrierungsfehler: Sichtsensoren. Mit Vorsicht fliegen", + "en": "Vision sensor calibration error. Fly with caution", + "es": "Error de calibración del sensor visual. Vuela con cuidado", + "fr": "Erreur d'étalonnage du capteur optique. Pilotez avec précaution", + "ja": "ビジョンセンサーのキャリブレーションエラー。慎重に飛行してください", + "ko": "비전 센서 캘리브레이션 오류. 비행 시 주의 필요", + "ru": "Ошибка калибровки датчика обзора. Соблюдайте осторожность при полете", + "tr": "Görüş sensörü kalibrasyon hatası. Aracınızı dikkatli uçurun", + "zh": "视觉传感器标定异常,请谨慎飞行" + }, + "fpv_tip_0x16200203": { + "de": "Kalibrierungsfehler: ToF-Sensor. Start nicht möglich", + "en": "ToF sensor calibration error. Unable to take off", + "es": "Error de calibración del sensor de tiempo de vuelo. No se puede despegar", + "fr": "Erreur étalonnage capteur ToF. Impossible de décoller", + "ja": "ToFセンサーのキャリブレーションエラー。離陸できません", + "ko": "ToF 센서 캘리브레이션 오류. 이륙 불가", + "ru": "Ошибка калибровки датчика ToF. Не удается выполнить взлет", + "tr": "ToF sensörü kalibrasyon hatası. Kalkış yapılamıyor", + "zh": "无法起飞:ToF标定异常" + }, + "fpv_tip_0x16200203_in_the_sky": { + "de": "Kalibrierungsfehler: ToF-Sensor. Mit Vorsicht fliegen", + "en": "ToF sensor calibration error. Fly with caution", + "es": "Error de calibración del sensor de tiempo de vuelo. Vuela con cuidado", + "fr": "Erreur étalonnage capteur ToF. Pilotez avec précaution", + "ja": "ToFセンサーのキャリブレーションエラー。慎重に飛行してください", + "ko": "ToF 센서 캘리브레이션 오류. 비행 시 주의 필요", + "ru": "Ошибка калибровки датчика ToF. Соблюдайте осторожность при полете", + "tr": "ToF sensörü kalibrasyon hatası. Aracınızı dikkatli uçurun", + "zh": "ToF标定异常,请谨慎飞行" + }, + "fpv_tip_0x16200204": { + "de": "Statusfehler: Sichtsensoren. Start nicht möglich", + "en": "Vision sensor status error. Unable to take off", + "es": "Error de estado del sensor visual. No se puede despegar", + "fr": "Erreur de statut du capteur optique. Impossible de décoller", + "ja": "ビジョンセンサーのステータスエラー。離陸できません", + "ko": "비전 센서 상태 오류. 이륙 불가", + "ru": "Ошибка статуса датчика изображения. Не удается выполнить взлет", + "tr": "Görüş sensörü durum hatası. Kalkış yapılamıyor", + "zh": "无法起飞:视觉传感器状态异常" + }, + "fpv_tip_0x16200204_in_the_sky": { + "de": "Statusfehler: Sichtsensoren. Mit Vorsicht fliegen", + "en": "Vision sensor status error. Fly with caution", + "es": "Error de estado del sensor visual. Vuela con cuidado", + "fr": "Erreur de statut du capteur optique. Pilotez avec précaution", + "ja": "ビジョンセンサーのステータスエラー。慎重に飛行してください", + "ko": "비전 센서 상태 오류. 비행 시 주의 필요", + "ru": "Ошибка статуса датчика изображения. Соблюдайте осторожность при полете", + "tr": "Görüş sensörü durum hatası. Aracınızı dikkatli uçurun", + "zh": "视觉传感器状态异常,请谨慎飞行" + }, + "fpv_tip_0x16200208": { + "de": "Propellerfehler. Start nicht möglich. Sicherstellen, dass die Propeller nicht beschädigt sind. Fluggerät neu starten und erneut versuchen", + "en": "Propeller error. Unable to take off. Make sure propellers are not damaged. Restart aircraft and try again", + "es": "Error de la hélice. No se puede despegar. Asegúrese de que las hélices no estén dañadas. Reinicie la aeronave y vuelva a intentarlo", + "fr": "Erreur d'hélice. Impossible de décoller. Assurez-vous que les hélices ne sont pas endommagées. Redémarrez l’appareil et réessayez", + "ja": "プロペラエラーです。離陸できません。プロペラが破損していないことを確かにしてください。機体を再起動し、やり直してください", + "ko": "프로펠러 오류입니다. 이륙 불가. 프로펠러가 손상되지 않았는지 확인하세요. 기체를 재시작한 후 다시 시도하세요", + "ru": "Ошибка пропеллера. Невозможно взлететь. Убедитесь, что пропеллеры не повреждены. Перезапустите дрон и повторите попытку", + "tr": "Pervane hatası. Kalkış yapılamıyor. Pervanelerin hasar görmediğinden emin olun. Hava aracını tekrar başlatın ve yeniden deneyin", + "zh": "桨叶异常,无法起飞,请确认桨叶完好无损后重启飞机再试" + }, + "fpv_tip_0x16200301": { + "de": "Gerätefehler am Erweiterungsanschluss. Start nicht möglich. PSDK-Gerät überprüfen", + "en": "Extension port device error. Unable to take off. Check PSDK device", + "es": "Error de dispositivo de puerto de ampliación. No se puede despegar. Comprueba el dispositivo PSDK", + "fr": "Erreur de périphérique de port d'extension. Impossible de décoller. Vérifier le périphérique PSDK", + "it": "", + "ja": "拡張ポート機器エラー。離陸できません。PSDK機器を確認してください", + "ko": "확장 포트 기기 오류. 이륙 불가. PSDK 기기 확인", + "pt": "", + "ru": "Ошибка устройства порта расширения. Не удается выполнить взлет. Проверьте устройство PSDK", + "tr": "Genişletme portu cihaz hatası. Kalkış yapılamıyor. PSDK cihazını kontrol edin", + "zh": "无法起飞:扩展口设备异常,请检查PSDK设备" + }, + "fpv_tip_0x16200301_in_the_sky": { + "de": "Gerätefehler am Erweiterungsanschluss. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Extension port device error. Return to home or land promptly", + "es": "Error de dispositivo de puerto de ampliación. Regresa al punto de origen o aterriza rápidamente", + "fr": "Erreur de périphérique de port d'extension. Retournez au point de départ ou atterrissez rapidement", + "ja": "拡張ポート機器エラー。直ちに帰還するか、着陸してください", + "ko": "확장 포트 기기 오류. 즉시 리턴 투 홈 또는 착륙 필요", + "ru": "Ошибка устройства порта расширения. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Genişletme portu cihaz hatası. Ana konuma geri dönün veya derhal iniş yapın", + "zh": "扩展口设备异常,请尽快返航或降落" + }, + "fpv_tip_0x16200302": { + "de": "Fehler: Nutzlasten von Drittanbietern. Start nicht möglich", + "en": "Third-party payload error. Unable to take off", + "es": "Error de instrumentos de terceros. No se puede despegar", + "fr": "Erreur de nacelles-caméras tierces. Impossible de décoller", + "ja": "他社製ペイロードのエラー。離陸できません", + "ko": "타사 페이로드 오류. 이륙 불가", + "ru": "Ошибка сторонней полезной нагрузки. Не удается выполнить взлет", + "tr": "Üçüncü taraf yük hatası. Kalkış yapılamıyor", + "zh": "无法起飞:第三方负载设备异常" + }, + "fpv_tip_0x16200302_in_the_sky": { + "de": "Propeller werden gestoppt. Landebereich basierend auf aktueller Position des Fluggeräts vorhersagen", + "en": "Stopping propellers. Predict landing area based on current aircraft location", + "es": "Deteniendo las hélices. Predecir el área de aterrizaje según la ubicación actual de la aeronave", + "fr": "Arrêt des hélices. Prédisez l'aire d'atterrissage en fonction de la position actuelle de l'appareil", + "ja": "プロペラを停止中。機体の現在地に基づいて着陸エリアを予測してください", + "ko": "프로펠러 정지 중. 현재 기체 위치를 기준으로 착륙 지점 예측 필요", + "ru": "Остановка пропеллеров. Прогнозировать зону посадки на основе текущего местоположения дрона", + "tr": "Pervaneler durduruluyor. Aracın mevcut konumuna göre iniş alanını tahmin edin", + "zh": "执行空中紧急停桨,请根据飞行器当前位置预测降落点位置" + }, + "fpv_tip_0x16200401": { + "de": "Obligatorische Aktualisierung der FlySafe-Datenbank wird durchgeführt. Start nicht möglich", + "en": "Mandatory Fly Safe database update in progress. Unable to take off", + "es": "Actualización obligatoria de la base de datos Vuela Seguro en curso. No se puede despegar", + "fr": "Mise à jour obligatoire de la base de données Fly Safe en cours. Impossible de décoller", + "ja": "安全飛行データベースを強制更新中。離陸できません", + "ko": "필수 비행 안전 데이터베이스 업데이트 진행 중. 이륙 불가", + "ru": "Выполняется обязательное обновление базы данных \"Безопасность полетов\". Не удается выполнить взлет", + "tr": "Zorunlu Güvenli Uçuş veritabanı güncellemesi devam ediyor. Kalkış yapılamıyor", + "zh": "无法起飞:APP限飞数据库强制升级中" + }, + "fpv_tip_0x16200401_in_the_sky": { + "de": "Obligatorische Aktualisierung der FlySafe-Datenbank wird durchgeführt. Mit Vorsicht fliegen", + "en": "Mandatory Fly Safe database update in progress. Fly with caution", + "es": "Actualización obligatoria de la base de datos Vuela Seguro en curso. Vuela con cuidado", + "fr": "Mise à jour obligatoire de la base de données Fly Safe en cours. Pilotez avec précaution", + "ja": "安全飛行データベースを強制更新中。慎重に飛行してください", + "ko": "필수 비행 안전 데이터베이스 업데이트 진행 중. 비행 시 주의 필요", + "ru": "Выполняется обязательное обновление базы данных \"Безопасность полетов\". Соблюдайте осторожность при полете", + "tr": "Zorunlu Güvenli Uçuş veritabanı güncellemesi devam ediyor. Aracınızı dikkatli uçurun", + "zh": "APP限飞数据库强制升级中,请谨慎飞行" + }, + "fpv_tip_0x16200402": { + "de": "Obligatorische Firmware-Aktualisierung wird durchgeführt. Start nicht möglich", + "en": "Mandatory firmware update in progress. Unable to take off", + "es": "Actualización obligatoria del firmware en curso. No se puede despegar", + "fr": "Mise à jour obligatoire du firmware en cours. Impossible de décoller", + "ja": "ファームウェアを強制更新中。離陸できません", + "ko": "필수 펌웨어 업데이트 진행 중. 이륙 불가", + "ru": "Идет обязательное обновление прошивки. Не удается выполнить взлет", + "tr": "Zorunlu ürün yazılımı güncellemesi devam ediyor. Kalkış yapılamıyor", + "zh": "无法起飞:APP固件强制升级中" + }, + "fpv_tip_0x16200402_in_the_sky": { + "de": "Obligatorische Firmware-Aktualisierung wird durchgeführt. Mit Vorsicht fliegen", + "en": "Mandatory firmware update in progress. Fly with caution", + "es": "Actualización obligatoria del firmware en curso. Vuela con cuidado", + "fr": "Mise à jour obligatoire du firmware en cours. Pilotez avec précaution", + "ja": "ファームウェアを強制更新中。慎重に飛行してください", + "ko": "필수 펌웨어 업데이트 진행 중. 비행 시 주의 필요", + "ru": "Идет обязательное обновление прошивки. Соблюдайте осторожность при полете", + "tr": "Zorunlu ürün yazılımı güncellemesi devam ediyor. Aracınızı dikkatli uçurun", + "zh": "APP固件强制升级中,请谨慎飞行" + }, + "fpv_tip_0x16200501": { + "de": "Inkompatible Akkuversionen. Start nicht möglich", + "en": "Incompatible battery versions. Unable to take off", + "es": "Versiones de batería incompatibles. No se puede despegar", + "fr": "Versions de batterie incompatibles. Impossible de décoller", + "ja": "互換性のないバッテリーバージョンです。離陸できません", + "ko": "호환되지 않는 배터리 버전. 이륙 불가", + "ru": "Несовместимые версии АКБ. Не удается выполнить взлет", + "tr": "Uyumsuz pil modeli. Kalkış yapılamıyor", + "zh": "无法起飞:电池版本不匹配" + }, + "fpv_tip_0x16200501_in_the_sky": { + "de": "Inkompatible Akkuversionen. Umgehend zum Startpunkt zurückkehren oder landen", + "en": "Incompatible battery versions. Return to home or land promptly", + "es": "Versiones de batería incompatibles. Regrese al punto de origen o aterrice rápidamente", + "fr": "Versions de batterie incompatibles. Retournez au point de départ ou atterrissez rapidement", + "ja": "互換性のないバッテリーバージョンです。直ちに帰還するか、着陸してください", + "ko": "호환되지 않는 배터리 버전. 즉시 리턴 투 홈을 실행하거나 착륙하세요", + "ru": "Несовместимые версии АКБ. Как можно скорее вернитесь на базу или приземлитесь", + "tr": "Uyumsuz pil modeli. Başlangıç noktasına geri dönün veya derhal iniş yapın", + "zh": "电池版本不匹配,请尽快返航或降落" + }, + "fpv_tip_0x16200601": { + "de": "Flugsystem wird initialisiert...", + "en": "Initializing flight system...", + "es": "Iniciando sistema de vuelo...", + "fr": "Initialisation du système de vol...", + "ja": "フライトシステムを初期化中...", + "ko": "비행 시스템 초기화 중...", + "ru": "Инициализация системы управления полетом...", + "tr": "Uçuş sistemi başlatılıyor...", + "zh": "飞行系统初始化中,请等待" + }, + "fpv_tip_0x16200601_in_the_sky": { + "de": "Flugsystem wird initialisiert...", + "en": "Initializing flight system...", + "es": "Iniciando sistema de vuelo...", + "fr": "Initialisation du système de vol...", + "ja": "フライトシステムを初期化中...", + "ko": "비행 시스템 초기화 중...", + "ru": "Инициализация системы управления полетом...", + "tr": "Uçuş sistemi başlatılıyor...", + "zh": "飞行系统初始化中,请等待" + }, + "fpv_tip_0x16200A01": { + "ar": "", + "de": "", + "en": "Unable to take off. Battery cover off", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "无法起飞:未接电池帽盖", + "zh-Hant": "" + }, + "fpv_tip_0x16200A01_in_the_sky": { + "ar": "", + "de": "", + "en": "Battery communication error. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "电池通信异常,请谨慎飞行", + "zh-Hant": "" + }, + "fpv_tip_0x16400002": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "AP主动释放控制权", + "zh-Hant": "" + }, + "fpv_tip_0x16400003": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "AP控制指令异常", + "zh-Hant": "" + }, + "fpv_tip_0x16400004": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "AP心跳异常", + "zh-Hant": "" + }, + "fpv_tip_0x16400005": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "mcu侧mission调度器状态数据包异常", + "zh-Hant": "" + }, + "fpv_tip_0x16400006": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "mission调度器异常", + "zh-Hant": "" + }, + "fpv_tip_0x16400007": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "调度器没有mission运行", + "zh-Hant": "" + }, + "fpv_tip_0x16400008": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "AP到MCU链路异常", + "zh-Hant": "" + }, + "fpv_tip_0x16400009": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "AP没有发送控制指令", + "zh-Hant": "" + }, + "fpv_tip_0x1640000A": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "AP挂死", + "zh-Hant": "" + }, + "fpv_tip_0x1640000B": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "系统实时性异常", + "zh-Hant": "" + }, + "fpv_tip_0x1640000C": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "业务实时性异常", + "zh-Hant": "" + }, + "fpv_tip_0x16400100": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据fly_core无内容", + "zh-Hant": "" + }, + "fpv_tip_0x16400101": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据fly_extend无内容", + "zh-Hant": "" + }, + "fpv_tip_0x16400102": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据fmu_gps无内容", + "zh-Hant": "" + }, + "fpv_tip_0x16400103": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据fmu_rtk无内容", + "zh-Hant": "" + }, + "fpv_tip_0x16400104": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据fusion_out无内容", + "zh-Hant": "" + }, + "fpv_tip_0x16400105": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据vio_result无内容", + "zh-Hant": "" + }, + "fpv_tip_0x16400106": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据image_status无内容", + "zh-Hant": "" + }, + "fpv_tip_0x16400107": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据radar_detect_info无内容", + "zh-Hant": "" + }, + "fpv_tip_0x16400108": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据gimbal_state无内容", + "zh-Hant": "" + }, + "fpv_tip_0x16400109": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据camera_state无内容", + "zh-Hant": "" + }, + "fpv_tip_0x1640010A": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据camera_cap_status无内容", + "zh-Hant": "" + }, + "fpv_tip_0x1640010B": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据camera_video_param无内容", + "zh-Hant": "" + }, + "fpv_tip_0x1640010C": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据camera_lens_param无内容", + "zh-Hant": "" + }, + "fpv_tip_0x1640010D": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据camera_lens_param_ir无内容", + "zh-Hant": "" + }, + "fpv_tip_0x1640010E": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据camera_data_hd无内容", + "zh-Hant": "" + }, + "fpv_tip_0x1640010F": { + "ar": "", + "de": "", + "en": "", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "抽象数据camera_data_vga无内容", + "zh-Hant": "" + }, + "fpv_tip_0x16476003": { + "en": "Vision sensor error. Restart aircraft and try again", + "zh": "视觉定位前端获取里程计异常,尝试重启后再工作" + }, + "fpv_tip_0x16490003": { + "ar": "", + "de": "", + "en": "Vertical altitude error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "垂直高度反馈异常", + "zh-Hant": "" + }, + "fpv_tip_0x164A1005": { + "en": "In No Position Hold mode, aircraft is unable to hover stably. It is recommended to switch to Normal mode before flying", + "zh": "当前为无位置保持模式,飞行器无法稳定悬停,建议切换为普通模式后起飞" + }, + "fpv_tip_0x164A1005_in_the_sky": { + "en": "In No Position Hold mode, aircraft is unable to hover stably, and flight safety is affected. It is recommended to switch to Normal mode", + "zh": "无位置保持模式下,无法稳定悬停,可能影响飞行安全,建议切换为普通模式" + }, + "fpv_tip_0x17000001": { + "de": "Primäre Bildübertragung getrennt", + "en": "Primary image transmission disconnected", + "es": "Transmisión de la imagen principal desconectada", + "fr": "Transmission d'image principale déconnectée", + "it": "", + "ja": "プライマリー映像伝送との接続が切断されました", + "ko": "기본 이미지 전송 연결 끊김", + "pt": "", + "ru": "Передача основного изображения отключена", + "tr": "Birincil görüntü aktarımı bağlantısı kesildi", + "zh": "主链路图传已断开" + }, + "fpv_tip_0x17000001_in_the_sky": { + "de": "Primäre Bildübertragung getrennt. Antennen ausrichten.", + "en": "Primary image transmission disconnected. Adjust antennas", + "es": "Transmisión de la imagen principal desconectada. Ajuste las antenas", + "fr": "Transmission d'image principale déconnectée. Ajuster les antennes", + "it": "", + "ja": "プライマリー映像伝送との接続が切断されました。アンテナを調整してください", + "ko": "기본 이미지 전송 연결 끊김. 안테나 조정 필요", + "pt": "", + "ru": "Передача основного изображения отключена. Отрегулируйте антенны", + "tr": "Birincil görüntü aktarımı bağlantısı kesildi. Antenleri ayarlayın", + "zh": "主链路图传已断开,请尝试调整天线角度" + }, + "fpv_tip_0x17000002": { + "de": "Schwaches Fernsteuerungssignal. Antennen ausrichten", + "en": "Remote controller signal weak. Adjust antennas", + "es": "La señal del control remoto es débil. Ajusta las antenas", + "fr": "Signal de la radiocommande faible. Ajuster les antennes", + "ja": "送信機信号が弱い。アンテナを調整してください", + "ko": "조종기 신호 약함. 안테나 조정 필요", + "ru": "Слабый сигнал пульта управления. Отрегулируйте антенны", + "tr": "Uzaktan kumanda sinyali zayıf. Antenleri ayarlayın", + "zh": "遥控器信号微弱,请调整天线" + }, + "fpv_tip_0x17000002_in_the_sky": { + "ar": "", + "de": "", + "en": "Remote controller signal weak. Adjust antennas", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "遥控器信号微弱,请调整天线", + "zh-Hant": "" + }, + "fpv_tip_0x17000003": { + "de": "Starke Signalstörungen an der Position des Fluggeräts. Mit Vorsicht fliegen", + "en": "Strong signal interference in aircraft location. Fly with caution", + "es": "Fuerte interferencia de señal en la ubicación de la aeronave. Vuela con cuidado", + "fr": "Fortes interférences de signal à la position de l’appareil. Pilotez avec précaution", + "ja": "機体の現在地で強い電波干渉があります。慎重に飛行してください", + "ko": "기체 위치에서 강한 신호 간섭 받음. 비행 시 주의 필요", + "ru": "Сильные помехи в местоположении дрона. Соблюдайте осторожность при полете", + "tr": "Araç konumunda güçlü sinyal paraziti. Aracınızı dikkatli uçurun", + "zh": "飞行器所在位置信号干扰较强,请谨慎飞行" + }, + "fpv_tip_0x17000003_in_the_sky": { + "ar": "", + "de": "", + "en": "Strong signal interference in aircraft location. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "飞行器所在位置信号干扰较强,请谨慎飞行", + "zh-Hant": "" + }, + "fpv_tip_0x17000004": { + "de": "Schwaches Bildübertragungssignal. Antennen ausrichten", + "en": "Image transmission signal weak. Adjust antennas", + "es": "Señal de transmisión de la imagen débil. Ajusta las antenas", + "fr": "Signal de transmission d'image faible. Ajuster les antennes", + "ja": "映像伝送信号が弱い。アンテナを調整してください", + "ko": "이미지 전송 신호 약함. 안테나 조정 필요", + "ru": "Слабый сигнал передачи изображения. Отрегулируйте антенны", + "tr": "Görüntü aktarım sinyali zayıf. Antenleri ayarlayın", + "zh": "图传信号弱,请调整遥控器朝向飞行器" + }, + "fpv_tip_0x17000004_in_the_sky": { + "ar": "", + "de": "", + "en": "Image transmission signal weak. Adjust antennas", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "图传信号弱,请调整遥控器朝向飞行器", + "zh-Hant": "" + }, + "fpv_tip_0x17000005": { + "de": "Starke Signalstörungen an der Position der Fernsteuerung. Mit Vorsicht fliegen", + "en": "Strong signal interference in remote controller location. Fly with caution", + "es": "Fuerte interferencia de señal en la ubicación del control remoto. Vuela con cuidado", + "fr": "Fortes interférences à la position de la radiocommande. Pilotez avec précaution", + "ja": "送信機の現在地で強い電波干渉があります。慎重に飛行してください", + "ko": "조종기 위치에서 강한 신호 간섭 받음. 비행 시 주의 필요", + "ru": "Сильные помехи в местоположении пульта управления. Соблюдайте осторожность при полете", + "tr": "Uzaktan kumanda konumunda güçlü sinyal paraziti. Aracınızı dikkatli uçurun", + "zh": "遥控器信号干扰较强,请注意飞行安全" + }, + "fpv_tip_0x17000005_in_the_sky": { + "ar": "", + "de": "", + "en": "Strong signal interference in remote controller location. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "遥控器信号干扰较强,请注意飞行安全", + "zh-Hant": "" + }, + "fpv_tip_0x17000006": { + "de": "Landeskennung nicht aktualisiert. Bestimmte Funktionen nicht verfügbar. Starkes GPS-Signal sicherstellen und mit DJI Pilot verbinden, um automatisch zu aktualisieren", + "en": "Country code not updated. Certain features unavailable. Make sure GPS signal is strong and connect to DJI Pilot to update automatically", + "es": "Código del país no actualizado. Algunas funciones no están disponibles. Asegúrate de que la señal GPS sea fuerte y conéctate a DJI Pilot para actualizar automáticamente", + "fr": "Code de pays non mis à jour. Certaines fonctionnalités ne sont pas disponibles. Assurez-vous que le signal GPS est fort et connectez-vous à DJI Pilot pour mettre à jour automatiquement", + "ja": "国コードが更新されていません。一部の機能は使用できません。GPS信号が強いことを確認し、DJI Pilotに接続すると、自動的に更新されます", + "ko": "국가 코드 업데이트 안 됨. 특정 기능 사용 불가. GPS 신호가 강한지 확인하고 DJI Pilot에 연결하여 자동으로 업데이트하세요.", + "ru": "Код страны не обновлен. Некоторые функции недоступны. Убедитесь, что сигнал GPS сильный, и подключитесь к DJI Pilot для автоматического обновления.", + "tr": "Ülke kodu güncellenmedi. Bazı özellikler kullanılamıyor. GPS sinyalinin güçlü olduğundan emin olun ve otomatik olarak güncellemek için DJI Pilot'a bağlanın", + "zh": "国家码未更新,部分功能受限,请保证飞机GPS信号良好并连接 DJI Pilot 自动更新" + }, + "fpv_tip_0x17000006_in_the_sky": { + "de": "Landeskennung nicht aktualisiert. Bestimmte Funktionen nicht verfügbar", + "en": "Country code not updated. Certain features unavailable", + "es": "Código del país no actualizado. Algunas funciones no están disponibles", + "fr": "Code de pays non mis à jour. Certaines fonctionnalités ne sont pas disponibles", + "ja": "国コードが更新されていません。一部の機能は使用できません", + "ko": "국가 코드 업데이트 안 됨. 특정 기능 사용 불가", + "ru": "Код страны не обновлен. Некоторые функции недоступны", + "tr": "Ülke kodu güncellenmedi. Bazı özellikler kullanılamıyor", + "zh": "国家码未更新,部分功能受限" + }, + "fpv_tip_0x17000011": { + "de": "Speicher von Avioniksystem unzureichend. Zum Wiederherstellen Fluggerät neu starten", + "en": "Avionics system memory insufficient. Restart aircraft to restore", + "es": "Memoria del sistema de aviónica insuficiente. Reinicia la aeronave para restaurar", + "fr": "Mémoire des systèmes avioniques insuffisante. Redémarrez l'appareil pour restaurer", + "ja": "航空電子システムのメモリ不足。復元するには機体を再起動してください", + "ko": "항공전자 시스템 메모리가 부족합니다. 복원하려면 기체를 재시작하세요", + "ru": "Недостаточно памяти в авиационной электронной системе. Перезагрузите дрон для восстановления", + "tr": "Havacılık Elektroniği sistem belleği yetersiz. Geri yüklemek için aracı yeniden başlatın", + "zh": "航电系统内存低,请重启飞行器尝试恢复" + }, + "fpv_tip_0x17000011_in_the_sky": { + "de": "Speicher von Avioniksystem unzureichend. Mit Vorsicht fliegen", + "en": "Avionics system memory insufficient. Fly with caution", + "es": "Memoria del sistema de aviónica insuficiente. Vuela con cuidado", + "fr": "Mémoire des systèmes avioniques insuffisante. Pilotez avec précaution", + "ja": "航空電子システムのメモリ不足。慎重に飛行してください", + "ko": "항공전자 시스템 메모리가 부족합니다. 비행 시 주의 필요", + "ru": "Недостаточно памяти в авиационной электронной системе. Будьте внимательны при полете", + "tr": "Havacılık Elektroniği sistem belleği yetersiz. Dikkatli uçurun", + "zh": "航电系统内存低,请谨慎飞行" + }, + "fpv_tip_0x17000013": { + "de": "Signalstörungen an der Fernsteuerung", + "en": "Remote controller signal interference", + "es": "El control remoto detecta interferencias", + "fr": "Interférences avec le signal de la radiocommande", + "ja": "送信機の信号干渉", + "ko": "조종기 신호 간섭", + "ru": "Помехи сигнала пульта управления", + "tr": "Uzaktan kumanda sinyali paraziti", + "zh": "遥控器信号受干扰" + }, + "fpv_tip_0x17000014": { + "de": "Starke Signalstörungen an der Fernsteuerung. Von anderen Fernsteuerungen oder der Störquelle wegbewegen", + "en": "Strong remote controller signal interference. Move away from other remote controllers or source of interference", + "es": "El control remoto detecta interferencias fuertes. Aléjate de otros controles remotos o de la fuente de interferencias.", + "fr": "Fortes interférences avec le signal de la radiocommande. Éloignez-vous des autres radiocommandes ou sources d'interférences", + "ja": "送信機の信号干渉 強。他の送信機や干渉源から離れてください", + "ko": "강한 조종기 신호 간섭. 다른 조종기나 간섭원에서 멀리 떨어지세요.", + "ru": "Сильные помехи сигнала пульта дистанционного управления. Отойдите от других пультов дистанционного управления или источников помех", + "tr": "Güçlü uzaktan kumanda sinyali paraziti. Diğer uzaktan kumandalardan veya parazit kaynaklarından uzak durun", + "zh": "遥控器侧干扰较强,请远离其他遥控器或干扰源" + }, + "fpv_tip_0x17000015": { + "de": "Starke Signalstörungen am Fluggerät. Umgehend zum Startpunkt zurückkehren oder Fluggerät von der Störquelle wegbewegen", + "en": "Strong aircraft signal interference. Return to home promptly or move away from source of interference", + "es": "La aeronave detecta interferencias fuertes. Regresa al punto de origen rápidamente o aléjate de la fuente de interferencias.", + "fr": "Fortes interférences avec le signal de l'appareil. Retournez rapidement au point de départ ou éloignez-vous des sources d'interférences", + "ja": "機体の信号干渉 強。直ちにホームに帰還するか、干渉源から離れてください", + "ko": "강한 기체 신호 간섭. 즉시 홈으로 돌아가거나 간섭원에서 멀리 떨어지세요.", + "ru": "Сильные помехи сигнала дрона. Как можно скорее вернитесь на базу или отойдите от источника помех", + "tr": "Güçlü hava aracı sinyali paraziti. Hemen başlangıç noktasına geri dönün veya parazit kaynağından uzaklaşın", + "zh": "飞行器侧干扰较强,请尽快返航或飞离干扰源" + }, + "fpv_tip_0x17000016": { + "de": "Schwache Signalstärke der Fernsteuerung. Antennenausrichtung überprüfen", + "en": "Remote controller signal weak. Adjust antenna", + "es": "Señal del control remoto débil. Ajusta la antena.", + "fr": "Signal de la radiocommande faible. Réglez l'antenne", + "ja": "送信機信号 弱。アンテナを調整してください", + "ko": "조종기 신호 약함. 안테나를 조정하세요.", + "ru": "Слабый сигнал пульта. Отрегулируйте антенну", + "tr": "Uzaktan kumanda sinyali zayıf. Anteni ayarlayın", + "zh": "遥控器信号微弱,请尝试调整天线" + }, + "fpv_tip_0x17000017": { + "de": "Schwaches Signal Steuerung A Darauf achten, dass die Antennen von Steuerung A ausgeklappt sind und es keine Hindernisse zwischen Fluggerät und Fernsteuerung gibt", + "en": "Controller A signal weak. Make sure antennas of Controller A are unfolded and no obstacle is blocking aircraft and remote controller", + "es": "Señal débil del control A. Asegúrese de que las antenas del control A estén desplegadas y de que ningún obstáculo bloquee la aeronave y el control remoto", + "fr": "Signal de la commande A faible. Assurez-vous que les antennes de la commande A sont dépliées et qu'aucun obstacle ne bloque l'appareil et la radiocommande", + "ja": "送信機Aの信号 弱。送信機Aのアンテナが展開され、機体や送信機を遮る障害物がないことを確認してください", + "ko": "조종기 A 신호 약함. 조종기 A의 안테나가 펼쳐져 있고 기체와 조종기를 가리는 장애물이 없는지 확인하세요", + "ru": "Слабый сигнал пульта А. Убедитесь, что антенны пульта А развернуты и никакие препятствия не блокируют дрон и пульт дистанционного управления", + "tr": "Kumanda A'nın sinyali zayıf. Kumanda A'nın antenlerinin açık olduğundan ve hiçbir engelin hava aracını ve uzaktan kumandayı engellemediğinden emin olun", + "zh": "A控信号弱,请检查A控天线已展开并和飞机之间无遮挡" + }, + "fpv_tip_0x17000018": { + "de": "Schwaches Signal Steuerung B Darauf achten, dass die Antennen von Steuerung B ausgeklappt sind und es keine Hindernisse zwischen Fluggerät und Fernsteuerung gibt", + "en": "Controller B signal weak. Make sure antennas of controller B are unfolded and no obstacle is blocking aircraft and remote controller", + "es": "Señal débil del control B. Asegúrese de que las antenas del control B estén desplegadas y de que ningún obstáculo bloquee la aeronave y el control remoto", + "fr": "Signal de la commande B faible. Assurez-vous que les antennes de la commande B sont dépliées et qu'aucun obstacle ne bloque l'appareil et la radiocommande", + "ja": "送信機Bの信号 弱。送信機Bのアンテナが展開され、機体や送信機を遮る障害物がないことを確認してください", + "ko": "조종기 B 신호 약함. 조종기 B의 안테나가 펼쳐져 있고 기체와 조종기를 가리는 장애물이 없는지 확인하세요", + "ru": "Слабый сигнал пульта B. Убедитесь, что антенны пульта B развернуты и никакие препятствия не блокируют дрон и пульт дистанционного управления", + "tr": "Kumanda B'nin sinyali zayıf. Kumanda B'nin antenlerinin açık olduğundan ve hiçbir engelin hava aracını ve uzaktan kumandayı engellemediğinden emin olun", + "zh": "B控信号弱,请检查B控天线已展开并和飞机之间无遮挡" + }, + "fpv_tip_0x17000019": { + "de": "Kamerafehler. Gimbal abnehmen und wieder anbringen", + "en": "Camera error. Detach and remount gimbal", + "es": "Error de la cámara. Retire el estabilizador y vuelva a montarlo", + "fr": "Erreur caméra. Détacher et remonter la nacelle", + "ja": "カメラエラー。ジンバルを取り外して、取り付け直してください", + "ko": "카메라 오류. 짐벌을 분리 후 다시 장착하세요", + "ru": "Ошибка камеры. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera hatası. Gimbalı çıkarın ve yeniden takın", + "zh": "相机异常,请尝试重新插拔云台" + }, + "fpv_tip_0x17000041": { + "en": "Unable to get control stick input", + "zh": "无法获取遥控器杆量" + }, + "fpv_tip_0x17000071": { + "de": "Avioniksystem überlastet. Überprüfen, ob Protokolle übertragen werden. Zum Wiederherstellen Fluggerät neu starten", + "en": "Avionics system overloaded. Check whether logs are being transmitted. Restart aircraft to restore", + "es": "Sistema de aviónica sobrecargado. Comprueba si se están transmitiendo los registros. Reinicia la aeronave para restaurar", + "fr": "Systèmes avioniques surchargés. Vérifiez si les journaux sont transmis. Redémarrez l'appareil pour restaurer", + "it": "", + "ja": "航空電子システム過負荷状態。ログが伝送中か確認してください。復元するには機体を再起動してください", + "ko": "항공전자 시스템 과부하. 로그가 전송되고 있는지 확인하세요. 복원하려면 기체를 재시작하세요", + "pt": "", + "ru": "Авиационная электронная система перегружена. Проверьте, передаются ли журналы. Перезагрузите дрон для восстановления", + "tr": "Havacılık Elektroniği sistemi aşırı yüklü. Kayıtların iletilip iletilmediğini kontrol edin. Geri yüklemek için aracı yeniden başlatın", + "zh": "航电系统负载高,请重启飞行器尝试恢复" + }, + "fpv_tip_0x17000071_in_the_sky": { + "de": "Avioniksystem überlastet. Mit Vorsicht fliegen", + "en": "Avionics system overloaded. Fly with caution", + "es": "Sistema de aviónica sobrecargado. Vuela con cuidado", + "fr": "Systèmes avioniques surchargés. Pilotez avec précaution", + "it": "", + "ja": "航空電子システム過負荷状態。慎重に飛行してください", + "ko": "항공전자 시스템 과부하. 비행 시 주의 필요", + "pt": "", + "ru": "Авиационная электронная система перегружена. Будьте внимательны при полете", + "tr": "Havacılık Elektroniği sistemi aşırı yüklü. Dikkatli uçurun", + "zh": "航电系统负载高,请谨慎飞行" + }, + "fpv_tip_0x17000081": { + "de": "Speicher von Avioniksystem unzureichend. Zum Wiederherstellen Fluggerät neu starten", + "en": "Avionics system memory insufficient. Restart aircraft to restore", + "es": "Memoria del sistema de aviónica insuficiente. Reinicia la aeronave para restaurar", + "fr": "Mémoire des systèmes avioniques insuffisante. Redémarrez l\\'appareil pour restaurer", + "it": "", + "ja": "航空電子システムのメモリ不足。機体を再起動して復旧してください", + "ko": "항공전자 시스템 메모리가 부족합니다. 복원하려면 기체를 재시동하세요", + "pt": "", + "ru": "Недостаточно памяти в авиационной электронной системе. Перезапустите дрон для восстановления", + "tr": "Havacılık Elektroniği sistem belleği yetersiz. Geri yüklemek için aracı yeniden başlatın", + "zh": "航电系统内存低,请重启飞行器尝试恢复" + }, + "fpv_tip_0x17000081_in_the_sky": { + "de": "Speicher von Avioniksystem unzureichend. Mit Vorsicht fliegen", + "en": "Avionics system memory insufficient. Fly with caution", + "es": "Memoria del sistema de aviónica insuficiente. Vuela con cuidado", + "fr": "Mémoire des systèmes avioniques insuffisante. Volez avec précaution", + "it": "", + "ja": "航空電子システムのメモリ不足。慎重に飛行してください", + "ko": "항공전자 시스템 메모리가 부족합니다. 주의해서 비행하세요", + "pt": "", + "ru": "Недостаточно памяти в авиационной электронной системе. Будьте внимательны при полете", + "tr": "Havacılık Elektroniği sistem belleği yetersiz. Dikkatli uçurun", + "zh": "航电系统内存低,请谨慎飞行" + }, + "fpv_tip_0x17010021": { + "de": "Fehler: Flugregler. Umgehend zum Startpunkt zurückkehren", + "en": "Flight controller error. Return to home promptly", + "es": "Error del controlador de vuelo. Regresa al punto de origen rápidamente.", + "fr": "Erreur du contrôleur de vol. Revenez au point de départ rapidement", + "ja": "フライトコントローラーエラー。直ちにホームに帰還してください", + "ko": "비행 컨트롤러 오류. 즉시 홈으로 돌아가세요.", + "ru": "Ошибка полетного контроллера. Как можно скорее вернитесь на базу", + "tr": "Uçuş kontrol sistemi hatası. Derhal başlangıç noktasına geri dönün", + "zh": "飞控系统异常,请尽快返航" + }, + "fpv_tip_0x17110041": { + "ar": "", + "de": "", + "en": "Unable to obtain control stick input", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "无法获取遥控器杆量信号", + "zh-Hant": "" + }, + "fpv_tip_0x17110041_in_the_sky": { + "ar": "", + "de": "", + "en": "Control stick input error. Fly with caution and land promptly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "遥控器杆量信号异常,请注意飞行安全,尽快降落", + "zh-Hant": "" + }, + "fpv_tip_0x17200020": { + "ar": "", + "de": "", + "en": "Winch system motor stalled", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电机堵转", + "zh-Hant": "" + }, + "fpv_tip_0x17200022": { + "en": "Winch system motor overloaded", + "zh": "空吊电机过载" + }, + "fpv_tip_0x1720002B": { + "ar": "", + "de": "", + "en": "Winch system ESC overheated", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调温度过高", + "zh-Hant": "" + }, + "fpv_tip_0x1720002C": { + "ar": "", + "de": "", + "en": "Winch system ESC voltage too high", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调电压过高", + "zh-Hant": "" + }, + "fpv_tip_0x1720002D": { + "ar": "", + "de": "", + "en": "Winch system ESC voltage too low", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调电压过低", + "zh-Hant": "" + }, + "fpv_tip_0x1720002F": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200030": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200031": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200032": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200033": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200034": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200035": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200036": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200037": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200038": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200039": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720003A": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720003B": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720003C": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720003D": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720003E": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720003F": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200040": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200041": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200042": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200043": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200044": { + "ar": "", + "de": "", + "en": "Winch system ESC voltage too low", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调电压过低", + "zh-Hant": "" + }, + "fpv_tip_0x17200045": { + "ar": "", + "de": "", + "en": "Winch system ESC voltage too high", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调电压过高", + "zh-Hant": "" + }, + "fpv_tip_0x17200046": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200047": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200048": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200049": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720004A": { + "ar": "", + "de": "", + "en": "Winch system ESC overheated", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调温度过高", + "zh-Hant": "" + }, + "fpv_tip_0x1720004B": { + "ar": "", + "de": "", + "en": "Winch system ESC temperature too low", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调温度过低", + "zh-Hant": "" + }, + "fpv_tip_0x1720004C": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720004D": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720004E": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200055": { + "ar": "", + "de": "", + "en": "Winch system motor may be overheated. Do not quickly reel up and down when aircraft is loaded", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电机存在超温风险,不要反复带载快速收放", + "zh-Hant": "" + }, + "fpv_tip_0x17200056": { + "ar": "", + "de": "", + "en": "Winch system motor severely overheated. Aircraft will land automatically", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电机严重超温,待电机冷却后重启使用", + "zh-Hant": "" + }, + "fpv_tip_0x17200058": { + "ar": "", + "de": "", + "en": "Winch system ESC speed and current error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调转速、电流异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720005D": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720005E": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200077": { + "ar": "", + "de": "", + "en": "Winch system ESC severely overheated", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调严重超温", + "zh-Hant": "" + }, + "fpv_tip_0x17200078": { + "ar": "", + "de": "", + "en": "Winch system ESC severely overheated", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调严重超温", + "zh-Hant": "" + }, + "fpv_tip_0x17200079": { + "ar": "", + "de": "", + "en": "Winch system ESC firmware incompatible with aircraft model", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调固件与飞机机型不匹配", + "zh-Hant": "" + }, + "fpv_tip_0x1720007B": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720007C": { + "ar": "", + "de": "", + "en": "Winch system ESC auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720007D": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720007E": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x1720007F": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200080": { + "ar": "", + "de": "", + "en": "Winch system ESC or motor auto-check error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电调或电机自检异常", + "zh-Hant": "" + }, + "fpv_tip_0x17200083": { + "en": "Winch system ESC calibration failed", + "zh": "空吊电调校准失败" + }, + "fpv_tip_0x17200200": { + "ar": "", + "de": "", + "en": "Cable stuck or reversely reeled in. Enable repair mode to manually unwind cable", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊系统绕线卡塞或反转,请开启检修模式,整理绕线", + "zh-Hant": "" + }, + "fpv_tip_0x17200201": { + "ar": "", + "de": "", + "en": "Winch system pinch protection enabled", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊系统防夹手功能启动", + "zh-Hant": "" + }, + "fpv_tip_0x17200202": { + "ar": "", + "de": "", + "en": "Winch reeling down without payload. Attach payload", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊系统空载放线,请带载放线", + "zh-Hant": "" + }, + "fpv_tip_0x17200203": { + "ar": "", + "de": "", + "en": "Winch system motor not calibrated. Calibrate motor", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊系统电机未校准,请校准再工作", + "zh-Hant": "" + }, + "fpv_tip_0x17200204": { + "ar": "", + "de": "", + "en": "Winch system triaxial force sensor not calibrated. Calibrate sensor", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊系统三向力未校准,请校准再工作", + "zh-Hant": "" + }, + "fpv_tip_0x17200205": { + "ar": "", + "de": "", + "en": "Winch system cable length not calibrated. Calibrate cable length", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊系统绳长未校准,请校准再工作", + "zh-Hant": "" + }, + "fpv_tip_0x17200206": { + "en": "Winch brake hardware damaged. Restart aircraft and try again", + "zh": "空吊系统制动器硬件已损坏,尝试重启后再工作" + }, + "fpv_tip_0x17200207": { + "en": "Winch brake auto-check error. Unable to take off", + "zh": "空吊系统制动器自检异常,无法起飞" + }, + "fpv_tip_0x17200208": { + "en": "Winch cable auto-check error. Check if cable is wound in reverse direction or not secure", + "zh": "空吊系统线绳自检异常,起飞前请确认是否反绕或不在位" + }, + "fpv_tip_0x17200209": { + "en": "Winch limit switch auto-check error. Stop propellers and rotate dial manually. Make sure winch system motor works properly", + "zh": "空吊系统在位开关自检异常,请停桨手动波轮,观察空吊电机是否正常运行" + }, + "fpv_tip_0x1720020A": { + "en": "Winch limit switch error. Check if the switch is stuck or damaged", + "zh": "空吊在位开关功能异常,请检查在位开关是否粘连或损坏" + }, + "fpv_tip_0x17210000": { + "ar": "", + "de": "", + "en": "Parachute sensor error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞传感器异常", + "zh-Hant": "" + }, + "fpv_tip_0x17210001": { + "ar": "", + "de": "", + "en": "Parachute igniter error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞点火器异常", + "zh-Hant": "" + }, + "fpv_tip_0x17210002": { + "ar": "", + "de": "", + "en": "Parachute connection error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞链路异常", + "zh-Hant": "" + }, + "fpv_tip_0x17210003": { + "ar": "", + "de": "", + "en": "Parachute igniter communication error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞点火器通信异常", + "zh-Hant": "" + }, + "fpv_tip_0x17210004": { + "ar": "", + "de": "", + "en": "Parachute igniter connection error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞点火器连接异常", + "zh-Hant": "" + }, + "fpv_tip_0x17210005": { + "ar": "", + "de": "", + "en": "Parachute igniter voltage error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞点火器电压异常", + "zh-Hant": "" + }, + "fpv_tip_0x17210006": { + "ar": "", + "de": "", + "en": "Parachute igniter resistance error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞点火器电阻异常", + "zh-Hant": "" + }, + "fpv_tip_0x17210007": { + "ar": "", + "de": "", + "en": "Parachute ignition error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞点火器点火异常", + "zh-Hant": "" + }, + "fpv_tip_0x17210008": { + "ar": "", + "de": "", + "en": "Parachute IMU communication error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞IMU通信异常", + "zh-Hant": "" + }, + "fpv_tip_0x17210009": { + "ar": "", + "de": "", + "en": "Parachute IMU connection error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞IMU连接异常", + "zh-Hant": "" + }, + "fpv_tip_0x1721000A": { + "ar": "", + "de": "", + "en": "Parachute barometer communication error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞气压计通信异常", + "zh-Hant": "" + }, + "fpv_tip_0x1721000B": { + "ar": "", + "de": "", + "en": "Parachute internal storage error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞机身存储异常", + "zh-Hant": "" + }, + "fpv_tip_0x1721000C": { + "ar": "", + "de": "", + "en": "Parachute control error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞控制链路异常", + "zh-Hant": "" + }, + "fpv_tip_0x1721000D": { + "ar": "", + "de": "", + "en": "Parachute connection error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞融合链路异常", + "zh-Hant": "" + }, + "fpv_tip_0x1721000E": { + "ar": "", + "de": "", + "en": "Parachute speed deviation too large", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞融合速度误差大", + "zh-Hant": "" + }, + "fpv_tip_0x1721000F": { + "ar": "", + "de": "", + "en": "Parachute built-in battery voltage too low", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞内置电池电压过低", + "zh-Hant": "" + }, + "fpv_tip_0x17210010": { + "ar": "", + "de": "", + "en": "Parachute Built-in Battery Overheated", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞内置电池温度过高", + "zh-Hant": "" + }, + "fpv_tip_0x17210011": { + "en": "Parachute File System Error", + "zh": "降落伞文件系统异常" + }, + "fpv_tip_0x17210013": { + "en": "Parachute deployed", + "zh": "降落伞已开伞" + }, + "fpv_tip_0x17210020": { + "ar": "", + "de": "", + "en": "Parachute opened. Watch out for pedestrians nearby", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "降落伞已经开伞,请注意周围行人安全", + "zh-Hant": "" + }, + "fpv_tip_0x19000001": { + "de": "Avioniksystem überlastet. Überprüfen, ob Protokolle übertragen werden. Zum Wiederherstellen Fluggerät neu starten", + "en": "Avionics system overloaded. Check whether logs are being transmitted. Restart aircraft to restore", + "es": "Sistema de aviónica sobrecargado. Comprueba si se están transmitiendo los registros. Reinicia la aeronave para restaurar", + "fr": "Systèmes avioniques surchargés. Vérifiez que les journaux sont bien transmis. Redémarrez l\\'appareil pour restaurer", + "ja": "航空電子システム過負荷状態。ログが伝送されているか確認してください。機体を再起動して復旧してください", + "ko": "항공전자 시스템 과부하. 로그가 전송되고 있는지 확인하세요. 복원하려면 기체를 재시동하세요", + "ru": "Авиационная электронная система перегружена. Проверьте, передаются ли журналы. Перезапустите дрон для восстановления", + "tr": "Havacılık Elektroniği sistemi aşırı yüklü. Kayıtların iletilip iletilmediğini kontrol edin. Geri yüklemek için aracı yeniden başlatın", + "zh": "航电系统负载高,请确认是否正在进行日志回传操作,可以重启飞行器尝试恢复" + }, + "fpv_tip_0x19000001_in_the_sky": { + "de": "Avioniksystem überlastet. Mit Vorsicht fliegen", + "en": "Avionics system overloaded. Fly with caution", + "es": "Sistema de aviónica sobrecargado. Vuela con cuidado", + "fr": "Systèmes avioniques surchargés. Volez avec précaution", + "ja": "航空電子システム過負荷状態。慎重に飛行してください(alarmid)", + "ko": "항공전자 시스템 과부하. 주의해서 비행하세요", + "ru": "Авиационная электронная система перегружена. Будьте внимательны при полете", + "tr": "Havacılık Elektroniği sistemi aşırı yüklü. Dikkatli uçurun", + "zh": "航电系统负载高,请谨慎飞行" + }, + "fpv_tip_0x19000002": { + "de": "Avioniksystem überlastet. Überprüfen, ob Protokolle übertragen werden. Zum Wiederherstellen Fluggerät neu starten", + "en": "Avionics system overloaded. Check whether logs are being transmitted. Restart aircraft to restore", + "es": "Sistema de aviónica sobrecargado. Comprueba si se están transmitiendo los registros. Reinicia la aeronave para restaurar", + "fr": "Systèmes avioniques surchargés. Vérifiez si les journaux sont transmis. Redémarrez l'appareil pour restaurer", + "ja": "航空電子システム過負荷状態。ログが伝送中か確認してください。復元するには機体を再起動してください", + "ko": "항공전자 시스템 과부하. 로그가 전송되고 있는지 확인하세요. 복원하려면 기체를 재시작하세요", + "ru": "Авиационная электронная система перегружена. Проверьте, передаются ли журналы. Перезагрузите дрон для восстановления", + "tr": "Havacılık Elektroniği sistemi aşırı yüklü. Kayıtların iletilip iletilmediğini kontrol edin. Geri yüklemek için aracı yeniden başlatın", + "zh": "航电系统负载高,请确认是否正在进行日志回传操作,可以重启飞行器尝试恢复" + }, + "fpv_tip_0x19000002_in_the_sky": { + "de": "Avioniksystem überlastet. Mit Vorsicht fliegen", + "en": "Avionics system overloaded. Fly with caution", + "es": "Sistema de aviónica sobrecargado. Vuela con cuidado", + "fr": "Systèmes avioniques surchargés. Pilotez avec précaution", + "ja": "航空電子システム過負荷状態。慎重に飛行してください", + "ko": "항공전자 시스템 과부하. 비행 시 주의 필요", + "ru": "Авиационная электронная система перегружена. Будьте внимательны при полете", + "tr": "Havacılık Elektroniği sistemi aşırı yüklü. Dikkatli uçurun", + "zh": "航电系统负载高,请谨慎飞行" + }, + "fpv_tip_0x19000003": { + "ar": "", + "de": "", + "en": "存在业务cpu loading超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "存在业务cpu loading超限", + "zh-Hant": "" + }, + "fpv_tip_0x19000004": { + "ar": "", + "de": "", + "en": "存在业务内存资源使用超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "存在业务内存资源使用超限", + "zh-Hant": "" + }, + "fpv_tip_0x19000005": { + "ar": "", + "de": "", + "en": "中断频率过高", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "中断频率过高", + "zh-Hant": "" + }, + "fpv_tip_0x19000006": { + "ar": "", + "de": "", + "en": "内存申请失败", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "内存申请失败", + "zh-Hant": "" + }, + "fpv_tip_0x19000007": { + "ar": "", + "de": "", + "en": "rt进程cpu loading过高", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "rt进程cpu loading过高", + "zh-Hant": "" + }, + "fpv_tip_0x19000008": { + "ar": "", + "de": "", + "en": "系统内存不足", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "系统内存不足", + "zh-Hant": "" + }, + "fpv_tip_0x19000009": { + "ar": "", + "de": "", + "en": "系统内存严重不足", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "系统内存严重不足", + "zh-Hant": "" + }, + "fpv_tip_0x1900000A": { + "ar": "", + "de": "", + "en": "rcu stall异常", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "rcu stall异常", + "zh-Hant": "" + }, + "fpv_tip_0x1900000B": { + "ar": "", + "de": "", + "en": "进程长期处于D状态", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "进程长期处于D状态", + "zh-Hant": "" + }, + "fpv_tip_0x1900000C": { + "ar": "", + "de": "", + "en": "原子操作异常", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "原子操作异常", + "zh-Hant": "" + }, + "fpv_tip_0x1900000D": { + "ar": "", + "de": "", + "en": "自旋锁操作异常", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "自旋锁操作异常", + "zh-Hant": "" + }, + "fpv_tip_0x19000011": { + "de": "Speicher von Avioniksystem unzureichend. Zum Wiederherstellen Fluggerät neu starten", + "en": "Avionics system memory insufficient. Restart aircraft to restore", + "es": "Memoria del sistema de aviónica insuficiente. Reinicia la aeronave para restaurar", + "fr": "Mémoire des systèmes avioniques insuffisante. Redémarrez l\\'appareil pour restaurer", + "ja": "航空電子システムのメモリ不足。機体を再起動して復旧してください", + "ko": "항공전자 시스템 메모리가 부족합니다. 복원하려면 기체를 재시동하세요", + "ru": "Недостаточно памяти в авиационной электронной системе. Перезапустите дрон для восстановления", + "tr": "Havacılık Elektroniği sistem belleği yetersiz. Geri yüklemek için aracı yeniden başlatın", + "zh": "航电系统内存低,请重启飞行器尝试恢复" + }, + "fpv_tip_0x19000011_in_the_sky": { + "de": "Speicher von Avioniksystem unzureichend. Mit Vorsicht fliegen", + "en": "Avionics system memory insufficient. Fly with caution", + "es": "Memoria del sistema de aviónica insuficiente. Vuela con cuidado", + "fr": "Mémoire des systèmes avioniques insuffisante. Volez avec précaution", + "ja": "航空電子システムのメモリ不足。慎重に飛行してください", + "ko": "항공전자 시스템 메모리가 부족합니다. 주의해서 비행하세요", + "ru": "Недостаточно памяти в авиационной электронной системе. Будьте внимательны при полете", + "tr": "Havacılık Elektroniği sistem belleği yetersiz. Dikkatli uçurun", + "zh": "航电系统内存低,请谨慎飞行" + }, + "fpv_tip_0x19000012": { + "de": "Speicher von Avioniksystem unzureichend. Zum Wiederherstellen Fluggerät neu starten", + "en": "Avionics system memory insufficient. Restart aircraft to restore", + "es": "Memoria del sistema de aviónica insuficiente. Reinicia la aeronave para restaurar", + "fr": "Mémoire des systèmes avioniques insuffisante. Redémarrez l'appareil pour restaurer", + "ja": "航空電子システムのメモリ不足。復元するには機体を再起動してください", + "ko": "항공전자 시스템 메모리가 부족합니다. 복원하려면 기체를 재시작하세요", + "ru": "Недостаточно памяти в авиационной электронной системе. Перезагрузите дрон для восстановления", + "tr": "Havacılık Elektroniği sistem belleği yetersiz. Geri yüklemek için aracı yeniden başlatın", + "zh": "航电系统内存低,请重启飞行器尝试恢复" + }, + "fpv_tip_0x19000012_in_the_sky": { + "de": "Speicher von Avioniksystem unzureichend. Mit Vorsicht fliegen", + "en": "Avionics system memory insufficient. Fly with caution", + "es": "Memoria del sistema de aviónica insuficiente. Vuela con cuidado", + "fr": "Mémoire des systèmes avioniques insuffisante. Pilotez avec précaution", + "ja": "航空電子システムのメモリ不足。慎重に飛行してください", + "ko": "항공전자 시스템 메모리가 부족합니다. 비행 시 주의 필요", + "ru": "Недостаточно памяти в авиационной электронной системе. Будьте внимательны при полете", + "tr": "Havacılık Elektroniği sistem belleği yetersiz. Dikkatli uçurun", + "zh": "航电系统内存低,请谨慎飞行" + }, + "fpv_tip_0x19000020": { + "ar": "", + "de": "", + "en": "camera进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "camera进程异常", + "zh-Hant": "" + }, + "fpv_tip_0x19000021": { + "de": "Fehler: Avioniksystem. Zum Wiederherstellen Fluggerät neu starten", + "en": "Avionics system error. Restart aircraft to restore", + "es": "Error del sistema de aviónica. Reinicia la aeronave para restaurar", + "fr": "Erreur des systèmes avioniques. Redémarrez l\\'appareil pour restaurer", + "ja": "航空電子システムエラー。機体を再起動して復旧してください", + "ko": "항공전자 시스템 오류. 복원하려면 기체를 재시동하세요", + "ru": "Ошибка авиационной электронной системы. Перезапустите дрон для восстановления", + "tr": "Havacılık Elektroniği sistem hatası. Geri yüklemek için aracı yeniden başlatın", + "zh": "相机回放进程异常" + }, + "fpv_tip_0x19000021_in_the_sky": { + "de": "Fehler: Avioniksystem. Mit Vorsicht fliegen", + "en": "Avionics system error. Fly with caution", + "es": "Error del sistema de aviónica. Vuela con cuidado", + "fr": "Erreur des systèmes avioniques. Volez avec précaution", + "ja": "航空電子システムエラー。慎重に飛行してください", + "ko": "항공전자 시스템 오류. 주의해서 비행하세요", + "ru": "Ошибка авиационной электронной системы. Будьте внимательны при полете", + "tr": "Havacılık Elektroniği sistem hatası. Dikkatli uçurun", + "zh": "相机回放进程异常" + }, + "fpv_tip_0x19000022": { + "de": "Fehler: Avioniksystem. Zum Wiederherstellen Fluggerät neu starten", + "en": "Avionics system error. Restart aircraft to restore", + "es": "Error del sistema de aviónica. Reinicia la aeronave para restaurar", + "fr": "Erreur des systèmes avioniques. Redémarrez l'appareil pour restaurer", + "ja": "航空電子システムエラー。復元するには機体を再起動してください", + "ko": "항공전자 시스템 오류. 복원하려면 기체를 재시작하세요", + "ru": "Ошибка авиационной электронной системы. Перезагрузите дрон для восстановления", + "tr": "Havacılık Elektroniği sistem hatası. Geri yüklemek için aracı yeniden başlatın", + "zh": "相机音频进程异常" + }, + "fpv_tip_0x19000022_in_the_sky": { + "de": "Fehler: Avioniksystem. Mit Vorsicht fliegen", + "en": "Avionics system error. Fly with caution", + "es": "Error del sistema de aviónica. Vuela con cuidado", + "fr": "Erreur des systèmes avioniques. Pilotez avec précaution", + "ja": "航空電子システムエラー。慎重に飛行してください", + "ko": "항공전자 시스템 오류. 비행 시 주의 필요", + "ru": "Ошибка авиационной электронной системы. Будьте внимательны при полете", + "tr": "Havacılık Elektroniği sistem hatası. Dikkatli uçurun", + "zh": "相机音频进程异常" + }, + "fpv_tip_0x19000023": { + "ar": "", + "de": "", + "en": "相机麦克风进程异常奔溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "相机麦克风进程异常", + "zh-Hant": "" + }, + "fpv_tip_0x19000024": { + "ar": "", + "de": "", + "en": "相机进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "相机进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x19000025": { + "ar": "", + "de": "", + "en": "相机进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "相机进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x19000026": { + "ar": "", + "de": "", + "en": "相机进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "相机进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x19000027": { + "ar": "", + "de": "", + "en": "相机进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "相机进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x19000028": { + "ar": "", + "de": "", + "en": "嵌入式dji_sys进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "嵌入式dji_sys进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x19000029": { + "ar": "", + "de": "", + "en": "嵌入式日志进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "嵌入式日志进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x1900002A": { + "ar": "", + "de": "", + "en": "嵌入式图传进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "嵌入式图传进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x1900002B": { + "ar": "", + "de": "", + "en": "嵌入式进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "嵌入式进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x1900002C": { + "ar": "", + "de": "", + "en": "嵌入式进程dji_gateway异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "嵌入式进程dji_gateway异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x1900002D": { + "ar": "", + "de": "", + "en": "进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x1900002E": { + "ar": "", + "de": "", + "en": "进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x1900002F": { + "ar": "", + "de": "", + "en": "相机进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "相机进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x19000030": { + "ar": "", + "de": "", + "en": "飞行系统感知进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "飞行系统感知进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x19000031": { + "de": "Abheben nicht möglich. Daten löschen und Fluggerät neu starten", + "en": "Unable to take off. Clear data and restart aircraft", + "es": "No se puede despegar. Borra los datos y reinicia la aeronave", + "fr": "Décollage impossible. Supprimez les données et redémarrez l'appareil", + "ja": "離陸できません。データを消去して、機体を再起動してください", + "ko": "이륙 불가. 데이터 삭제 및 기체 재시작", + "pt": "", + "ru": "Невозможно выполнить взлет. Удалите данные и перезапустите дрон", + "tr": "Kalkış yapılamıyor. Verileri temizle ve aracı yeniden başlat", + "zh": "无法起飞:数据清除完成后需重启飞行器" + }, + "fpv_tip_0x19000031_in_the_sky": { + "de": "Flugzeug nach dem Löschen der Daten neu starten", + "en": "Restart aircraft after clearing data", + "es": "Reinicia la aeronave tras borrar los datos", + "fr": "Redémarrez l'appareil après la suppression des données", + "ja": "データ消去後、機体を再起動してください", + "ko": "데이터 삭제 후 기체 재시작", + "pt": "", + "ru": "Перезапустите дрон после удаления данных", + "tr": "Verileri temizledikten sonra aracı yeniden başlatın", + "zh": "数据清除完成后需重启飞行器" + }, + "fpv_tip_0x19000032": { + "ar": "", + "de": "", + "en": "飞行系统进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "飞行系统进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x19000033": { + "ar": "", + "de": "", + "en": "飞行系统rtk_fusion进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "飞行系统rtk_fusion进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x19000034": { + "ar": "", + "de": "", + "en": "CRobot进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "CRobot进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x19000035": { + "ar": "", + "de": "", + "en": "进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x19000036": { + "ar": "", + "de": "", + "en": "机器学习进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "机器学习进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x19000037": { + "ar": "", + "de": "", + "en": "进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x19000038": { + "ar": "", + "de": "", + "en": "进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x19000039": { + "ar": "", + "de": "", + "en": "电池进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "电池进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x1900003A": { + "ar": "", + "de": "", + "en": "进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x1900003B": { + "ar": "", + "de": "", + "en": "进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x1900003C": { + "ar": "", + "de": "", + "en": "激光雷达进程进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "激光雷达进程进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x1900003D": { + "ar": "", + "de": "", + "en": "进程发生crash,请拉日志分析", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "进程发生crash,请拉日志分析", + "zh-Hant": "" + }, + "fpv_tip_0x1900003E": { + "ar": "", + "de": "", + "en": "System panic", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "系统panic", + "zh-Hant": "" + }, + "fpv_tip_0x1900003F": { + "ar": "", + "de": "", + "en": "进程异常崩溃", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "进程异常崩溃", + "zh-Hant": "" + }, + "fpv_tip_0x19000041": { + "de": "USB-Verbindung erkannt. Kann nicht abheben. USB-Kabel trennen und Fluggerät neu starten", + "en": "USB connection detected. Unable to take off. Disconnect USB cable and restart aircraft", + "es": "Conexión USB detectada. No se puede despegar. Desconecta el cable USB y reinicia la aeronave", + "fr": "Connexion USB détectée. Décollage impossible. Déconnectez le câble USB et redémarrez l\\'appareil", + "ja": "USB接続を検出。離陸できません。USBケーブルを取り外し、機体を再起動してください", + "ko": "USB 연결 감지됨. 이륙 불가. USB 케이블 연결 해제 후 기체 재시작 필요", + "pt": "", + "ru": "Обнаружено USB-соединение. Взлет невозможен. Отключите USB-кабель и перезапустите дрон", + "tr": "USB bağlantısı tespit edildi. Kalkış yapamıyor. USB kablosunu çıkarın ve aracı yeniden başlatın", + "zh": "无法起飞:连接USB阻飞,请拔下USB后重启飞行器尝试恢复" + }, + "fpv_tip_0x19000041_in_the_sky": { + "de": "USB-Verbindung erkannt. Vorsichtig fliegen und sofort landen", + "en": "USB connection detected. Fly with caution and land promptly", + "es": "Conexión USB detectada. Vuela con precaución y aterriza lo antes posible", + "fr": "Connexion USB détectée. Volez avec précaution et atterrissez rapidement", + "ja": "USB接続を検出。慎重に飛行し、直ちに着陸してください", + "ko": "USB 연결 감지됨. 비행 시 주의 필요. 즉시 착륙 필요", + "pt": "", + "ru": "Обнаружено USB-соединение. Будьте осторожны в полете и приземлитесь как можно скорее", + "tr": "USB bağlantısı tespit edildi. Dikkatli uçurun ve düzgün iniş yapın", + "zh": "连接USB,请谨慎飞行并尽快降落" + }, + "fpv_tip_0x19000042": { + "de": "Abheben nicht möglich. Daten löschen und Fluggerät neu starten", + "en": "Unable to take off. Clear data and restart aircraft", + "es": "No se puede despegar. Borra los datos y reinicia la aeronave", + "fr": "Décollage impossible. Supprimez les données et redémarrez l'appareil", + "ja": "離陸できません。データを消去して、機体を再起動してください", + "ko": "이륙 불가. 데이터 삭제 및 기체 재시작", + "pt": "", + "ru": "Невозможно выполнить взлет. Удалите данные и перезапустите дрон", + "tr": "Kalkış yapılamıyor. Verileri temizle ve aracı yeniden başlat", + "zh": "无法起飞:清除数据阻飞,请数据清除完成后重启飞行器" + }, + "fpv_tip_0x19000042_in_the_sky": { + "de": "Flugzeug nach dem Löschen der Daten neu starten", + "en": "Restart aircraft after clearing data", + "es": "Reinicia la aeronave tras borrar los datos", + "fr": "Redémarrez l'appareil après la suppression des données", + "ja": "データ消去後、機体を再起動してください", + "ko": "데이터 삭제 후 기체 재시작", + "pt": "", + "ru": "Перезапустите дрон после удаления данных", + "tr": "Verileri temizledikten sonra aracı yeniden başlatın", + "zh": "清除数据中,请谨慎飞行并尽快降落" + }, + "fpv_tip_0x19000051": { + "de": "Firmware-Aktualisierung. Kann nicht abheben. Warten, bis das Update abgeschlossen ist", + "en": "Firmware updating. Unable to take off. Wait for update to complete", + "es": "Actualizando firmware. No se puede despegar. Espera a que finalice la actualización", + "fr": "Mise à jour du firmware en cours. Décollage impossible. Attendez la fin de la mise à jour", + "ja": "ファームウェア更新中。離陸できません。更新が完了するのをお待ちください", + "ko": "펌웨어 업데이트 중. 이륙 불가. 완료될 때까지 기다려야 함", + "pt": "", + "ru": "Обновление прошивки. Взлет невозможен. Дождитесь завершения обновления", + "tr": "Yazılım güncelleniyor. Kalkış yapamıyor. Güncellemenin tamamlanmasını bekleyin", + "zh": "无法起飞:固件升级中,请等待固件升级完成" + }, + "fpv_tip_0x19000051_in_the_sky": { + "de": "Firmware-Aktualisierung. Vorsicht fliegen und sofort landen", + "en": "Firmware updating. Fly with caution and land promptly", + "es": "Actualizando firmware. Vuela con precaución y aterriza lo antes posible", + "fr": "Mise à jour du firmware en cours. Volez avec précaution et atterrissez rapidement", + "ja": "ファームウェア更新中。慎重に飛行し、直ちに着陸してください", + "ko": "펌웨어 업데이트 중. 비행 시 주의 및 즉시 착륙 필요", + "pt": "", + "ru": "Обновление прошивки. Будьте осторожны в полете и приземлитесь как можно скорее", + "tr": "Yazılım güncelleniyor. Dikkatli uçurun ve düzgün iniş yapın", + "zh": "固件升级中,请谨慎飞行并尽快降落" + }, + "fpv_tip_0x19000060": { + "ar": "", + "de": "Fehler beim Prüfen der Selinux-Berechtigung", + "en": "Selinux permission check error", + "es": "Error de comprobación de permisos de Selinux", + "fr": "Erreur de vérification de l’autorisation Selinux", + "id": "", + "it": "", + "ja": "Selinux権限チェックエラー", + "ko": "Selinux 권한 확인 오류", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка проверки разрешений Selinux", + "th": "", + "tr": "Selinux izin kontrolü hatası", + "ug": "", + "vi": "", + "zh": "Selinux 权限检查错误", + "zh-Hant": "" + }, + "fpv_tip_0x19000061": { + "ar": "", + "de": "", + "en": "Selinux permission check errors", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "Selinux 权限检查错误", + "zh-Hant": "" + }, + "fpv_tip_0x19000070": { + "de": "Dateisystemfehler. Datei ist möglicherweise beschädigt oder Speicherkarte wurde möglicherweise entfernt. Speicherkarte entnehmen und wieder einsetzen oder Speicherkarte formatieren", + "en": "File system error. File may be damaged or storage card may be removed. Remove and insert storage card or format storage card", + "es": "Error de sistema de archivos. Es posible que el archivo esté dañado o que se haya extraído la tarjeta de almacenamiento. Retira e inserta la tarjeta de almacenamiento o formatea la tarjeta de almacenamiento", + "fr": "Erreur système du fichier. Le fichier peut être endommagé ou la carte de stockage peut être retirée. Retirez et insérez la carte de stockage ou formatez la carte de stockage", + "ja": "ファイルシステムエラーです。ファイルが破損しているか、ストレージカードが取り出されている可能性があります。ストレージカードを取り出して挿入するか、ストレージカードをフォーマットします", + "ko": "파일 시스템 오류. 파일이 손상되었거나 저장 장치 카드를 제거할 수 있습니다. 저장 장치 카드를 제거했다가 삽입하거나 포맷하세요", + "ru": "Ошибка файловой системы. Возможно, файл поврежден или карта памяти извлечена. Извлеките и вставьте карту памяти или отформатируйте карту памяти", + "tr": "Dosya sistem hatası. Dosya zarar görebilir veya depolama kartı çıkarılabilir. Depolama kartını çıkarıp takın veya depolama kartını biçimlendirin", + "zh": "文件系统异常:文件可能损坏或存储卡异常拔出,建议尝试拔插存储卡或格式化" + }, + "fpv_tip_0x190003ED": { + "ar": "", + "de": "", + "en": "dji_wlm_slave cpu loading超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_wlm_slave cpu loading超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003EE": { + "ar": "", + "de": "", + "en": "logd loading 超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "logd loading 超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003EF": { + "ar": "", + "de": "", + "en": "dji_autoflight cpu loading 超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_autoflight cpu loading 超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003F1": { + "ar": "", + "de": "", + "en": "dji_sdrs_agent cpu loading 超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_sdrs_agent cpu loading 超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003F2": { + "ar": "", + "de": "", + "en": "dji_lte cpu loading超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_lte cpu loading超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003F3": { + "ar": "", + "de": "", + "en": "dji_wlm cpu loading超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_wlm cpu loading超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003F5": { + "ar": "", + "de": "", + "en": "dji_nn_server loading超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_nn_server loading超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003F6": { + "ar": "", + "de": "", + "en": "dji_ml cpu loading超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_ml cpu loading超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003F9": { + "ar": "", + "de": "", + "en": "dji_media_server cpu loading 超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_media_server cpu loading 超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003FB": { + "ar": "", + "de": "", + "en": "dji_rcam cpu loading 超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_rcam cpu loading 超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003FC": { + "ar": "", + "de": "", + "en": "dji_camera cpu loading超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_camera cpu loading超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003FD": { + "ar": "", + "de": "", + "en": "dji_perception cpu loading超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_perception cpu loading超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003FE": { + "ar": "", + "de": "", + "en": "dji_blackbox loading超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_blackbox loading超限", + "zh-Hant": "" + }, + "fpv_tip_0x190003FF": { + "ar": "", + "de": "", + "en": "dji_sys loading超限", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dji_sys loading超限", + "zh-Hant": "" + }, + "fpv_tip_0x19000400": { + "ar": "", + "de": "", + "en": "SD异常", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "SD异常", + "zh-Hant": "" + }, + "fpv_tip_0x19000700": { + "de": "Dateisystemfehler. Datei ist möglicherweise beschädigt oder Speicherkarte wurde möglicherweise entfernt. Speicherkarte entnehmen und wieder einsetzen oder Speicherkarte formatieren", + "en": "File system error. File may be damaged or storage card may be removed. Remove and insert storage card or format storage card", + "es": "Error de sistema de archivos. Es posible que el archivo esté dañado o que se haya extraído la tarjeta de almacenamiento. Retira e inserta la tarjeta de almacenamiento o formatea la tarjeta de almacenamiento", + "fr": "File system error. File may be damaged or storage card may be removed. Remove and insert storage card or format storage card", + "ja": "ファイルシステムエラーです。ファイルが破損しているか、ストレージカードが取り出されている可能性があります。ストレージカードを取り出して挿入するか、ストレージカードをフォーマットします", + "ko": "파일 시스템 오류. 파일이 손상되었거나 저장 장치 카드를 제거할 수 있습니다. 저장 장치 카드를 제거했다가 삽입하거나 포맷하세요", + "ru": "Ошибка файловой системы. Возможно, файл поврежден или карта памяти извлечена. Извлеките и вставьте карту памяти или отформатируйте карту памяти", + "tr": "Dosya sistem hatası. Dosya zarar görebilir veya depolama kartı çıkarılabilir. Depolama kartını çıkarıp takın veya depolama kartını biçimlendirin", + "zh": "文件系统异常:文件可能损坏或存储卡异常拔出,建议尝试拔插存储卡或格式化" + }, + "fpv_tip_0x19000701": { + "ar": "", + "de": "", + "en": "磁盘扫描异常", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "磁盘扫描异常", + "zh-Hant": "" + }, + "fpv_tip_0x19000702": { + "ar": "", + "de": "", + "en": "File system error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "文件系统检查异常", + "zh-Hant": "" + }, + "fpv_tip_0x19000703": { + "ar": "", + "de": "", + "en": "SD card not recommended. User experience may be\r\n affected", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "SD卡为非推荐卡,可能会影响使用体验", + "zh-Hant": "" + }, + "fpv_tip_0x19000800": { + "ar": "", + "de": "Fehler des Fluggerätlüfters %index. Überprüfen, ob der Lüfter blockiert ist", + "en": "Aircraft fan %index error. Check whether fan is stalled", + "es": "Error %index del ventilador de la aeronave. Compruebe si el ventilador está atascado", + "fr": "Erreur %index sur le ventilateur de l’appareil. Vérifiez si le ventilateur est bloqué", + "id": "", + "it": "", + "ja": "機体ファン%indexエラー。ファンが停止していないかを確認してください", + "ko": "기체 팬 %index 오류. 팬이 멈췄는지 확인하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка %index вентилятора дрона. Проверьте, не заклинило ли вентилятор", + "th": "", + "tr": "Hava aracı fanı %index hatası. Fanın arızalanarak durup durmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "机身%index号风扇异常,请检查飞行器风扇是否有堵转", + "zh-Hant": "" + }, + "fpv_tip_0x19000801": { + "ar": "", + "de": "Fehler des Kameralüfters. Überprüfen, ob der Lüfter blockiert ist", + "en": "Camera fan error. Check whether fan is stalled", + "es": "Error del ventilador de la cámara. Compruebe si el ventilador está atascado", + "fr": "Erreur sur le ventilateur de la caméra. Vérifiez si le ventilateur est bloqué", + "id": "", + "it": "", + "ja": "カメラファンエラー。ファンが停止していないかを確認してください", + "ko": "카메라 팬 오류. 팬이 멈췄는지 확인하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка вентилятора камеры. Проверьте, не заклинило ли вентилятор", + "th": "", + "tr": "Kamera fanı hatası. Fanın arızalanarak durup durmadığını kontrol edin", + "ug": "", + "vi": "", + "zh": "相机风扇异常,请检查相机风扇是否有堵转", + "zh-Hant": "" + }, + "fpv_tip_0x19000802": { + "de": "Der Kameraprozessor ist überhitzt. Den Kameraprozessor vor Gebrauch abkühlen lassen", + "en": "Camera processor overheated. Wait for camera processor to cool down before use", + "es": "Procesador de la cámara sobrecalentado. Espera a que el procesador de la cámara se enfríe antes de usarlo", + "fr": "Surchauffe du processeur de la caméra. Attendez que le processeur de la caméra refroidisse avant utilisation", + "ja": "カメラプロセッサー高温。使用する前にカメラプロセッサーが冷えるのを待ってください", + "ko": "카메라 프로세서 과열. 카메라 프로세서가 식을 때까지 기다렸다가 사용하세요", + "ru": "Перегрев процессора камеры. Дождитесь охлаждения процессора камеры перед использованием", + "tr": "Kamera işlemcisi aşırı ısındı. Kullanmadan önce kamera işlemcisinin soğumasını bekleyin", + "zh": "相机芯片温度过高,请待冷却后使用" + }, + "fpv_tip_0x19000803": { + "de": "Kamera überhitzt. Die Aufnahme wird bald gestoppt. Die Kamera vor Gebrauch abkühlen lassen", + "en": "Camera overheated. Recording will stop soon. Wait for camera to cool down before use", + "es": "Cámara sobrecalentada. La grabación se detendrá pronto. Espera a que la cámara se enfríe antes de usarla", + "fr": "Surchauffe caméra. L’enregistrement va bientôt s’arrêter. Attendez que la caméra refroidisse avant utilisation", + "ja": "カメラ高温。撮影はすぐに停止します。使用する前にカメラが冷えるのを待ってください", + "ko": "카메라 과열. 녹화가 곧 중단됩니다. 카메라가 식을 때까지 기다렸다가 사용하세요", + "ru": "Камера перегрета. Запись скоро остановится. Дождитесь охлаждения камеры перед использованием", + "tr": "Kamera aşırı ısındı. Kayıt yakında duracak. Kullanmadan önce kameranın soğumasını bekleyin", + "zh": "相机温度过高,将无法录制,请待冷却后使用" + }, + "fpv_tip_0x19000810": { + "ar": "", + "de": "", + "en": "Aircraft in low-power state", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "飞机进入低功耗模式", + "zh-Hant": "" + }, + "fpv_tip_0x19000811": { + "ar": "", + "de": "", + "en": "Air unit in low-power state", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "air unit处于低功耗状态", + "zh-Hant": "" + }, + "fpv_tip_0x19000C00": { + "en": "Connection error between avionics board and radio frequency board. Downward radar and video transmission performance may be affected", + "zh": "航电板与射频板连接异常,可能影响下雷达与图传" + }, + "fpv_tip_0x1900E001": { + "ar": "", + "de": "", + "en": "Log storage space insufficient. Unable to store logs", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "日志空间不足,避免无法存储日志", + "zh-Hant": "" + }, + "fpv_tip_0x1900E002": { + "ar": "", + "de": "", + "en": "Log data missing", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "日志数据丢失", + "zh-Hant": "" + }, + "fpv_tip_0x1900E003": { + "ar": "", + "de": "", + "en": "Log data missing", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "日志数据丢失", + "zh-Hant": "" + }, + "fpv_tip_0x1900E004": { + "ar": "", + "de": "", + "en": "Storage device mounting error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "存储设备挂载异常", + "zh-Hant": "" + }, + "fpv_tip_0x1900F001": { + "ar": "", + "de": "", + "en": "Goggles only support motion controller", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "眼镜只支持穿越摇杆飞行", + "zh-Hant": "" + }, + "fpv_tip_0x19018001": { + "ar": "", + "de": "", + "en": "System in factory mode", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "系统处于工厂模式", + "zh-Hant": "" + }, + "fpv_tip_0x19100041": { + "de": "Livestream-Netzwerkverbindung nicht verfügbar", + "en": "Livestream network connection unavailable", + "es": "Conexión de red de retransmisión en directo no disponible", + "fr": "Connexion au réseau de diffusion en direct indisponible", + "ja": "ライブ配信ネットワークに接続できません", + "ko": "라이브 네트워크 연결 불가", + "ru": "Подключение к прямой трансляции недоступно", + "tr": "Canlı yayın ağ bağlantısı yok", + "zh": "视频直播网络不通" + }, + "fpv_tip_0x19100041_in_the_sky": { + "de": "Keine Livestream-Netzwerkverbindung", + "en": "No livestream network connection", + "es": "No hay conexión de red de retransmisión en directo", + "fr": "Pas de connexion réseau pour diffusion en direct", + "ja": "ライブ配信ネットワーク接続がありません", + "ko": "라이브 스트림 네트워크 연결 없음", + "ru": "Отсутствует подключение к сети для трансляции", + "tr": "Canlı yayın ağ bağlantısı yok", + "zh": "视频直播网络不通" + }, + "fpv_tip_0x19100042": { + "de": "Passwortfehler bei Livestream-Registrierung", + "en": "Livestream registration password error", + "es": "Error de contraseña de registro de retransmisión en directo", + "fr": "Erreur de mot de passe de connexion à la diffusion en direct", + "ja": "ライブ配信登録パスワードエラー", + "ko": "라이브 등록 비밀번호 오류", + "ru": "Ошибка пароля прямой трансляции", + "tr": "Canlı yayın kayıt şifresi hatası", + "zh": "视频直播注册密码错误" + }, + "fpv_tip_0x19100042_in_the_sky": { + "de": "Falsches Livestream-Registrierungspasswort", + "en": "Incorrect livestream registration password", + "es": "Contraseña de registro de retransmisión en directo incorrecta", + "fr": "Mot de passe d'enregistrement de diffusion en direct incorrect", + "ja": "ライブ配信の登録パスワードが正しくありません", + "ko": "라이브 스트림 등록 비밀번호 잘못됨", + "ru": "Неверный пароль для регистрации на трансляцию", + "tr": "Canlı yayın kayıt şifresi yanlış", + "zh": "视频直播注册密码错误" + }, + "fpv_tip_0x19100043": { + "de": "Zeitüberschreitung bei Livestream-Registrierung", + "en": "Livestream registration timed out", + "es": "Se agotó el tiempo de espera de registro de retransmisión en directo", + "fr": "Délai d'inscription à la diffusion en direct expiré", + "ja": "ライブ配信登録 時間切れ", + "ko": "라이브 등록 시간 초과", + "ru": "Время регистрации прямой трансляции", + "tr": "Canlı yayın kaydı zaman aşımına uğradı", + "zh": "视频直播注册超时" + }, + "fpv_tip_0x19100043_in_the_sky": { + "de": "Zeitüberschreitung bei Livestream-Registrierung", + "en": "Livestream registration timed out", + "es": "Se agotó el tiempo de espera de registro de retransmisión en directo", + "fr": "L'enregistrement de diffusion en direct a expiré", + "ja": "ライブ配信の登録がタイムアウトしました", + "ko": "라이브 스트림 등록 시간 초과됨", + "ru": "Время регистрации на трансляцию истекло", + "tr": "Canlı yayın kaydı zaman aşımına uğradı", + "zh": "视频直播注册超时" + }, + "fpv_tip_0x19100044": { + "de": "Verbindung mit Livestream-Kanal %d fehlgeschlagen", + "en": "Livestream channel %d connection failed", + "es": "Error de conexión del canal de retransmisión en directo %d", + "fr": "Connexion au canal %d de diffusion en direct échouée", + "ja": "ライブ配信チャンネル%d 接続失敗", + "ko": "라이브 채널 %d 연결 실패", + "ru": "Не удалось подключиться к каналу прямой трансляции %d", + "tr": "Canlı yayın kanalı %d bağlantısı başarısız", + "zh": "直播通道%d连接失败" + }, + "fpv_tip_0x19100044_in_the_sky": { + "de": "Verbindung zum Livestream-Kanal fehlgeschlagen %d", + "en": "Failed to connect to livestream channel %d", + "es": "Error de conexión al canal de retransmisión en directo %d", + "fr": "Échec de la connexion au canal de diffusion en direct%d", + "ja": "ライブ配信チャンネル%dに接続できませんでした", + "ko": "라이브 스트림 채널 %d에 연결 실패", + "ru": "Не удалось подключиться к каналу прямой трансляции %d", + "tr": "%d canlı yayın kanalına bağlanılamadı", + "zh": "直播通道%d连接失败" + }, + "fpv_tip_0x19100045": { + "de": "Fehlerhafte URL für Livestream-Kanal %d", + "en": "Livestream channel %d URL parameter format error", + "es": "Error de formato del parámetro de URL del canal de retransmisión en directo %d", + "fr": "Erreur de format de paramètres URL %d du canal de diffusion en direct", + "ja": "ライブ配信チャンネル%d URLパラメーター形式エラー", + "ko": "라이브 채널 %d URL 매개변수 형식 오류", + "ru": "Ошибка формата URL-адреса канала прямой трансляции %d", + "tr": "Canlı yayın kanalı %d URL parametresi format hatası", + "zh": "直播通道%d URL参数格式错误" + }, + "fpv_tip_0x19100045_in_the_sky": { + "de": "Livestream-Kanal %d Fehler: URL-Parameterformat", + "en": "Livestream channel %d URL parameter format error", + "es": "Error de formato del parámetro de URL del canal de retransmisión en directo %d", + "fr": "Canal de diffusion en direct%d Erreur de format de paramètre d'URL", + "ja": "ライブ配信チャンネル%dのURLパラメーターのフォーマットエラー", + "ko": "라이브 스트림 채널 %d URL 매개변수 포맷 오류", + "ru": "Ошибка формата параметра URL канала прямой трансляции %d", + "tr": "%d canlı yayın kanalı URL parametresi biçim hatası", + "zh": "直播通道%d URL参数格式错误" + }, + "fpv_tip_0x19100051": { + "de": "Zeitüberschreitung bei Auswahl von Livestream-Kanal %d", + "en": "Selecting livestream channel %d timed out", + "es": "Se agotó el tiempo de espera de selección del canal de retransmisión en directo %d", + "fr": "Délai de sélection du canal de diffusion en direct %d expiré", + "ja": "ライブ配信チャンネル%dの選択 時間切れ", + "ko": "라이브 채널 %d 선택 시간 초과", + "ru": "Истекло время ожидания %d при выборе канала прямой трансляции", + "tr": "Canlı yayın kanalı %d seçimi zaman aşımına uğradı", + "zh": "直播通道%d点播超时" + }, + "fpv_tip_0x19100051_in_the_sky": { + "de": "Livestream-Kanal %d Zeitüberschreitung", + "en": "Livestream channel %d timed out", + "es": "Se agotó el tiempo de espera %d del canal de retransmisión en directo", + "fr": "Canal de diffusion en direct%d arrivé à expiration", + "ja": "ライブ配信チャンネル%dがタイムアウトしました", + "ko": "라이브 스트림 채널 %d 시간 초과됨", + "ru": "Превышение времени ожидания канала прямой трансляции %d", + "tr": "%d canlı yayın kanalı zaman aşımına uğradı", + "zh": "直播通道%d点播超时" + }, + "fpv_tip_0x19100052": { + "de": "Auswahl des Livestream-Kanals %d. Parameterfehler", + "en": "Selecting livestream channel %d. Parameters error", + "es": "Parámetros erróneos al seleccionar el canal de retransmisión en directo %d", + "fr": "Erreur de sélection des paramètres %d du canal de diffusion en direct", + "ja": "ライブ配信チャンネル%dの選択 パラメーターエラー", + "ko": "라이브 채널 %d 선택. 매개변수 오류", + "ru": "Выбор канала прямой трансляции %d. Ошибка параметров", + "tr": "Canlı yayın kanalı %d seçiliyor. Parametre hatası", + "zh": "直播通道%d点播参数错误" + }, + "fpv_tip_0x19100052_in_the_sky": { + "de": "Livestream-Kanal %d Parameterfehler", + "en": "Livestream channel %d parameter error", + "es": "Error del parámetro del canal de retransmisión en directo %d", + "fr": "Canal de diffusion en direct %d Erreur de paramètre", + "ja": "ライブ配信チャンネル%dのパラメーターのエラー", + "ko": "라이브 스트림 채널 %d 매개변수 오류", + "ru": "Ошибка параметра канала прямой трансляции %d", + "tr": "%d canlı yayın kanalı parametre hatası", + "zh": "直播通道%d点播参数错误" + }, + "fpv_tip_0x19100053": { + "de": "Keine Antwort bei Auswahl von Livestream-Kanal %d", + "en": "Selecting livestream channel %d received no response", + "es": "No se ha recibido respuesta al seleccionar el canal de retransmisión en directo %d", + "fr": "Aucune réponse de la sélection du canal %d de diffusion en direct", + "ja": "ライブ配信チャンネル%dの選択 反応なし", + "ko": "라이브 채널 %d 선택 응답 없음", + "ru": "Выбор канала прямой трансляции %d не получил ответа", + "tr": "Canlı yayın kanalı %d seçimi için yanıt alınamadı", + "zh": "直播通道%d点播未响应" + }, + "fpv_tip_0x19100053_in_the_sky": { + "de": "Livestream-Kanal %d Zeitüberschreitung", + "en": "Livestream channel %d timed out", + "es": "Se agotó el tiempo de espera %d del canal de retransmisión en directo", + "fr": "Canal de diffusion en direct%d arrivé à expiration", + "ja": "ライブ配信チャンネル%dがタイムアウトしました", + "ko": "라이브 스트림 채널 %d 시간 초과됨", + "ru": "Превышение времени ожидания канала прямой трансляции %d", + "tr": "%d canlı yayın kanalı zaman aşımına uğradı", + "zh": "直播通道%d点播未响应" + }, + "fpv_tip_0x19100054": { + "de": "删除", + "en": "删除", + "es": "删除", + "fr": "删除", + "ja": "删除", + "ko": "删除", + "ru": "删除", + "tr": "删除", + "zh": "直播通道%d长时间未有点播" + }, + "fpv_tip_0x19100054_in_the_sky": { + "de": "Livestream-Kanal %d Zeitüberschreitung", + "en": "Livestream channel %d timed out", + "es": "Se agotó el tiempo de espera %d del canal de retransmisión en directo", + "fr": "Canal de diffusion en direct%d arrivé à expiration", + "ja": "ライブ配信チャンネル%dがタイムアウトしました", + "ko": "라이브 스트림 채널 %d 시간 초과됨", + "ru": "Превышение времени ожидания канала прямой трансляции %d", + "tr": "%d canlı yayın kanalı zaman aşımına uğradı", + "zh": "直播通道%d长时间未有点播" + }, + "fpv_tip_0x19100055": { + "de": "Livestream-Kanal %d ausgewählt. Keine Streaming-Daten", + "en": "Livestream channel %d successfully selected. No streaming data", + "es": "Canal de retransmisión en directo %d seleccionado correctamente. No hay datos de streaming", + "fr": "Canal de diffusion en direct %d sélectionné. Aucune donnée de diffusion", + "ja": "ライブ配信チャンネル%d選択済。配信データがありません", + "ko": "라이브 채널 %d 선택 성공. 스트림 데이터 없음", + "ru": "Канал прямой трансляции %d успешно выбран. Нет потоковых данных", + "tr": "Canlı yayın kanalı %d başarıyla seçildi. Canlı yayın verisi yok", + "zh": "直播通道%d点播成功,无视频流数据" + }, + "fpv_tip_0x19100055_in_the_sky": { + "de": "Livestream-Kanal %d verbunden. Noch keine Streaming-Daten", + "en": "Livestream channel %d connected. No streaming data yet", + "es": "Canal de retransmisión en directo %d conectado. Aún no hay datos de streaming", + "fr": "Canal de diffusion en direct %d connecté. Pas encore de données de streaming", + "ja": "ライブ配信チャンネル%dに接続しました。配信データはまだありません", + "ko": "라이브 스트림 채널 %d 연결됨. 아직 스트리밍 데이터가 없습니다.", + "ru": "Канал прямой трансляции %d подключен. Отсутствуют потоковые данные.", + "tr": "%d canlı yayın kanalı bağlı. Henüz canlı yayın verisi yok", + "zh": "直播通道%d点播成功,但未有视频流发送" + }, + "fpv_tip_0x19100056": { + "de": "Bitratenfehler bei Livestream-Kanal %d", + "en": "Livestream channel %d bit rate error", + "es": "Error de tasa de bits del canal de retransmisión en directo %d", + "fr": "Erreur de débit binaire du canal %d de diffusion en direct", + "ja": "ライブ配信チャンネル%d ビットレート エラー", + "ko": "라이브 채널 %d 비트전송률 오류", + "ru": "Ошибка скорости передачи %d канала прямой трансляции", + "tr": "Canlı yayın kanalı %d bit hızı hatası", + "zh": "直播通道%d直播码率异常" + }, + "fpv_tip_0x19100056_in_the_sky": { + "de": "Livestream-Kanal %d Bit-Ratenfehler", + "en": "Livestream channel %d bit rate error", + "es": "Error de tasa de bits del canal de retransmisión en directo %d", + "fr": "Canal de diffusion en direct %d Erreur de débit", + "ja": "ライブ配信チャンネル%dのビットレートエラー", + "ko": "라이브 스트림 채널 %d 비트 속도 오류", + "ru": "Ошибка скорости передачи канала прямой трансляции %d", + "tr": "%d canlı yayın kanalı bit hızı hatası", + "zh": "直播通道%d直播码率过大或者过小" + }, + "fpv_tip_0x19100057": { + "de": "Bildratenfehler bei Livestream-Kanal %d", + "en": "Livestream channel %d frame rate error", + "es": "Error de ratio de fotogramas del canal de retransmisión en directo %d", + "fr": "Erreur de taux de rafraîchissement du canal %d de diffusion en direct", + "ja": "ライブ配信チャンネル%d フレームレート エラー", + "ko": "라이브 채널 %d 프레임 속도 오류", + "ru": "Ошибка частоты кадров %d канала прямой трансляции", + "tr": "Canlı yayın kanalı %d kare hızı hatası", + "zh": "直播通道%d直播帧率异常" + }, + "fpv_tip_0x19100057_in_the_sky": { + "de": "Livestream-Kanal %d Bildratenfehler", + "en": "Livestream channel %d frame rate error", + "es": "Error de ratio de fotogramas del canal de retransmisión en directo %d", + "fr": "Canal de diffusion en direct %d Erreur de taux de rafraichissement", + "ja": "ライブ配信チャンネル%dのフレームレートエラー", + "ko": "라이브 스트림 채널 %d 프레임 속도 오류", + "ru": "Ошибка частоты кадров канала прямой трансляции %d", + "tr": "%d canli yayın kanalı kare hızı hatası", + "zh": "直播通道%d直播帧率过大或者过小" + }, + "fpv_tip_0x19100058": { + "de": "Fehler beim Senden der Daten von Livestream-Kanal %d", + "en": "Livestream channel %d data sending error", + "es": "Error de envío de datos del canal de retransmisión en directo %d", + "fr": "Erreur d'envoi de données du canal %d de diffusion en direct", + "ja": "ライブ配信チャンネル%d データ送信エラー", + "ko": "라이브 채널 %d 데이터 전송 오류", + "ru": "Ошибка отправки данных канала прямой трансляции %d", + "tr": "Canlı yayın kanalı %d veri gönderme hatası", + "zh": "直播通道%d视频数据发送失败" + }, + "fpv_tip_0x19100058_in_the_sky": { + "de": "Daten des Livestream-Kanals %d konnten nicht gesendet werden", + "en": "Failed to send livestream channel %d data", + "es": "Error al enviar los datos del canal de retransmisión en directo %d", + "fr": "Échec de l'envoi des données du canal de diffusion %d en direct", + "ja": "ライブ配信チャンネル%dのデータの送信に失敗しました", + "ko": "라이브 스트림 채널 %d 데이터 전송 실패", + "ru": "Не удалось отправить данные канала прямой трансляции %d", + "tr": "%d canlı yayın kanalı verileri gönderilemedi", + "zh": "直播通道%d视频数据发送失败" + }, + "fpv_tip_0x19100071": { + "de": "Datenpaket für Livestream-Kanal %d verloren", + "en": "Livestream channel %d losing data packet", + "es": "Pérdida de paquete de datos en el canal de retransmisión en directo %d", + "fr": "Perte de paquet de données du canal %d de diffusion en direct", + "ja": "ライブ配信チャンネル%d データパケットロス発生中", + "ko": "라이브 채널 %d 유실 데이터 패킷", + "ru": "Потеря пакета даных канала передачи %d", + "tr": "Canlı yayın kanalı %d veri paketi kaybı", + "zh": "直播通道%d网络持续丢包" + }, + "fpv_tip_0x19100071_in_the_sky": { + "de": "Livestream-Kanal %d Paketverlust", + "en": "Livestream channel %d packet loss", + "es": "Pérdida de paquete en el canal de retransmisión en directo %d", + "fr": "Perte de paquets du canal de diffusion %d en direct", + "ja": "ライブ配信チャンネル%dのパケット損失", + "ko": "라이브 스트림 채널 %d 패킷 손실", + "ru": "Потеря пакетов канала прямой трансляции %d", + "tr": "%d canlı yayın kanalı paket kaybı", + "zh": "直播通道%d网络持续丢包" + }, + "fpv_tip_0x19100072": { + "de": "Hohe Netzwerklatenz bei Livestream-Kanal %d", + "en": "Livestream channel %d experiencing high network latency", + "es": "Alta latencia de red en el canal de retransmisión en directo %d", + "fr": "Forte latence réseau du canal %d de diffusion en direct", + "ja": "ライブ配信チャンネル%dでネットワークの高遅延 発生中", + "ko": "라이브 채널 %d 네트워크 지연율 높음", + "ru": "Большая задержка сети канала прямой трансляции %d", + "tr": "Canlı yayın kanalı %d yüksek oranda ağ gecikmesi yaşıyor", + "zh": "直播通道%d网络延迟大" + }, + "fpv_tip_0x19100072_in_the_sky": { + "de": "Netzwerklatenz auf Livestream-Kanal %d", + "en": "Network latency on livestream channel %d", + "es": "Latencia de red en el canal de retransmisión en directo %d", + "fr": "Latence du réseau sur le canal de diffusion en direct %d", + "ja": "ライブ配信チャネル%dのネットワーク遅延", + "ko": "라이브 스트림 채널 %d의 네트워크 지연율", + "ru": "Сетевая задержка канала прямой трансляции %d", + "tr": "%d canlı yayın kanalında ağ gecikmesi", + "zh": "直播通道%d网络延迟大" + }, + "fpv_tip_0x19100073": { + "de": "Hohe Netzwerkschwankungen bei Livestream-Kanal %d", + "en": "Livestream channel %d experiencing high network jitter", + "es": "Alta inestabilidad de red en el canal de retransmisión en directo %d", + "fr": "Forte gigue réseau du canal %d de diffusion en direct", + "ja": "ライブ配信チャンネル%dで大きなネットワークジッタ発生中", + "ko": "라이브 채널 %d 네트워크 지터 높음", + "ru": "Высокий джиттер сети канала прямой трансляции %d", + "tr": "Canlı yayın kanalı %d yüksek oranda ağ sapması yaşıyor", + "zh": "直播通道%d网络抖动明显" + }, + "fpv_tip_0x19100073_in_the_sky": { + "de": "Netzwerk-Jitter auf Livestream-Kanal %d", + "en": "Network jitter on livestream channel %d", + "es": "Alta inestabilidad de red en el canal de retransmisión en directo %d", + "fr": "Instabilité du réseau sur le canal de diffusion en direct %d", + "ja": "ライブ配信チャネル%dのネットワークジッター", + "ko": "라이브 스트림 채널 %d의 네트워크 지터", + "ru": "Джиттер сети на канале прямой трансляции %d", + "tr": "%d canlı yayın kanalında ağ sapması", + "zh": "直播通道%d网络抖动明显" + }, + "fpv_tip_0x19100074": { + "de": "Netzwerküberlastung bei Livestream-Kanal %d", + "en": "Livestream channel %d experiencing network congestion", + "es": "Congestión de red en el canal de retransmisión en directo %d", + "fr": "Congestion du réseau du canal %d de diffusion en direct", + "ja": "ライブ配信チャンネル%d ネットワーク輻輳", + "ko": "라이브 채널 %d 네트워크 정체 심함", + "ru": "Перегрузка сети канала прямой трансляции %d", + "tr": "Canlı yayın kanalı %d yüksek oranda ağ trafiği yaşıyor", + "zh": "直播通道%d出现网络拥塞" + }, + "fpv_tip_0x19100074_in_the_sky": { + "de": "Netzwerküberlastung auf Livestream-Kanal %d", + "en": "Network congestion on livestream channel %d", + "es": "Congestión de red en el canal de retransmisión en directo %d", + "fr": "Congestion du réseau sur le canal de diffusion en direct %d", + "ja": "ライブ配信チャネル%dのネットワーク輻輳", + "ko": "라이브 스트림 채널 %d의 네트워크 정체", + "ru": "Перегрузка сети на канале прямой трансляции %d", + "tr": "%d canlı yayın kanalında yüksek oranda ağ trafiği", + "zh": "直播通道%d出现网络拥塞" + }, + "fpv_tip_0x19100081": { + "de": "Fehler bei der Übertragung von Livestream-Metadaten", + "en": "Livestream metadata transfer frequency error", + "es": "Error de frecuencia de transferencia de metadatos de retransmisión en directo", + "fr": "Erreur de fréquence de transfert des métadonnées de la diffusion en direct", + "ja": "ライブ配信メタデータ伝送周波数エラー", + "ko": "라이브 메타데이터 전송 주파수 오류", + "ru": "Ошибка частоты передачи метаданных трансляции", + "tr": "Canlı yayın meta veri aktarım frekansı hatası", + "zh": "视频直播扩展数据回传频率异常" + }, + "fpv_tip_0x19100081_in_the_sky": { + "de": "Fehler: Übertragungsfrequenz der Livestream-Metadaten", + "en": "Livestream metadata transfer frequency error", + "es": "Error de frecuencia de transferencia de metadatos de retransmisión en directo", + "fr": "Erreur de fréquence lors du transfert de métadonnées pour la diffusion en direct", + "ja": "ライブ配信メタデータの転送頻度エラー", + "ko": "라이브 스트림 메타데이터 전송 주파수 오류", + "ru": "Ошибка частоты передачи метаданных прямой трансляции", + "tr": "Canlı yayın meta veri aktarım frekansı hatası", + "zh": "视频直播扩展数据回传频率异常" + }, + "fpv_tip_0x19100082": { + "de": "Livestream kann keine Metadaten abrufen", + "en": "Livestream unable to get metadata", + "es": "La retransmisión en directo no puede obtener los metadatos", + "fr": "Impossible d'obtenir les métadonnéees de la diffusion en direct", + "ja": "ライブ配信がメタデータを取得できません", + "ko": "라이브 메타데이터 가져올 수 없음", + "ru": "Ошибка получения метаданных трансляции", + "tr": "Canlı yayın meta verileri alamıyor", + "zh": "视频直播未收到扩展数据" + }, + "fpv_tip_0x19100082_in_the_sky": { + "de": "Metadaten konnten nicht gesendet werden", + "en": "Failed to send metadata", + "es": "Error al enviar los metadatos", + "fr": "Échec de l'envoi des métadonnées", + "ja": "メタデータの送信に失敗しました", + "ko": "메타데이터 전송 실패", + "ru": "Не удалось отправить метаданные", + "tr": "Meta veri gönderilemedi", + "zh": "视频直播未收到扩展数据" + }, + "fpv_tip_0x19100083": { + "de": "Livestream kann den Standort des Fluggeräts nicht ermitteln", + "en": "Livestream unable to get aircraft location", + "es": "La retransmisión en directo no puede obtener la ubicación de la aeronave", + "fr": "Impossible d'obtenir la localisation de l'appareil pendant la diffusion en direct", + "ja": "ライブ配信が機体位置を取得できません", + "ko": "라이브 기체 위치 가져올 수 없음", + "ru": "Невозможно определить местоположение дрона во время прямой трансляции", + "tr": "Canlı yayın araç konumunu alamıyor", + "zh": "视频直播无法获取无人机位置" + }, + "fpv_tip_0x19100083_in_the_sky": { + "de": "Informationen zur Position des Fluggeräts konnten nicht gesendet werden", + "en": "Failed to send aircraft location info", + "es": "Error al enviar la información de ubicación de la aeronave", + "fr": "Échec de l'envoi des informations de localisation de l'appareil", + "ja": "機体の位置情報の送信に失敗しました", + "ko": "기체 위치 정보 전송 실패", + "ru": "Не удалось отправить информацию о местоположении дрона", + "tr": "Araç konum bilgileri gönderilemedi", + "zh": "视频直播无法获取无人机位置" + }, + "fpv_tip_0x19200001": { + "de": "CPU-Auslastung des Nutzlastsystems zu hoch. Fluggerät neu starten", + "en": "Payload system CPU usage too high. Restart aircraft to restore", + "es": "Uso de la CPU del sistema del instrumento demasiado alto. Reinicia la aeronave para restaurar", + "fr": "Utilisation CPU du système de charge utile trop élevée. Redémarrez l'appareil pour restaurer", + "ja": "ペイロードシステムのCPU使用率が高すぎます。機体を再起動してリストアしてください", + "ko": "페이로드 시스템 CPU 사용량 높음. 기체 재시작해 복원", + "ru": "Слишком высокая загрузка CPU системы полезной нагрузки. Перезагрузите дрон для восстановления", + "tr": "Yük sistem CPU kullanımı çok yüksek. Geri yüklemek için aracı yeniden başlatın", + "zh": "负载系统CPU负载高,请重启飞行器尝试恢复" + }, + "fpv_tip_0x19200001_in_the_sky": { + "de": "CPU-Auslastung des Nutzlastsystems zu hoch. Kamerafunktion kann beeinträchtigt sein", + "en": "Payload system CPU usage too high. Camera tasks may be affected", + "es": "Uso de la CPU del sistema del instrumento demasiado alto. Las tareas de cámara pueden verse afectadas", + "fr": "Utilisation CPU du système de charge utile trop élevée. Les tâches de la caméra peuvent en être impactées", + "ja": "ペイロードシステムのCPU使用率が高すぎます。カメラのタスクが影響を受ける可能性があります", + "ko": "페이로드 시스템 CPU 사용량 높음. 카메라 작업에 영향 줄 수 있음", + "ru": "Слишком высокая загрузка CPU системы полезной нагрузки. Это может повлиять на работу камеры", + "tr": "Yük sistem CPU kullanımı çok yüksek. Kamera görevleri etkilenebilir", + "zh": "负载系统CPU负载高,可能影响作业" + }, + "fpv_tip_0x19200011": { + "de": "Nutzlast-Systemspeicher fast voll ausgelastet. Fluggerät neu starten", + "en": "Payload system memory low. Restart aircraft to restore", + "es": "Sistema del instrumento con poca memoria. Reinicia la aeronave para restaurar", + "fr": "Mémoire du système de charge utile faible. Redémarrez l'appareil pour restaurer", + "ja": "ペイロードシステムがメモリ不足。機体を再起動してリストアしてください", + "ko": "페이로드 시스템 메모리 부족. 기체 재시작해 복원", + "ru": "Недостаточно системной памяти полезной нагрузки. Перезагрузите дрон для восстановления", + "tr": "Yük sistem belleği düşük. Geri yüklemek için aracı yeniden başlatın", + "zh": "负载系统内存低,请重启飞行器尝试恢复" + }, + "fpv_tip_0x19200011_in_the_sky": { + "de": "Speicher des Nutzlastsystems fast voll. Kamerafunktion kann beeinträchtigt sein", + "en": "Payload system low on memory. Camera tasks may be affected", + "es": "Sistema del instrumento con poca memoria. Las tareas de cámara pueden verse afectadas", + "fr": "Mémoire du système de charge utile faible. Les tâches de la caméra peuvent en être impactées", + "ja": "ペイロードシステムがメモリ不足。カメラのタスクが影響を受ける可能性があります", + "ko": "페이로드 시스템 메모리 부족. 카메라 작업에 영향 줄 수 있음", + "ru": "Системе полезной нагрузки не хватает памяти. Это может повлиять на работу камеры", + "tr": "Yük sistem belleği düşük. Kamera görevleri etkilenebilir", + "zh": "负载系统内存低,可能影响作业" + }, + "fpv_tip_0x19200021": { + "de": "Nutzlast-Systemfehler. Fluggerät neu starten", + "en": "Payload system error. Restart aircraft to restore", + "es": "Error del sistema del instrumento. Reinicia la aeronave para restaurar", + "fr": "Erreur du système de charge utile. Redémarrez l'appareil pour restaurer", + "ja": "ペイロード システムエラー。機体を再起動してリストアしてください", + "ko": "페이로드 시스템 오류. 기체 재시작해 복원", + "ru": "Ошибка системы полезной нагрузки. Перезапустите дрон для восстановления", + "tr": "Yük sistem hatası. Geri yüklemek için aracı yeniden başlatın", + "zh": "负载系统异常,请重启飞行器尝试恢复" + }, + "fpv_tip_0x19200021_in_the_sky": { + "de": "Nutzlast-Systemfehler. Kamerafunktion kann beeinträchtigt sein", + "en": "Payload system error. Camera tasks may be affected", + "es": "Error del sistema del instrumento. Las tareas de cámara pueden verse afectadas", + "fr": "Erreur du système de charge utile. Les tâches de la caméra peuvent en être impactées", + "ja": "ペイロード システムエラー。カメラのタスクが影響を受ける可能性があります", + "ko": "페이로드 시스템 오류. 카메라 작업에 영향 줄 수 있음", + "ru": "Ошибка системы полезной нагрузки. Это может повлиять на работу камеры", + "tr": "Yük sistem hatası. Kamera görevleri etkilenebilir", + "zh": "负载系统异常,可能影响作业" + }, + "fpv_tip_0x1A010007": { + "de": "System im Werksmodus. DJI Support kontaktieren", + "en": "System in factory mode. Contact DJI Support", + "es": "Sistema en modo de fábrica. Ponte en contacto con la Asistencia técnica de DJI", + "fr": "Système en mode usine. Contactez le service client DJI", + "ja": "システムが出荷時の初期モードですDJIサポートまでお問い合わせください", + "ko": "시스템이 공장 모드에 있습니다. DJI 고객지원에 문의하세요.", + "ru": "Система в заводском режиме. Обратитесь в службу поддержки DJI", + "tr": "Sistem, fabrika modunda. DJI Destek birimiyle iletişime geçin", + "zh": "当前处于工厂模式,请联系售后维修" + }, + "fpv_tip_0x1A010040": { + "de": "Verbindungsfehler: Nach unten links gerichteter Sichtsensor", + "en": "Downward-left vision sensor connection error", + "es": "Error de conexión del sensor visual inferior izquierdo", + "fr": "Erreur connexion du capteur optique inférieur gauche", + "ja": "左下方ビジョンセンサーの接続エラー", + "ko": "하향 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения левого заднего видеодатчика", + "tr": "Aşağı sol görüş sensörü bağlantı hatası", + "zh": "下视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010041": { + "de": "Verbindungsfehler: Nach unten rechts gerichteter Sichtsensor", + "en": "Downward-right vision sensor connection error", + "es": "Error de conexión del sensor visual inferior derecho", + "fr": "Erreur connexion du capteur optique inférieur droit", + "ja": "右下方ビジョンセンサーの接続エラー", + "ko": "하향 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения правого заднего видеодатчика", + "tr": "Aşağı sağ görüş sensörü bağlantı hatası", + "zh": "下视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010042": { + "de": "Verbindungsfehler: Nach vorne links gerichteter Sichtsensor", + "en": "Forward-left vision sensor connection error", + "es": "Error de conexión del sensor visual frontal izquierdo", + "fr": "Erreur connexion du capteur optique avant gauche", + "ja": "左前方ビジョンセンサーの接続エラー", + "ko": "전방 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения левого переднего видеодатчика", + "tr": "İleri sol görüş sensörü bağlantı hatası", + "zh": "前视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010043": { + "de": "Verbindungsfehler: Nach vorne rechts gerichteter Sichtsensor", + "en": "Forward-right vision sensor connection error", + "es": "Error de conexión del sensor visual frontal derecho", + "fr": "Erreur connexion du capteur optique avant droit", + "ja": "右前方ビジョンセンサーの接続エラー", + "ko": "전방 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения правого переднего видеодатчика", + "tr": "İleri sağ görüş sensörü bağlantı hatası", + "zh": "前视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010044": { + "de": "Verbindungsfehler: Nach hinten links gerichteter Sichtsensor", + "en": "Backward-left vision sensor connection error", + "es": "Error de conexión del sensor visual trasero izquierdo", + "fr": "Erreur connexion du capteur optique arrière gauche", + "ja": "左後方ビジョンセンサーの接続エラー", + "ko": "후방 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения левого заднего видеодатчика", + "tr": "Geri sol görüş sensörü bağlantı hatası", + "zh": "后视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010045": { + "de": "Verbindungsfehler: Nach hinten rechts gerichteter Sichtsensor", + "en": "Backward-right vision sensor connection error", + "es": "Error de conexión del sensor visual trasero derecho", + "fr": "Erreur connexion du capteur optique arrière droit", + "ja": "右後方ビジョンセンサーの接続エラー", + "ko": "후방 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения правого заднего видеодатчика", + "tr": "Geri sağ görüş sensörü bağlantı hatası", + "zh": "后视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010046": { + "de": "Verbindungsfehler: Nach oben links gerichteter Sichtsensor", + "en": "Upward-left vision sensor connection error", + "es": "Error de conexión del sensor visual superior izquierdo", + "fr": "Erreur connexion du capteur optique supérieur gauche", + "ja": "左上方ビジョンセンサーの接続エラー", + "ko": "상향 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения левого верхнего видеодатчика", + "tr": "Yukarı sol görüş sensörü bağlantı hatası", + "zh": "上视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010047": { + "de": "Verbindungsfehler: Nach oben rechts gerichteter Sichtsensor", + "en": "Upward-right vision sensor connection error", + "es": "Error de conexión del sensor visual superior derecho", + "fr": "Erreur connexion du capteur optique supérieur droit", + "ja": "右上方ビジョンセンサーの接続エラー", + "ko": "상향 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения правого верхнего видеодатчика", + "tr": "Yukarı sağ görüş sensörü bağlantı hatası", + "zh": "上视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010048": { + "de": "Verbindungsfehler: Nach hinten links gerichteter Sichtsensor. Bitte mit erhöhter Vorsicht fliegen", + "en": "Left-rear vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual izquierdo trasero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique arrière gauche. Volez avec précaution", + "ja": "後部左ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "좌측 후면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения левого заднего видеодатчика. Будьте осторожны", + "tr": "Sol arka görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "左视后部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A010049": { + "de": "Verbindungsfehler: Nach vorne links gerichteter Sichtsensor. Bitte mit erhöhter Vorsicht fliegen", + "en": "Left-front vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual izquierdo delantero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique avant gauche. Volez avec précaution", + "ja": "前部左ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "좌측 전면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения левого переднего видеодатчика. Будьте осторожны", + "tr": "Sol ön görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "左视前部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A01004A": { + "de": "Verbindungsfehler: Nach vorne rechts gerichteter Sichtsensor. Bitte mit erhöhter Vorsicht fliegen", + "en": "Right-front vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual derecho delantero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique avant droit. Volez avec précaution", + "ja": "前部右ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "우측 전면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения правого переднего видеодатчика. Будьте осторожны", + "tr": "Sağ ön görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "右视前部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A01004B": { + "de": "Verbindungsfehler: Nach hinten rechts gerichteter Sichtsensor. Bitte mit erhöhter Vorsicht fliegen", + "en": "Right-rear vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual derecho trasero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique arrière droit. Volez avec précaution", + "ja": "後部右ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "우측 후면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения правого заднего видеодатчика. Будьте осторожны", + "tr": "Sağ arka görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "右视后部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A010080": { + "de": "Verbindungsfehler: Nach unten links gerichteter Sichtsensor", + "en": "Downward-left vision sensor connection error", + "es": "Error de conexión del sensor visual inferior izquierdo", + "fr": "Erreur connexion du capteur optique inférieur gauche", + "ja": "左下方ビジョンセンサーの接続エラー", + "ko": "하향 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения нижнего левого датчика обзора", + "tr": "Aşağı sol görüş sensörü bağlantı hatası", + "zh": "下视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010081": { + "de": "Verbindungsfehler: Nach unten rechts gerichteter Sichtsensor", + "en": "Downward-right vision sensor connection error", + "es": "Error de conexión del sensor visual inferior derecho", + "fr": "Erreur connexion du capteur optique inférieur droit", + "ja": "右下方ビジョンセンサーの接続エラー", + "ko": "하향 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения нижнего правого датчика обзора", + "tr": "Aşağı sağ görüş sensörü bağlantı hatası", + "zh": "下视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010082": { + "de": "Verbindungsfehler: Nach vorne links gerichteter Sichtsensor", + "en": "Forward-left vision sensor connection error", + "es": "Error de conexión del sensor visual frontal izquierdo", + "fr": "Erreur connexion du capteur optique avant gauche", + "ja": "左前方ビジョンセンサーの接続エラー", + "ko": "전방 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения переднего левого датчика обзора", + "tr": "İleri sol görüş sensörü bağlantı hatası", + "zh": "前视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010083": { + "de": "Verbindungsfehler: Nach vorne rechts gerichteter Sichtsensor", + "en": "Forward-right vision sensor connection error", + "es": "Error de conexión del sensor visual frontal derecho", + "fr": "Erreur connexion du capteur optique avant droit", + "ja": "右前方ビジョンセンサーの接続エラー", + "ko": "전방 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения переднего правого датчика обзора", + "tr": "İleri sağ görüş sensörü bağlantı hatası", + "zh": "前视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010084": { + "de": "Verbindungsfehler: Nach hinten links gerichteter Sichtsensor", + "en": "Backward-left vision sensor connection error", + "es": "Error de conexión del sensor visual trasero izquierdo", + "fr": "Erreur connexion du capteur optique arrière gauche", + "ja": "左後方ビジョンセンサーの接続エラー", + "ko": "후방 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения заднего левого датчика обзора", + "tr": "Geri sol görüş sensörü bağlantı hatası", + "zh": "后视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010085": { + "de": "Verbindungsfehler: Nach hinten rechts gerichteter Sichtsensor", + "en": "Backward-right vision sensor connection error", + "es": "Error de conexión del sensor visual trasero derecho", + "fr": "Erreur connexion du capteur optique arrière droit", + "ja": "右後方ビジョンセンサーの接続エラー", + "ko": "후방 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения заднего правого датчика обзора", + "tr": "Geri sağ görüş sensörü bağlantı hatası", + "zh": "后视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010086": { + "de": "Verbindungsfehler: Nach oben links gerichteter Sichtsensor", + "en": "Upward-left vision sensor connection error", + "es": "Error de conexión del sensor visual superior izquierdo", + "fr": "Erreur connexion du capteur optique supérieur gauche", + "ja": "左上方ビジョンセンサーの接続エラー", + "ko": "상향 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения верхнего левого датчика обзора", + "tr": "Yukarı sol görüş sensörü bağlantı hatası", + "zh": "上视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010087": { + "de": "Verbindungsfehler: Nach oben rechts gerichteter Sichtsensor", + "en": "Upward-right vision sensor connection error", + "es": "Error de conexión del sensor visual superior derecho", + "fr": "Erreur connexion du capteur optique supérieur droit", + "ja": "右上方ビジョンセンサーの接続エラー", + "ko": "상향 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения верхнего правого датчика обзора", + "tr": "Yukarı sağ görüş sensörü bağlantı hatası", + "zh": "上视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A010088": { + "de": "Verbindungsfehler: Nach hinten links gerichteter Sichtsensor. Mit Vorsicht fliegen", + "en": "Left-rear vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual izquierdo trasero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique arrière gauche. Volez avec précaution", + "ja": "後部左ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "좌측 후면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения левого заднего датчика обзора. Будьте внимательны при полете", + "tr": "Sol arka görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "左视后部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A010089": { + "de": "Verbindungsfehler: Nach vorne links gerichteter Sichtsensor. Mit Vorsicht fliegen", + "en": "Left-front vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual izquierdo delantero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique avant gauche. Volez avec précaution", + "ja": "前部左ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "좌측 전면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения левого переднего датчика обзора. Будьте внимательны при полете", + "tr": "Sol ön görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "左视前部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A01008A": { + "de": "Verbindungsfehler: Nach vorne rechts gerichteter Sichtsensor. Mit Vorsicht fliegen", + "en": "Right-front vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual derecho delantero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique avant droit. Volez avec précaution", + "ja": "前部右ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "우측 전면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения правого переднего датчика обзора. Будьте внимательны при полете", + "tr": "Sağ ön görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "右视前部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A01008B": { + "de": "Verbindungsfehler: Nach hinten rechts gerichteter Sichtsensor. Mit Vorsicht fliegen", + "en": "Right-rear vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual derecho trasero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique arrière droit. Volez avec précaution", + "ja": "後部右ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "우측 후면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения правого заднего датчика обзора. Будьте внимательны при полете", + "tr": "Sağ arka görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "右视后部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A0100C0": { + "de": "Verbindungsfehler: Nach unten links gerichteter Sichtsensor", + "en": "Downward-left vision sensor connection error", + "es": "Error de conexión del sensor visual inferior izquierdo", + "fr": "Erreur connexion du capteur optique inférieur gauche", + "ja": "左下方ビジョンセンサーの接続エラー", + "ko": "하향 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения нижнего левого датчика обзора", + "tr": "Aşağı sol görüş sensörü bağlantı hatası", + "zh": "下视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A0100C1": { + "de": "Verbindungsfehler: Nach unten rechts gerichteter Sichtsensor", + "en": "Downward-right vision sensor connection error", + "es": "Error de conexión del sensor visual inferior derecho", + "fr": "Erreur connexion du capteur optique inférieur droit", + "ja": "右下方ビジョンセンサーの接続エラー", + "ko": "하향 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения нижнего правого датчика обзора", + "tr": "Aşağı sağ görüş sensörü bağlantı hatası", + "zh": "下视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A0100C2": { + "de": "Verbindungsfehler: Nach vorne links gerichteter Sichtsensor", + "en": "Forward-left vision sensor connection error", + "es": "Error de conexión del sensor visual frontal izquierdo", + "fr": "Erreur connexion du capteur optique avant gauche", + "ja": "左前方ビジョンセンサーの接続エラー", + "ko": "전방 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения переднего левого датчика обзора", + "tr": "İleri sol görüş sensörü bağlantı hatası", + "zh": "前视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A0100C3": { + "de": "Verbindungsfehler: Nach vorne rechts gerichteter Sichtsensor", + "en": "Forward-right vision sensor connection error", + "es": "Error de conexión del sensor visual frontal derecho", + "fr": "Erreur connexion du capteur optique avant droit", + "ja": "右前方ビジョンセンサーの接続エラー", + "ko": "전방 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения переднего правого датчика обзора", + "tr": "İleri sağ görüş sensörü bağlantı hatası", + "zh": "前视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A0100C4": { + "de": "Verbindungsfehler: Nach hinten links gerichteter Sichtsensor", + "en": "Backward-left vision sensor connection error", + "es": "Error de conexión del sensor visual trasero izquierdo", + "fr": "Erreur connexion du capteur optique arrière gauche", + "ja": "左後方ビジョンセンサーの接続エラー", + "ko": "후방 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения заднего левого датчика обзора", + "tr": "Geri sol görüş sensörü bağlantı hatası", + "zh": "后视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A0100C5": { + "de": "Verbindungsfehler: Nach hinten rechts gerichteter Sichtsensor", + "en": "Backward-right vision sensor connection error", + "es": "Error de conexión del sensor visual trasero derecho", + "fr": "Erreur connexion du capteur optique arrière droit", + "ja": "右後方ビジョンセンサーの接続エラー", + "ko": "후방 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения заднего правого датчика обзора", + "tr": "Geri sağ görüş sensörü bağlantı hatası", + "zh": "后视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A0100C6": { + "de": "Verbindungsfehler: Nach oben links gerichteter Sichtsensor", + "en": "Upward-left vision sensor connection error", + "es": "Error de conexión del sensor visual superior izquierdo", + "fr": "Erreur connexion du capteur optique supérieur gauche", + "ja": "左上方ビジョンセンサーの接続エラー", + "ko": "상향 좌측 비전 센서 연결 오류", + "ru": "Ошибка подключения верхнего левого датчика обзора", + "tr": "Yukarı sol görüş sensörü bağlantı hatası", + "zh": "上视左侧视觉传感器连接异常" + }, + "fpv_tip_0x1A0100C7": { + "de": "Verbindungsfehler: Nach oben rechts gerichteter Sichtsensor", + "en": "Upward-right vision sensor connection error", + "es": "Error de conexión del sensor visual superior derecho", + "fr": "Erreur connexion du capteur optique supérieur droit", + "ja": "右上方ビジョンセンサーの接続エラー", + "ko": "상향 우측 비전 센서 연결 오류", + "ru": "Ошибка подключения верхнего правого датчика обзора", + "tr": "Yukarı sağ görüş sensörü bağlantı hatası", + "zh": "上视右侧视觉传感器连接异常" + }, + "fpv_tip_0x1A0100C8": { + "de": "Verbindungsfehler: Nach hinten links gerichteter Sichtsensor. Mit Vorsicht fliegen", + "en": "Left-rear vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual izquierdo trasero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique arrière gauche. Volez avec précaution", + "ja": "後部左ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "좌측 후면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения левого заднего датчика обзора. Будьте внимательны при полете", + "tr": "Sol arka görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "左视后部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A0100C9": { + "de": "Verbindungsfehler: Nach vorne links gerichteter Sichtsensor. Mit Vorsicht fliegen", + "en": "Left-front vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual izquierdo delantero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique avant gauche. Volez avec précaution", + "ja": "前部左ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "좌측 전면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения левого переднего датчика обзора. Будьте внимательны при полете", + "tr": "Sol ön görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "左视前部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A0100CA": { + "de": "Verbindungsfehler: Nach vorne rechts gerichteter Sichtsensor. Mit Vorsicht fliegen", + "en": "Right-front vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual derecho delantero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique avant droit. Volez avec précaution", + "ja": "前部右ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "우측 전면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения правого переднего датчика обзора. Будьте внимательны при полете", + "tr": "Sağ ön görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "右视前部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A0100CB": { + "de": "Verbindungsfehler: Nach hinten rechts gerichteter Sichtsensor. Mit Vorsicht fliegen", + "en": "Right-rear vision sensor connection error. Fly with caution", + "es": "Error de conexión del sensor visual derecho trasero. Vuela con cuidado", + "fr": "Erreur de connexion du capteur optique arrière droit. Volez avec précaution", + "ja": "後部右ビジョンセンサーの接続エラー。慎重に飛行してください", + "ko": "우측 후면 비전 센서 연결 오류. 비행 시 주의 필요", + "ru": "Ошибка подключения правого заднего датчика обзора. Будьте внимательны при полете", + "tr": "Sağ arka görüş sensörü bağlantı hatası. Dikkatli uçurun", + "zh": "右视后部视觉传感器连接异常,请谨慎飞行" + }, + "fpv_tip_0x1A011340": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A011341": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A011342": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A011343": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A011344": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A011345": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A011346": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A011347": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A011348": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A011349": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A01134A": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A01134B": { + "de": "Kalibrierungsfehler: Sichtsensoren", + "en": "Vision system calibration error", + "es": "Error de calibración del sistema de visión", + "fr": "Erreur d'étalonnage du système optique", + "ja": "ビジョンシステムのキャリブレーションエラー", + "ko": "비전 시스템 캘리브레이션 오류", + "ru": "Ошибка калибровки системы обзора", + "tr": "Görüş sistemi kalibrasyon hatası", + "zh": "视觉系统标定异常" + }, + "fpv_tip_0x1A020040": { + "de": "Verbindungsfehler: Abwärts gerichteter Infrarotsensor", + "en": "Downward infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos inferior", + "fr": "Erreur connexion du capteur infrarouge inférieur", + "ja": "下方赤外線センサーの接続エラー", + "ko": "하향 적외선 센서 연결 오류", + "ru": "Ошибка подключения нижнего ИК датчика", + "tr": "Aşağı kızılötesi sensör bağlantı hatası", + "zh": "下视红外传感器连接异常" + }, + "fpv_tip_0x1A020041": { + "de": "Verbindungsfehler: Nach vorne gerichteter Infrarotsensor", + "en": "Forward infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos frontal", + "fr": "Erreur connexion du capteur infrarouge avant", + "ja": "前方赤外線センサーの接続エラー", + "ko": "전방 적외선 센서 연결 오류", + "ru": "Ошибка подключения переднего ИК датчика", + "tr": "İleri kızılötesi sensör bağlantı hatası", + "zh": "前视红外传感器连接异常" + }, + "fpv_tip_0x1A020042": { + "de": "Verbindungsfehler: Rechter Infrarotsensor", + "en": "Right infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos derecho", + "fr": "Erreur connexion du capteur infrarouge droit", + "ja": "右赤外線センサーの接続エラー", + "ko": "우측 적외선 센서 연결 오류", + "ru": "Ошибка подключения правого ИК датчика", + "tr": "Sağ kızılötesi sensör bağlantı hatası", + "zh": "右视红外传感器连接异常" + }, + "fpv_tip_0x1A020043": { + "de": "Verbindungsfehler: Nach hinten gerichteter Infrarotsensor", + "en": "Backward infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos trasero", + "fr": "Erreur connexion du capteur infrarouge arrière", + "ja": "後方赤外線センサーの接続エラー", + "ko": "후방 적외선 센서 연결 오류", + "ru": "Ошибка подключения заднего ИК датчика", + "tr": "Geri kızılötesi sensör bağlantı hatası", + "zh": "后视红外传感器连接异常" + }, + "fpv_tip_0x1A020044": { + "de": "Verbindungsfehler: Linker Infrarotsensor", + "en": "Left infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos izquierdo", + "fr": "Erreur connexion du capteur infrarouge gauche", + "ja": "左赤外線センサーの接続エラー", + "ko": "좌측 적외선 센서 연결 오류", + "ru": "Ошибка подключения левого ИК датчика", + "tr": "Sol kızılötesi sensör bağlantı hatası", + "zh": "左视红外传感器连接异常" + }, + "fpv_tip_0x1A020045": { + "de": "Verbindungsfehler: Nach oben gerichteter Infrarotsensor", + "en": "Upward infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos superior", + "fr": "Erreur connexion du capteur infrarouge supérieur", + "ja": "上方赤外線センサーの接続エラー", + "ko": "상향 적외선 센서 연결 오류", + "ru": "Ошибка подключения верхнего ИК датчика", + "tr": "Yukarı kızılötesi sensör bağlantı hatası", + "zh": "上视红外传感器连接异常" + }, + "fpv_tip_0x1A020080": { + "de": "Verbindungsfehler: Nach unten gerichteter Infrarotsensor", + "en": "Downward Infrared Sensor Connection Error", + "es": "Error de conexión del sensor de infrarrojos inferior", + "fr": "Erreur connexion du capteur infrarouge inférieur", + "ja": "下方赤外線センサーの接続エラー", + "ko": "하향 적외선 센서 연결 오류", + "ru": "Ошибка подключения нижнего инфракрасного датчика", + "tr": "Aşağı Kızılötesi Sensör Bağlantı Hatası", + "zh": "下视红外传感器连接异常" + }, + "fpv_tip_0x1A020081": { + "de": "Verbindungsfehler: Nach vorne gerichteter Infrarotsensor", + "en": "Forward infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos frontal", + "fr": "Erreur connexion du capteur infrarouge avant", + "ja": "前方赤外線センサーの接続エラー", + "ko": "전방 적외선 센서 연결 오류", + "ru": "Ошибка подключения переднего инфракрасного датчика", + "tr": "İleri kızılötesi sensör bağlantı hatası", + "zh": "前视红外传感器连接异常" + }, + "fpv_tip_0x1A020082": { + "de": "Verbindungsfehler: Rechter Infrarotsensor", + "en": "Right infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos derecho", + "fr": "Erreur connexion du capteur infrarouge droit", + "ja": "右赤外線センサーの接続エラー", + "ko": "우측 적외선 센서 연결 오류", + "ru": "Ошибка подключения правого инфракрасного датчика", + "tr": "Sağ kızılötesi sensör bağlantı hatası", + "zh": "右视红外传感器连接异常" + }, + "fpv_tip_0x1A020083": { + "de": "Verbindungsfehler: Nach hinten gerichteter Infrarotsensor", + "en": "Backward infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos trasero", + "fr": "Erreur connexion du capteur infrarouge arrière", + "ja": "後方赤外線センサーの接続エラー", + "ko": "후방 적외선 센서 연결 오류", + "ru": "Ошибка подключения заднего инфракрасного датчика", + "tr": "Geri kızılötesi sensör bağlantı hatası", + "zh": "后视红外传感器连接异常" + }, + "fpv_tip_0x1A020084": { + "de": "Verbindungsfehler: Linker Infrarotsensor", + "en": "Left infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos izquierdo", + "fr": "Erreur connexion du capteur infrarouge gauche", + "ja": "左赤外線センサーの接続エラー", + "ko": "좌측 적외선 센서 연결 오류", + "ru": "Ошибка подключения левого инфракрасного датчика", + "tr": "Sol kızılötesi sensör bağlantı hatası", + "zh": "左视红外传感器连接异常" + }, + "fpv_tip_0x1A020085": { + "de": "Verbindungsfehler: Nach oben gerichteter Infrarotsensor", + "en": "Upward infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos superior", + "fr": "Erreur connexion du capteur infrarouge supérieur", + "ja": "上方赤外線センサーの接続エラー", + "ko": "상향 적외선 센서 연결 오류", + "ru": "Ошибка подключения верхнего инфракрасного датчика", + "tr": "Yukarı kızılötesi sensör bağlantı hatası", + "zh": "上视红外传感器连接异常" + }, + "fpv_tip_0x1A0200C0": { + "de": "Verbindungsfehler: Nach unten gerichteter Infrarotsensor", + "en": "Downward Infrared Sensor Connection Error", + "es": "Error de conexión del sensor de infrarrojos inferior", + "fr": "Erreur connexion du capteur infrarouge inférieur", + "ja": "下方赤外線センサーの接続エラー", + "ko": "하향 적외선 센서 연결 오류", + "ru": "Ошибка подключения нижнего инфракрасного датчика", + "tr": "Aşağı Kızılötesi Sensör Bağlantı Hatası", + "zh": "下视红外传感器连接异常" + }, + "fpv_tip_0x1A0200C1": { + "de": "Verbindungsfehler: Nach vorne gerichteter Infrarotsensor", + "en": "Forward infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos frontal", + "fr": "Erreur connexion du capteur infrarouge avant", + "ja": "前方赤外線センサーの接続エラー", + "ko": "전방 적외선 센서 연결 오류", + "ru": "Ошибка подключения переднего инфракрасного датчика", + "tr": "İleri kızılötesi sensör bağlantı hatası", + "zh": "前视红外传感器连接异常" + }, + "fpv_tip_0x1A0200C2": { + "de": "Verbindungsfehler: Rechter Infrarotsensor", + "en": "Right infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos derecho", + "fr": "Erreur connexion du capteur infrarouge droit", + "ja": "右赤外線センサーの接続エラー", + "ko": "우측 적외선 센서 연결 오류", + "ru": "Ошибка подключения правого инфракрасного датчика", + "tr": "Sağ kızılötesi sensör bağlantı hatası", + "zh": "右视红外传感器连接异常" + }, + "fpv_tip_0x1A0200C3": { + "de": "Verbindungsfehler: Nach hinten gerichteter Infrarotsensor", + "en": "Backward infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos trasero", + "fr": "Erreur connexion du capteur infrarouge arrière", + "ja": "後方赤外線センサーの接続エラー", + "ko": "후방 적외선 센서 연결 오류", + "ru": "Ошибка подключения заднего инфракрасного датчика", + "tr": "Geri kızılötesi sensör bağlantı hatası", + "zh": "后视红外传感器连接异常" + }, + "fpv_tip_0x1A0200C4": { + "de": "Verbindungsfehler: Linker Infrarotsensor", + "en": "Left infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos izquierdo", + "fr": "Erreur connexion du capteur infrarouge gauche", + "ja": "左赤外線センサーの接続エラー", + "ko": "좌측 적외선 센서 연결 오류", + "ru": "Ошибка подключения левого инфракрасного датчика", + "tr": "Sol kızılötesi sensör bağlantı hatası", + "zh": "左视红外传感器连接异常" + }, + "fpv_tip_0x1A0200C5": { + "de": "Verbindungsfehler: Nach oben gerichteter Infrarotsensor", + "en": "Upward infrared sensor connection error", + "es": "Error de conexión del sensor de infrarrojos superior", + "fr": "Erreur connexion du capteur infrarouge supérieur", + "ja": "上方赤外線センサーの接続エラー", + "ko": "상향 적외선 센서 연결 오류", + "ru": "Ошибка подключения верхнего инфракрасного датчика", + "tr": "Yukarı kızılötesi sensör bağlantı hatası", + "zh": "上视红外传感器连接异常" + }, + "fpv_tip_0x1A020100": { + "de": "Kalibrierungsfehler: Abwärts gerichteter Infrarotsensor", + "en": "Downward infrared sensor calibration error", + "es": "Error de calibración del sensor de infrarrojos inferior", + "fr": "Erreur étalonnage du capteur infrarouge inférieur", + "ja": "下方赤外線センサーのキャリブレーションエラー", + "ko": "하향 적외선 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки нижнего ИК датчика", + "tr": "Aşağı kızılötesi sensör kalibrasyon hatası", + "zh": "下视红外传感器标定异常" + }, + "fpv_tip_0x1A020101": { + "de": "Kalibrierungsfehler: Nach vorne gerichteter Infrarotsensor", + "en": "Forward infrared sensor calibration error", + "es": "Error de calibración del sensor de infrarrojos frontal", + "fr": "Erreur étalonnage du capteur infrarouge avant", + "ja": "前方赤外線センサーのキャリブレーションエラー", + "ko": "전방 적외선 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки переднего ИК датчика", + "tr": "İleri kızılötesi sensör kalibrasyon hatası", + "zh": "前视红外传感器标定异常" + }, + "fpv_tip_0x1A020102": { + "de": "Kalibrierungsfehler: Rechter Infrarotsensor", + "en": "Right infrared sensor calibration error", + "es": "Error de calibración del sensor de infrarrojos derecho", + "fr": "Erreur étalonnage du capteur infrarouge droit", + "ja": "右赤外線センサーのキャリブレーションエラー", + "ko": "우측 적외선 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки правого ИК датчика", + "tr": "Sağ kızılötesi sensör kalibrasyon hatası", + "zh": "右视红外传感器标定异常" + }, + "fpv_tip_0x1A020103": { + "de": "Kalibrierungsfehler: Nach hinten gerichteter Infrarotsensor", + "en": "Backward infrared sensor calibration error", + "es": "Error de calibración del sensor de infrarrojos trasero", + "fr": "Erreur étalonnage du capteur infrarouge arrière", + "ja": "後方赤外線センサーのキャリブレーションエラー", + "ko": "후방 적외선 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки заднего ИК датчика", + "tr": "Geri kızılötesi sensör kalibrasyon hatası", + "zh": "后视红外传感器标定异常" + }, + "fpv_tip_0x1A020104": { + "de": "Kalibrierungsfehler: Linker Infrarotsensor", + "en": "Left infrared sensor calibration error", + "es": "Error de calibración del sensor de infrarrojos izquierdo", + "fr": "Erreur étalonnage du capteur infrarouge gauche", + "ja": "左赤外線センサーのキャリブレーションエラー", + "ko": "좌측 적외선 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки левого ИК датчика", + "tr": "Sol kızılötesi sensör kalibrasyon hatası", + "zh": "左视红外传感器标定异常" + }, + "fpv_tip_0x1A020105": { + "de": "Kalibrierungsfehler: Nach oben gerichteter Infrarotsensor", + "en": "Upward infrared sensor calibration error", + "es": "Error de calibración del sensor de infrarrojos superior", + "fr": "Erreur étalonnage du capteur infrarouge supérieur", + "ja": "上方赤外線センサーのキャリブレーションエラー", + "ko": "상향 적외선 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки верхнего ИК датчика", + "tr": "Yukarı kızılötesi sensör kalibrasyon hatası", + "zh": "上视红外传感器标定异常" + }, + "fpv_tip_0x1A020140": { + "de": "Infrarotsensoren blockiert", + "en": "Infrared sensors blocked", + "es": "Sensores de infrarrojos bloqueados", + "fr": "Capteurs infrarouges bloqués", + "ja": "赤外線センサーがブロック", + "ko": "적외선 센서 차단", + "ru": "Инфракрасные датчики заблокированы", + "tr": "Kızılötesi sensörler engelleniyor", + "zh": "视觉红外传感器被遮挡" + }, + "fpv_tip_0x1A020180": { + "de": "Infrarotsensoren überhitzt. Umgehend zum Startpunkt zurückkehren oder landen. Bitte aus Umgebung mit hoher Temperatur entfernen", + "en": "Infrared sensors overheated. Return to home or land promptly. Move away from high-temperature environment", + "es": "Sensores de infrarrojos sobrecalentados. Regresa al punto de origen o aterriza rápidamente. Aléjate del entorno de alta temperatura", + "fr": "Surchauffe des capteurs infrarouges. Retournez au point de départ ou atterrissez immédiatement. Éloignez-vous des sources de hautes températures", + "ja": "赤外線センサー高温。直ちに帰還するか、着陸してください。高温環境から離れてください", + "ko": "적외선 센서 과열. 홈으로 돌아가거나 신속히 착륙하세요. 고온 환경에서 벗어나세요", + "ru": "Инфракрасные датчики перегреты. Немедленно вернитесь в исходное положение и приземлитесь. Переместитесь от среды с высокой температурой", + "tr": "Kızılötesi sensörler aşırı ısındı. Hemen eve dön veya iniş yap. Yüksek sıcaklık alanından uzaklaş", + "zh": "视觉红外传感器温度过高,请尽快返航或降落,远离高温环境" + }, + "fpv_tip_0x1A020400": { + "de": "Schlechte Sicht. Mit Vorsicht fliegen", + "en": "Low visibility. Fly with caution", + "es": "Poca visibilidad. Vuela con cuidado", + "fr": "Faible visibilité. Pilotez avec précaution", + "ja": "視界不良。慎重に飛行してください", + "ko": "가시성 낮음. 비행 시 주의 필요", + "ru": "Низкая видимость. Соблюдайте осторожность при полете", + "tr": "Düşük görüş. Aracınızı dikkatli uçurun", + "zh": "环境能见度差,请谨慎飞行" + }, + "fpv_tip_0x1A040001": { + "de": "Fehler: Energiemodus. Fluggerät neu starten.", + "en": "Power mode error. Restart aircraft", + "es": "Error del modo de energía. Reinicie la aeronave", + "fr": "Erreur de mode d'alimentation. Redémarrez l’appareil", + "ja": "電源モードのエラー。機体を再起動してください", + "ko": "전원 모드 오류. 기체 재시작", + "ru": "Ошибка режима питания. Перезапустите дрон", + "tr": "Güç modu hatası. Hava aracını yeniden başlatın", + "zh": "功耗切换异常,请重启飞行器" + }, + "fpv_tip_0x1A050040": { + "ar": "", + "de": "", + "en": "Obstacle sensing error. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "感知避障异常,请谨慎飞行", + "zh-Hant": "" + }, + "fpv_tip_0x1A050041": { + "ar": "", + "de": "", + "en": "Obstacle sensing error. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "感知避障异常,请谨慎飞行", + "zh-Hant": "" + }, + "fpv_tip_0x1A050042": { + "ar": "", + "de": "", + "en": "Obstacle sensing error. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "感知避障异常,请谨慎飞行", + "zh-Hant": "" + }, + "fpv_tip_0x1A050043": { + "ar": "", + "de": "", + "en": "Obstacle sensing error. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "感知避障异常,请谨慎飞行", + "zh-Hant": "" + }, + "fpv_tip_0x1A210180": { + "de": "Fehler: Sensorsystem. Umgehend landen oder mit Vorsicht fliegen", + "en": "Sensor system error. Land promptly or fly with caution", + "es": "Error del sistema de sensores. Aterriza rápidamente o vuela con cuidado", + "fr": "Erreur du système de capteurs. Atterrissez rapidement ou pilotez avec précaution", + "ja": "センサーシステムのエラー。直ちに着陸するか、慎重に飛行してください", + "ko": "센서 시스템 오류. 즉시 착륙 또는 비행 시 주의 필요", + "ru": "Ошибка системы датчиков. Немедленно выполните посадку или соблюдайте осторожность при полете", + "tr": "Sensör sistem hatası. Derhal iniş yapın veya aracı dikkatli uçurun", + "zh": "感知系统异常,请尽快降落或谨慎飞行" + }, + "fpv_tip_0x1A210181": { + "de": "Fehler: Sensorsystem. Umgehend landen oder mit Vorsicht fliegen", + "en": "Sensor system error. Land promptly or fly with caution", + "es": "Error del sistema de sensores. Aterriza rápidamente o vuela con cuidado", + "fr": "Erreur du système de capteurs. Atterrissez rapidement ou pilotez avec précaution", + "ja": "センサーシステムのエラー。直ちに着陸するか、慎重に飛行してください", + "ko": "센서 시스템 오류. 즉시 착륙 또는 비행 시 주의 필요", + "ru": "Ошибка системы датчиков. Немедленно выполните посадку или соблюдайте осторожность при полете", + "tr": "Sensör sistem hatası. Derhal iniş yapın veya aracı dikkatli uçurun", + "zh": "感知系统异常,请尽快降落或谨慎飞行" + }, + "fpv_tip_0x1A210182": { + "de": "Fehler: Sensorsystem. Umgehend landen oder mit Vorsicht fliegen", + "en": "Sensor system error. Land promptly or fly with caution", + "es": "Error del sistema de sensores. Aterriza rápidamente o vuela con cuidado", + "fr": "Erreur du système de capteurs. Atterrissez rapidement ou pilotez avec précaution", + "ja": "センサーシステムのエラー。直ちに着陸するか、慎重に飛行してください", + "ko": "센서 시스템 오류. 즉시 착륙 또는 비행 시 주의 필요", + "ru": "Ошибка системы датчиков. Немедленно выполните посадку или соблюдайте осторожность при полете", + "tr": "Sensör sistem hatası. Derhal iniş yapın veya aracı dikkatli uçurun", + "zh": "感知系统异常,请尽快降落或谨慎飞行" + }, + "fpv_tip_0x1A210183": { + "de": "Fehler: Sensorsystem. Umgehend landen oder mit Vorsicht fliegen", + "en": "Sensor system error. Land promptly or fly with caution", + "es": "Error del sistema de sensores. Aterriza rápidamente o vuela con cuidado", + "fr": "Erreur du système de capteurs. Atterrissez rapidement ou pilotez avec précaution", + "ja": "センサーシステムのエラー。直ちに着陸するか、慎重に飛行してください", + "ko": "센서 시스템 오류. 즉시 착륙 또는 비행 시 주의 필요", + "ru": "Ошибка системы датчиков. Немедленно выполните посадку или соблюдайте осторожность при полете", + "tr": "Sensör sistem hatası. Derhal iniş yapın veya aracı dikkatli uçurun", + "zh": "感知系统异常,请尽快降落或谨慎飞行" + }, + "fpv_tip_0x1A210184": { + "de": "Fehler: Sensorsystem. Umgehend landen oder mit Vorsicht fliegen", + "en": "Sensor system error. Land promptly or fly with caution", + "es": "Error del sistema de sensores. Aterriza rápidamente o vuela con cuidado", + "fr": "Erreur du système de capteurs. Atterrissez rapidement ou pilotez avec précaution", + "ja": "センサーシステムのエラー。直ちに着陸するか、慎重に飛行してください", + "ko": "센서 시스템 오류. 즉시 착륙 또는 비행 시 주의 필요", + "ru": "Ошибка системы датчиков. Немедленно выполните посадку или соблюдайте осторожность при полете", + "tr": "Sensör sistem hatası. Derhal iniş yapın veya aracı dikkatli uçurun", + "zh": "感知系统异常,请尽快降落或谨慎飞行" + }, + "fpv_tip_0x1A210185": { + "de": "Fehler: Sensorsystem. Umgehend landen oder mit Vorsicht fliegen", + "en": "Sensor system error. Land promptly or fly with caution", + "es": "Error del sistema de sensores. Aterriza rápidamente o vuela con cuidado", + "fr": "Erreur du système de capteurs. Atterrissez rapidement ou pilotez avec précaution", + "ja": "センサーシステムのエラー。直ちに着陸するか、慎重に飛行してください", + "ko": "센서 시스템 오류. 즉시 착륙 또는 비행 시 주의 필요", + "ru": "Ошибка системы датчиков. Немедленно выполните посадку или соблюдайте осторожность при полете", + "tr": "Sensör sistem hatası. Derhal iniş yapın veya aracı dikkatli uçurun", + "zh": "感知系统异常,请尽快降落或谨慎飞行" + }, + "fpv_tip_0x1A2101C0": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l'appareil", + "ja": "センサーシステムのエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезапустите дрон", + "tr": "Sensör sistem hatası. Aracı yeniden başlatın", + "zh": "感知系统异常,请重启飞行器" + }, + "fpv_tip_0x1A2101C1": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l'appareil", + "ja": "センサーシステムのエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезапустите дрон", + "tr": "Sensör sistem hatası. Aracı yeniden başlatın", + "zh": "感知系统异常,请重启飞行器" + }, + "fpv_tip_0x1A2101C2": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l'appareil", + "ja": "センサーシステムのエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезапустите дрон", + "tr": "Sensör sistem hatası. Aracı yeniden başlatın", + "zh": "感知系统异常,请重启飞行器" + }, + "fpv_tip_0x1A2101C3": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l'appareil", + "ja": "センサーシステムのエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезапустите дрон", + "tr": "Sensör sistem hatası. Aracı yeniden başlatın", + "zh": "感知系统异常,请重启飞行器" + }, + "fpv_tip_0x1A2101C4": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l'appareil", + "ja": "センサーシステムのエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезапустите дрон", + "tr": "Sensör sistem hatası. Aracı yeniden başlatın", + "zh": "感知系统异常,请重启飞行器" + }, + "fpv_tip_0x1A2101C5": { + "de": "Fehler: Sensorsystem. Fluggerät neu starten", + "en": "Sensor system error. Restart aircraft", + "es": "Error del sistema de sensores. Reinicia la aeronave", + "fr": "Erreur du système de capteurs. Redémarrez l'appareil", + "ja": "センサーシステムのエラー。機体を再起動してください", + "ko": "센서 시스템 오류. 기체 재시작 필요", + "ru": "Ошибка системы датчиков. Перезапустите дрон", + "tr": "Sensör sistem hatası. Aracı yeniden başlatın", + "zh": "感知系统异常,请重启飞行器" + }, + "fpv_tip_0x1A310980": { + "de": "Systemfehler: Sichtpositionierung", + "en": "Vision positioning system error", + "es": "Error del sistema de posicionamiento visual", + "fr": "Erreur système positionnement visuel", + "ja": "ビジョンポジショニング システム エラー", + "ko": "비전 포지셔닝 시스템 오류", + "ru": "Ошибка системы визуального позиционирования", + "tr": "Görüntü konumlandırma sistemi hatası", + "zh": "视觉定位系统异常" + }, + "fpv_tip_0x1A310981": { + "de": "Systemfehler: Sichtpositionierung", + "en": "Vision positioning system error", + "es": "Error del sistema de posicionamiento visual", + "fr": "Erreur système positionnement visuel", + "ja": "ビジョンポジショニングシステム エラー", + "ko": "비전 포지셔닝 시스템 오류", + "ru": "Ошибка системы визуального позиционирования", + "tr": "Görüntü konumlandırma sistemi hatası", + "zh": "视觉定位系统异常" + }, + "fpv_tip_0x1A420040": { + "de": "Systemfehler: Hinderniserkennung nach unten", + "en": "Downward obstacle sensing system error", + "es": "Error del sistema de detección de obstáculos inferior", + "fr": "Erreur système de détection d\\'obstacles inférieur", + "ja": "下方障害物検知システムエラー", + "ko": "하향 장애물 감지 시스템 오류", + "ru": "Ошибка системы распознавания препятствий снизу", + "tr": "Aşağı engel algılama sistemi hatası", + "zh": "下视障碍物感知系统异常" + }, + "fpv_tip_0x1A420041": { + "de": "Systemfehler: Hinderniserkennung nach vorne", + "en": "Forward obstacle sensing system error", + "es": "Error del sistema de detección de obstáculos frontal", + "fr": "Erreur système de détection d\\'obstacles avant", + "ja": "前方障害物検知システムエラー", + "ko": "전방 장애물 감지 시스템 오류", + "ru": "Ошибка системы распознавания препятствий сверху", + "tr": "İleri engel algılama sistemi hatası", + "zh": "前视障碍物感知系统异常" + }, + "fpv_tip_0x1A420042": { + "de": "Systemfehler: Hinderniserkennung nach rechts", + "en": "Right obstacle sensing system error", + "es": "Error del sistema de detección de obstáculos derecho", + "fr": "Erreur système de détection d\\'obstacles droit", + "ja": "右障害物検知システムエラー", + "ko": "우측 장애물 감지 시스템 오류", + "ru": "Ошибка системы распознавания препятствий справа", + "tr": "Sağ engel algılama sistemi hatası", + "zh": "右视障碍物感知系统异常" + }, + "fpv_tip_0x1A420043": { + "de": "Systemfehler: Hinderniserkennung nach hinten", + "en": "Backward obstacle sensing system error", + "es": "Error del sistema de detección de obstáculos trasero", + "fr": "Erreur système de détection d\\'obstacles arrière", + "ja": "後方障害物検知システムエラー", + "ko": "후방 장애물 감지 시스템 오류", + "ru": "Ошибка системы распознавания препятствий сзади", + "tr": "Geri engel algılama sistemi hatası", + "zh": "后视障碍物感知系统异常" + }, + "fpv_tip_0x1A420044": { + "de": "Systemfehler: Hinderniserkennung nach links", + "en": "Left obstacle sensing system error", + "es": "Error del sistema de detección de obstáculos izquierdo", + "fr": "Erreur système de détection d\\'obstacles gauche", + "ja": "左障害物検知システムエラー", + "ko": "좌측 장애물 감지 시스템 오류", + "ru": "Ошибка системы распознавания препятствий слева", + "tr": "Sol engel algılama sistemi hatası", + "zh": "左视障碍物感知系统异常" + }, + "fpv_tip_0x1A420045": { + "de": "Systemfehler: Hinderniserkennung nach oben", + "en": "Upward obstacle sensing system error", + "es": "Error del sistema de detección de obstáculos superior", + "fr": "Erreur système de détection d\\'obstacles supérieur", + "ja": "上方障害物検知システムエラー", + "ko": "상향 장애물 감지 시스템 오류", + "ru": "Ошибка системы распознавания препятствий сверху", + "tr": "Yukarı engel algılama sistemi hatası", + "zh": "上视障碍物感知系统异常" + }, + "fpv_tip_0x1A420440": { + "de": "Systemfehler: Hinderniserkennung", + "en": "Obstacle sensing system error", + "es": "Error del sistema de detección de obstáculos", + "fr": "Erreur système de détection d\\'obstacles", + "ja": "障害物検知システムエラー", + "ko": "장애물 감지 시스템 오류", + "ru": "Ошибка системы распознавания препятствий", + "tr": "Engel algılama sistemi hatası", + "zh": "障碍物感知系统异常" + }, + "fpv_tip_0x1A4205C0": { + "de": "Fehler: Hinderniserkennung", + "en": "Obstacle sensing system error", + "es": "Error del sistema de detección de obstáculos", + "fr": "Erreur système de détection d\\'obstacles", + "ja": "障害物検知システムエラー", + "ko": "장애물 감지 시스템 오류", + "ru": "Ошибка системы распознавания препятствий", + "tr": "Engel algılama sistemi hatası", + "zh": "障碍物感知系统异常" + }, + "fpv_tip_0x1A420680": { + "de": "Fehler: Hinderniserkennung", + "en": "Obstacle sensing system error", + "es": "Error del sistema de detección de obstáculos", + "fr": "Erreur système de détection d\\'obstacles", + "ja": "障害物検知システムエラー", + "ko": "장애물 감지 시스템 오류", + "ru": "Ошибка системы распознавания препятствий", + "tr": "Engel algılama sistemi hatası", + "zh": "障碍物感知系统异常" + }, + "fpv_tip_0x1A420BC0": { + "de": "Abwärtsgerichtetes Umgebungslicht zu schwach. Abwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Downward ambient light too low. Obstacle avoidance unavailable. Fly with caution", + "es": "Luz ambiental inferior demasiado débil. Sistema anticolisión no disponible. Vuela con cuidado", + "fr": "Éclairage ambiant vers le bas trop faible. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "下方の環境光が十分ではありません。障害物回避を利用できません。慎重に飛行してください", + "ko": "하향 주변 조명이 너무 어둡습니다. 하향 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком низкая яркость окружающего света внизу. Обход препятствий снизу недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Aşağıdaki ortam ışığı çok az. Engel önleyici kullanılamıyor. Dikkatli uçurun", + "zh": "下视环境光过暗,下方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420BC1": { + "de": "Vorwärtsgerichtetes Umgebungslicht zu schwach. Vorwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Forward ambient light too low. Obstacle avoidance unavailable. Fly with caution", + "es": "Luz ambiental frontal demasiado débil. Sistema anticolisión no disponible. Vuela con cuidado", + "fr": "Éclairage ambiant vers l\\'avant trop faible. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "前方の環境光が十分ではありません。障害物回避を利用できません。慎重に飛行してください", + "ko": "전방 주변 조명이 너무 어둡습니다. 전방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком низкая яркость окружающего света впереди. Обход препятствий спереди недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "İleri ortam ışığı çok az. Engel önleyici kullanılamıyor. Dikkatli uçurun", + "zh": "前视环境光过暗,前向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420BC2": { + "de": "Rückwärtsgerichtetes Umgebungslicht zu schwach. Rückwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Backward ambient light too low. Backward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental trasera demasiado débil. Sistema anticolisión trasero no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop faible à l\\'arrière. Évitement des obstacles à l\\'arrière non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "後方の環境光が十分ではありません。後方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "후방 주변 조명이 너무 어둡습니다. 후방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком низкая яркость окружающего света сзади. Обход препятствий сзади недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Gerideki ortam ışığı çok az. Geri engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "后视环境光过暗,后向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420BC3": { + "de": "Rechtsgerichtetes Umgebungslicht zu schwach. Rechtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Rightward ambient light too low. Rightward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental derecha demasiado débil. Sistema anticolisión derecho no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop faible sur la droite. Évitement des obstacles sur la droite non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "右方向の環境光が十分ではありません。右方向の障害物回避を使用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "오른쪽 주변 조명이 너무 어둡습니다. 오른쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком низкая яркость окружающего света справа. Обход препятствий справа недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Sağ taraftaki ortam ışığı çok az. Sağ engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "右视环境光过暗,右向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420BC4": { + "de": "Linksgerichtetes Umgebungslicht zu schwach. Linksgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Leftward ambient light too low. Leftward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental izquierda demasiado débil. Sistema anticolisión izquierdo no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Éclairage ambiant vers la gauche trop faible. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "左方向の環境光が十分ではありません。左方向の障害物回避を使用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "왼쪽 주변 조명이 너무 어둡습니다. 왼쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком низкая яркость окружающего света слева. Обход препятствий слева недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Sol taraftaki ortam ışığı çok az. Sol engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "左视环境光过暗,左向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420BC5": { + "de": "Aufwärtsgerichtetes Umgebungslicht zu schwach. Aufwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Upward ambient light too low. Upward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental superior demasiado débil. Sistema anticolisión superior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Éclairage ambiant vers le haut trop faible. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "上方の環境光が十分ではありません。上方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "상방 주변 조명이 너무 어둡습니다. 상향 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком низкая яркость окружающего света сверху. Обход препятствий сверху недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Yukarıdaki ortam ışığı çok az. Yukarı engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "上视环境光过暗,上方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420BC6": { + "de": "Horizontales Umgebungslicht zu schwach. Horizontale Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Horizontal ambient light too low. Horizontal obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental horizontal demasiado débil. Sistema anticolisión horizontal no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Éclairage ambiant horizontal trop faible. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "水平方向の環境光が十分ではありません。水平方向の障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "수평 주변 조명이 너무 어둡습니다. 수평 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком низкая яркость окружающего света в горизонтальном направлении. Обход препятствий в горизонтальном направлении недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Yatay ortam ışığı çok az. Yatay engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "水平方向环境光过暗,水平方向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C00": { + "de": "Abwärtsgerichtetes Umgebungslicht zu hell. Abwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Downward ambient light too bright. Downward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental inferior demasiado intensa. Sistema anticolisión inferior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Éclairage ambiant vers le bas trop intense. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "下方の環境光が明るすぎます。下方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "하향 주변 조명이 너무 밝습니다. 하향 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком высокая яркость окружающего света внизу. Обход препятствий снизу недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Aşağıdaki ortam ışığı çok parlak. Aşağı engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "下视环境光过亮,下方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C01": { + "de": "Vorwärtsgerichtetes Umgebungslicht zu hell. Vorwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Forward ambient light too bright. Forward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental frontal demasiado intensa. Sistema anticolisión frontal no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop forte à l\\'avant. Évitement des obstacles à l\\'avant non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "前方の環境光が明るすぎます。前方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "전방 주변 조명이 너무 밝습니다. 전방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком высокая яркость окружающего света впереди. Обход препятствий спереди недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "İlerideki ortam ışığı çok parlak. İleri engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "前视环境光过亮,前向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C02": { + "de": "Rückwärtsgerichtetes Umgebungslicht zu hell. Rückwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Backward ambient light too bright. Backward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental trasera demasiado intensa. Sistema anticolisión trasero no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Éclairage ambiant vers l\\'arrière trop intense. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "後方の環境光が明るすぎます。後方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "후방 주변 조명이 너무 밝습니다. 후방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком высокая яркость окружающего света сзади. Обход препятствий сзади недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Gerideki ortam ışığı çok parlak. Geri engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "后视环境光过亮,后向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C03": { + "de": "Rechtsgerichtetes Umgebungslicht zu hell. Rechtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Rightward ambient light too bright. Rightward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental derecha demasiado intensa. Sistema anticolisión derecho no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Éclairage ambiant vers la droite trop intense. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "右方向の環境光が明るすぎます。右方向の障害物回避を使用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "오른쪽 주변 조명이 너무 밝습니다. 오른쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком высокая яркость окружающего света справа. Обход препятствий справа недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Sağ taraftaki ortam ışığı çok parlak. Sağ engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "右视环境光过亮,右向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C04": { + "de": "Linksgerichtetes Umgebungslicht zu hell. Linksgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Leftward ambient light too bright. Leftward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental izquierda demasiado intensa. Sistema anticolisión izquierdo no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Éclairage ambiant vers la gauche trop intense. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "左方向の環境光が明るすぎます。左方向の障害物回避を使用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "왼쪽 주변 조명이 너무 밝습니다. 왼쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком высокая яркость окружающего света слева. Обход препятствий слева недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Sol taraftaki ortam ışığı çok parlak. Sol engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "左视环境光过亮,左向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C05": { + "de": "Aufwärtsgerichtetes Umgebungslicht zu hell. Aufwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Upward ambient light too bright. Upward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental superior demasiado intensa. Sistema anticolisión superior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Éclairage ambiant vers le haut trop intense. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "上方の環境光が明るすぎます。上方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "상향 주변 조명이 너무 밝습니다. 상향 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком высокая яркость окружающего света сверху. Обход препятствий сверху недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Yukarıdaki ortam ışığı çok parlak. Yukarı engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "上视环境光过亮,上方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C06": { + "de": "Horizontales Umgebungslicht zu hell. Horizontale Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Horizontal ambient light too bright. Horizontal obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental horizontal demasiado intensa. Sistema anticolisión horizontal no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Éclairage ambiant horizontal trop intense. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "水平方向の環境光が明るすぎます。水平方向の障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "수평 주변 조명이 너무 밝습니다. 수평 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком высокая яркость окружающего света в горизонтальном направлении. Обход препятствий в горизонтальном направлении недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Yatay ortam ışığı çok parlak. Yatay engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "水平方向环境光过亮,水平方向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C40": { + "de": "Abwärtsgerichtete(r) Sensor(en) blockiert. Abwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Downward sensor(s) blocked. Downward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) inferior(es) bloqueado(s). Sistema anticolisión inferior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) inférieurs bloqué(s). Évitement des obstacles en dessous non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "下方センサーがブロックされています。下方障害物回避を使用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "하향 센서가 막혔습니다. 하향 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Нижние датчики заблокированы. Обход препятствий снизу недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Aşağı sensör(ler) engelleniyor. Aşağı engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "下视可能遮挡,下方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C41": { + "de": "Vorwärtsgerichtete(r) Sensor(en) blockiert. Vorwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Forward sensor(s) blocked. Forward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) frontal(es) bloqueado(s). Sistema anticolisión frontal no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) avant bloqué(s). Évitement des obstacles à l\\'avant non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "前方センサーがブロックされています。前方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "전방 센서가 막혔습니다. 전방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Передние датчики заблокированы. Обход препятствий спереди недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "İleri sensör(ler) engelleniyor. İleri engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "前视可能遮挡,前向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C42": { + "de": "Rückwärtsgerichtete(r) Sensor(en) blockiert. Rückwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Backward sensor(s) blocked. Backward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) trasero(s) bloqueado(s). Sistema anticolisión trasero no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) à l\\'arrière bloqué(s). Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "後方センサーがブロックされています。後方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "후방 센서가 막혔습니다. 후방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Задние датчики заблокированы. Обход препятствий сзади недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Geri sensör(ler) engelleniyor. Geri engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "后视可能遮挡,后向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C43": { + "de": "Rechtsgerichtete(r) Sensor(en) blockiert. Rechtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Rightward sensor(s) blocked. Rightward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) derecho(s) bloqueado(s). Sistema anticolisión derecho no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) de droite bloqué(s). Évitement des obstacles sur la droite non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "右方向センサーがブロックされています。右方向の障害物回避を使用できません。赤外線センサーのみが使用可能です。 慎重に飛行してください", + "ko": "오른쪽 센서가 막혔습니다. 오른쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Правые датчики заблокированы. Обход препятствий справа недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Sağ sensör(ler) engelleniyor. Sağ engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "右视可能遮挡,右向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C44": { + "de": "Linksgerichtete(r) Sensor(en) blockiert. Linksgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Leftward sensor(s) blocked. Leftward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) izquierdo(s) bloqueado(s). Sistema anticolisión izquierdo no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) à gauche bloqué(s). Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "左方向センサーがブロックされています。左方向の障害物回避を使用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "왼쪽 센서가 막혔습니다. 왼쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Левые датчики заблокированы. Обход препятствий слева недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Sol sensör(ler) engelleniyor. Sol engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "左视可能遮挡,左向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C45": { + "de": "Aufwärtsgerichtete(r) Sensor(en) blockiert. Aufwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Upward sensor(s) blocked. Upward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) superior(es) bloqueado(s). Sistema anticolisión superior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) supérieur(s) bloqué(s). Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "上方センサーがブロックされています。上方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "상향 센서가 막혔습니다. 상향 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Верхние датчики заблокированы. Обход препятствий сверху недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Yukarı sensör(ler) engelleniyor. Yukarı engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "上视可能遮挡,上方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1A420C80": { + "de": "Abwärtsgerichtete(r) Sensor(en) unscharf. Abwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Downward sensor(s) blurry. Downward obstacle avoidance unavailable. Fly with caution", + "es": "Sensor(es) inferior(es) borroso(s). Sistema anticolisión inferior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) inférieurs flou(s). Évitement des obstacles en dessous non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "下方センサーが不鮮明です。下方障害物回避を使用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "하향 센서가 흐릿합니다. 하향 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Размытое изображение с нижних датчиков. Обход препятствий снизу недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Aşağı sensör(ler) bulanık. Aşağı engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "下视可能脏污,下方视觉避障失效,请谨慎飞行" + }, + "fpv_tip_0x1A420C81": { + "de": "Vorwärtsgerichtete(r) Sensor(en) unscharf. Vorwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Forward sensor(s) blurry. Forward obstacle avoidance unavailable. Fly with caution", + "es": "Sensor(es) frontal(es) borroso(s). Sistema anticolisión frontal no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) à l\\'avant flou(s). Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "前方センサーが不鮮明です。前方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "전방 센서가 흐릿합니다. 전방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Размытое изображение с передних датчиков. Обход препятствий спереди недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "İleri sensör(ler) bulanık. İleri engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "前视可能脏污,前向视觉避障失效,请谨慎飞行" + }, + "fpv_tip_0x1A420C82": { + "de": "Rückwärtsgerichtete(r) Sensor(en) verschwommen. Rückwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Backward sensor(s) blurry. Backward obstacle avoidance unavailable. Fly with caution", + "es": "Sensor(es) trasero(s) borroso(s). Sistema anticolisión trasero no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) arrière flou(s). Évitement des obstacles à l\\'arrière non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "後方センサーが不鮮明です。後方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "후방 센서가 흐릿합니다. 후방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Размытое изображение с задних датчиков. Обход препятствий сзади недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Geri sensör(ler) bulanık. Geri engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "后视可能脏污,后向视觉避障失效,请谨慎飞行" + }, + "fpv_tip_0x1A420C83": { + "de": "Rechte(r) Sensor(en) unscharf. Rechtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Right sensor(s) blurry. Rightward obstacle avoidance unavailable. Fly with caution", + "es": "Sensor(es) derecho(s) borroso(s). Sistema anticolisión derecho no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) de droite flou(s). Évitement des obstacles sur la droite non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "右センサーが不鮮明です。右方向の障害物回避を使用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "오른쪽 센서가 흐릿합니다. 오른쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Размытое изображение с правых датчиков. Обход препятствий справа недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Sağ sensör(ler) bulanık. Sağ engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "右视可能脏污,右向视觉避障失效,请谨慎飞行" + }, + "fpv_tip_0x1A420C84": { + "de": "Linke(r) Sensor(en) unscharf. Linksgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Left sensor(s) blurry. Leftward obstacle avoidance unavailable. Fly with caution", + "es": "Sensor(es) izquierdo(s) borroso(s). Sistema anticolisión izquierdo no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) de gauche flou(s). Évitement des obstacles sur la gauche non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "左センサーが不鮮明です。左方向の障害物回避を使用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "왼쪽 센서가 흐릿합니다. 왼쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Размытое изображение с левых датчиков. Обход препятствий слева недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Sol sensör(ler) bulanık. Sol engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "左视可能脏污,左向视觉避障失效,请谨慎飞行" + }, + "fpv_tip_0x1A420C85": { + "de": "Aufwärtsgerichtete(r) Sensor(en) unscharf. Aufwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Upward sensor(s) blurry. Upward obstacle avoidance unavailable. Fly with caution", + "es": "Sensor(es) superior(es) borroso(s). Sistema anticolisión superior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) supérieur(s) flou(s). Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "上方センサーが不鮮明です。上方障害物回避を利用できません。赤外線センサーのみが使用可能です。慎重に飛行してください", + "ko": "상향 센서가 흐릿합니다. 상향 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Размытое изображение с верхних датчиков. Обход препятствий сверху недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "Yukarı sensör(ler) bulanık. Yukarı engel önleyici kullanılamıyor. Sadece kızılötesi sensörler kullanılabiliyor. Dikkatli uçurun", + "zh": "上视可能脏污,上方视觉避障失效,请谨慎飞行" + }, + "fpv_tip_0x1A420CC0": { + "de": "Fluglagenwinkel des Fluggeräts zu groß. Hindernisvermeidung nicht verfügbar. Mit Vorsicht fliegen", + "en": "Aircraft attitude angle too large. Obstacle avoidance unavailable. Fly with caution", + "es": "Ángulo de posición de la aeronave demasiado grande. Sistema anticolisión no disponible. Vuela con cuidado", + "fr": "Angle d\\'attitude de l\\'appareil trop important. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "機体の姿勢角が大きすぎます。障害物回避を利用できません。慎重に飛行してください", + "ko": "기체 자세 각도가 너무 큽니다. 장애물 회피를 사용할 수 없습니다. 주의해서 비행하세요", + "ru": "Слишком большой угол тангажа дрона. Обход препятствий недоступен. Будьте внимательны при полете", + "tr": "Aracın davranış açısı çok büyük. Engel önleyici kullanılamıyor. Dikkatli uçurun", + "zh": "飞行器姿态角过大,避障失效,请谨慎飞行" + }, + "fpv_tip_0x1A420D00": { + "de": "Fluglagenwinkel des Fluggeräts zu groß. Landeschutz nicht verfügbar. Manuell landen", + "en": "Aircraft attitude angle too large. Landing protection unavailable. Land manually", + "es": "Ángulo de posición de la aeronave demasiado grande. Protección durante el aterrizaje no disponible. Aterriza manualmente", + "fr": "Angle d\\'attitude de l\\'appareil trop important. Protection à l\\'atterrissage indisponible. Atterrissez manuellement", + "ja": "機体の姿勢角が大きすぎます。着陸保護は利用できません。手動で着陸してください", + "ko": "기체 자세 각도가 너무 큽니다. 착륙 보호 기능을 사용할 수 없습니다. 수동 착륙", + "ru": "Слишком большой угол тангажа дрона. Безопасное приземление недоступно. Приземлитесь вручную", + "tr": "Aracın davranış açısı çok büyük. İniş koruma kullanılamıyor. Manuel olarak indirin", + "zh": "飞行器姿态角过大,降落保护失效,请手动降落" + }, + "fpv_tip_0x1A420D40": { + "de": "Fluggerät nähert sich Hindernis mit totem Winkel. Hinderniserkennung evtl. nicht möglich. Mit Vorsicht fliegen", + "en": "Aircraft approaching obstacle sensing blind spot and may be unable to detect obstacles. Fly with caution", + "es": "La aeronave se está acercando al punto ciego de detección de obstáculos y es posible que no pueda detectar obstáculos. Vuela con cuidado", + "fr": "L\\'appareil approche de l\\'angle mort de la détection d\\'obstacles et pourrait ne pas être en mesure de détecter les obstacles. Volez avec précaution", + "ja": "機体が障害物検知の死角に接近中。障害物を検知できない可能性があります。慎重に飛行してください", + "ko": "기체가 장애물 감지 사각 지대에 접근하고 있으므로 장애물을 감지하지 못할 수도 있습니다. 주의해서 비행하세요", + "ru": "Дрон приближается к слепой зоне определения препятствий, и, возможно, не сможет обнаружить препятствия. Будьте внимательны при полете", + "tr": "Araç, engel algılama kör noktasına yaklaşıyor ve engelleri tespit edemeyebilir. Dikkatli uçurun", + "zh": "正飞向障碍物感知盲区,可能无法检测障碍物,请谨慎飞行" + }, + "fpv_tip_0x1A421B00": { + "en": "Vision system disabled. Switched to radar obstacle avoidance. The obstacle avoidance available range will change", + "zh": "视觉避障失效,已切换为雷达避障,注意可避障区间变化" + }, + "fpv_tip_0x1A421B40": { + "en": "", + "zh": "激光雷达已连接" + }, + "fpv_tip_0x1A421B80": { + "en": "", + "zh": "激光雷达连接已断开" + }, + "fpv_tip_0x1A430680": { + "de": "Instabile Lichtverhältnisse. Sichtsensoren und Hinderniserkennung sind evtl. nicht verfügbar. Mit Vorsicht fliegen", + "en": "Unstable lighting conditions. Vision system and obstacle sensing may be unavailable. Fly with caution", + "es": "Condiciones de iluminación inestables. Puede que el sistema de visión y la detección de obstáculos no estén disponibles. Vuela con cuidado.", + "fr": "Conditions de luminosité instables. Le système optique et la détection d'obstacles peuvent être indisponibles. Pilotez avec précaution", + "ja": "照明条件が不安定。ビジョンシステムと障害物検知が利用できない可能性があります。慎重に飛行してください", + "ko": "조명 조건 불안정. 비전 시스템 및 장애물 감지를 사용하지 못할 수 있음. 비행 시 주의 필요", + "ru": "Нестабильные условия освещения. Системы обзора и обнаружения препятствий могут быть недоступны. Соблюдайте осторожность при полете", + "tr": "Değişken ışık koşulları. Görüş sistemi ve engel algılama kullanılamayabilir. Dikkatlice uçun", + "zh": "环境光线差异较大,视觉系统及避障可能失效,请注意飞行安全" + }, + "fpv_tip_0x1A510380": { + "de": "Kalibrierungsfehler: Nach unten gerichteter Sichtsensor", + "en": "Downward vision sensor calibration error", + "es": "Error de calibración del sensor visual inferior", + "fr": "Erreur d\\'étalonnage du capteur optique inférieur", + "ja": "下方ビジョンセンサーのキャリブレーションエラー", + "ko": "하향 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки нижнего видеодатчика", + "tr": "Aşağı görüş sensörü kalibrasyon hatası", + "zh": "下视传感器标定异常" + }, + "fpv_tip_0x1A510381": { + "de": "Kalibrierungsfehler: Nach vorne gerichteter Sichtsensor", + "en": "Forward vision sensor calibration error", + "es": "Error de calibración del sensor visual frontal", + "fr": "Erreur d\\'étalonnage du capteur optique avant", + "ja": "前方ビジョンセンサーのキャリブレーションエラー", + "ko": "전방 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки переднего видеодатчика", + "tr": "İleri görüş sensörü kalibrasyon hatası", + "zh": "前视传感器标定异常" + }, + "fpv_tip_0x1A510382": { + "de": "Kalibrierungsfehler: Nach hinten gerichteter Sichtsensor", + "en": "Backward vision sensor calibration error", + "es": "Error de calibración del sensor visual trasero", + "fr": "Erreur d\\'étalonnage du capteur optique arrière", + "ja": "後方ビジョンセンサーのキャリブレーションエラー", + "ko": "후방 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки заднего видеодатчика", + "tr": "Geri görüş sensörü kalibrasyon hatası", + "zh": "后视传感器标定异常" + }, + "fpv_tip_0x1A510383": { + "de": "Kalibrierungsfehler: Nach oben gerichteter Sichtsensor", + "en": "Upward vision sensor calibration error", + "es": "Error de calibración del sensor visual superior", + "fr": "Erreur d\\'étalonnage du capteur optique supérieur", + "ja": "上方ビジョンセンサーのキャリブレーションエラー", + "ko": "상향 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки верхнего видеодатчика", + "tr": "Yukarı görüş sensörü kalibrasyon hatası", + "zh": "上视传感器标定异常" + }, + "fpv_tip_0x1A510384": { + "de": "Kalibrierungsfehler: Linker Sichtsensor", + "en": "Left vision sensor calibration error", + "es": "Error de calibración del sensor visual izquierdo", + "fr": "Erreur d\\'étalonnage du capteur optique gauche", + "ja": "左ビジョンセンサーのキャリブレーションエラー", + "ko": "좌측 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки левого видеодатчика", + "tr": "Sol görüş sensörü kalibrasyon hatası", + "zh": "左视传感器标定异常" + }, + "fpv_tip_0x1A510385": { + "de": "Kalibrierungsfehler: Rechter Sichtsensor", + "en": "Right vision sensor calibration error", + "es": "Error de calibración del sensor visual derecho", + "fr": "Erreur d\\'étalonnage du capteur optique droit", + "ja": "右ビジョンセンサーのキャリブレーションエラー", + "ko": "우측 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки правого видеодатчика", + "tr": "Sağ görüş sensörü kalibrasyon hatası", + "zh": "右视传感器标定异常" + }, + "fpv_tip_0x1A5103C0": { + "de": "Kalibrierungsfehler: Sichtsensor", + "en": "Downward vision sensor calibration error", + "es": "Error de calibración del sensor visual inferior", + "fr": "Erreur d\\'étalonnage du capteur optique inférieur", + "ja": "下方ビジョンセンサーのキャリブレーションエラー", + "ko": "비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки видеодатчика", + "tr": "Aşağı görüş sensörü kalibrasyon hatası", + "zh": "下视传感器标定异常" + }, + "fpv_tip_0x1A5103C1": { + "de": "Kalibrierungsfehler: Vorwärtsgerichtete Sichtsensoren", + "en": "Forward vision sensor calibration error", + "es": "Error de calibración del sensor visual frontal", + "fr": "Erreur d\\'étalonnage du capteur optique avant", + "ja": "前方ビジョンセンサーのキャリブレーションエラー", + "ko": "전방 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки переднего датчика обзора", + "tr": "İleri görüş sensörü kalibrasyon hatası", + "zh": "前视传感器标定异常" + }, + "fpv_tip_0x1A5103C2": { + "de": "Kalibrierungsfehler: Rückwärtsgerichtete Sichtsensoren", + "en": "Backward vision sensor calibration error", + "es": "Error de calibración del sensor visual trasero", + "fr": "Erreur d\\'étalonnage du capteur optique arrière", + "ja": "後方ビジョンセンサーのキャリブレーションエラー", + "ko": "후방 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки заднего датчика обзора", + "tr": "Geri görüş sensörü kalibrasyon hatası", + "zh": "后视传感器标定异常" + }, + "fpv_tip_0x1A5103C3": { + "de": "Kalibrierungsfehler: Aufwärtsgerichtete Sichtsensoren", + "en": "Upward vision sensor calibration error", + "es": "Error de calibración del sensor visual superior", + "fr": "Erreur d\\'étalonnage du capteur optique supérieur", + "ja": "上方ビジョンセンサーのキャリブレーションエラー", + "ko": "상향 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки верхнего датчика обзора", + "tr": "Yukarı görüş sensörü kalibrasyon hatası", + "zh": "上视传感器标定异常" + }, + "fpv_tip_0x1A5103C4": { + "de": "Kalibrierungsfehler: Linksgerichtete Sichtsensoren", + "en": "Left vision sensor calibration error", + "es": "Error de calibración del sensor visual izquierdo", + "fr": "Erreur d\\'étalonnage du capteur optique gauche", + "ja": "左ビジョンセンサーのキャリブレーションエラー", + "ko": "좌측 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки левого датчика обзора", + "tr": "Sol görüş sensörü kalibrasyon hatası", + "zh": "左视传感器标定异常" + }, + "fpv_tip_0x1A5103C5": { + "de": "Kalibrierungsfehler: Rechtsgerichtete Sichtsensoren", + "en": "Right vision sensor calibration error", + "es": "Error de calibración del sensor visual derecho", + "fr": "Erreur d\\'étalonnage du capteur optique droit", + "ja": "右ビジョンセンサーのキャリブレーションエラー", + "ko": "우측 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки правого датчика обзора", + "tr": "Sağ görüş sensörü kalibrasyon hatası", + "zh": "右视传感器标定异常" + }, + "fpv_tip_0x1A5104C0": { + "de": "Fehler: abwärts gerichtete Hinderniserkennung. Mit Vorsicht fliegen", + "en": "Downward obstacle sensing error. Fly with caution", + "es": "Error de detección de obstáculos inferior. Vuele con cuidado", + "fr": "Erreur de détection d'obstacles vers le bas. Pilotez avec précaution", + "ja": "下方障害物検知エラー。慎重に飛行してください", + "ko": "하향 장애물 감지 오류. 비행 시 주의 필요", + "ru": "Ошибка определения препятствий снизу. Соблюдайте осторожность при полете", + "tr": "Aşağı yönde engel algılama hatası. Dikkatlice uçurun", + "zh": "下视避障感知异常,请谨慎飞行" + }, + "fpv_tip_0x1A5104C1": { + "de": "Fehler: nach vorn gerichtete Hinderniserkennung. Mit Vorsicht fliegen", + "en": "Forward obstacle sensing error. Fly with caution", + "es": "Error de detección de obstáculos frontal. Vuele con cuidado", + "fr": "Erreur de détection d'obstacles vers l'avant. Pilotez avec précaution", + "ja": "前方障害物検知エラー。慎重に飛行してください", + "ko": "전방 장애물 감지 오류. 비행 시 주의 필요", + "ru": "Ошибка определения препятствий спереди. Соблюдайте осторожность при полете", + "tr": "İleri yönde engel algılama hatası. Dikkatlice uçurun", + "zh": "前视避障感知异常,请谨慎飞行" + }, + "fpv_tip_0x1A5104C2": { + "de": "Fehler: nach hinten gerichtete Hinderniserkennung. Mit Vorsicht fliegen", + "en": "Backward obstacle sensing error. Fly with caution", + "es": "Error de detección de obstáculos trasero. Vuele con cuidado", + "fr": "Erreur de détection d'obstacles vers l'arrière. Pilotez avec précaution", + "ja": "後方障害物検知エラー。慎重に飛行してください", + "ko": "후방 장애물 감지 오류. 비행 시 주의 필요", + "ru": "Ошибка определения препятствий сзади. Соблюдайте осторожность при полете", + "tr": "Geri yönde engel algılama hatası. Dikkatlice uçurun", + "zh": "后视避障感知异常,请谨慎飞行" + }, + "fpv_tip_0x1A5104C3": { + "de": "Fehler: aufwärts gerichtete Hinderniserkennung. Mit Vorsicht fliegen", + "en": "Upward obstacle sensing error. Fly with caution", + "es": "Error de detección de obstáculos superior. Vuele con cuidado", + "fr": "Erreur de détection d'obstacles vers le haut. Pilotez avec précaution", + "ja": "上方障害物検知エラー。慎重に飛行してください", + "ko": "상향 장애물 감지 오류. 비행 시 주의 필요", + "ru": "Ошибка определения препятствий сверху. Соблюдайте осторожность при полете", + "tr": "Yukarı yönde engel algılama hatası. Dikkatlice uçurun", + "zh": "上视避障感知异常,请谨慎飞行" + }, + "fpv_tip_0x1A5104C4": { + "de": "Fehler: nach links gerichtete Hinderniserkennung. Mit Vorsicht fliegen", + "en": "Left obstacle sensing error. Fly with caution", + "es": "Error de detección de obstáculos izquierdo. Vuele con cuidado", + "fr": "Erreur de détection d'obstacles vers la gauche. Pilotez avec précaution", + "ja": "左側障害物検知エラー。慎重に飛行してください", + "ko": "좌측 장애물 감지 오류. 비행 시 주의 필요", + "ru": "Ошибка определения препятствий слева. Соблюдайте осторожность при полете", + "tr": "Sol yönde engel algılama hatası. Dikkatlice uçurun", + "zh": "左视避障感知异常,请谨慎飞行" + }, + "fpv_tip_0x1A5104C5": { + "de": "Fehler: nach rechts gerichtete Hinderniserkennung, Mit Vorsicht fliegen", + "en": "Right obstacle sensing error. Fly with caution", + "es": "Error de detección de obstáculos derecho. Vuele con cuidado", + "fr": "Erreur de détection d'obstacles vers la droite. Pilotez avec précaution", + "ja": "右側障害物検知エラー。慎重に飛行してください", + "ko": "우측 장애물 감지 오류. 비행 시 주의 필요", + "ru": "Ошибка определения препятствий справа. Соблюдайте осторожность при полете", + "tr": "Sağ yönde engel algılama hatası. Dikkatlice uçurun", + "zh": "右视避障感知异常,请谨慎飞行" + }, + "fpv_tip_0x1A5104C6": { + "de": "Fehler: omnidirektionale Hinderniserkennung. Mit Vorsicht fliegen", + "en": "Omnidirectional obstacle sensing error. Fly with caution", + "es": "Error de detección de obstáculos omnidireccional. Vuele con cuidado", + "fr": "Erreur de détection d'obstacles omnidirectionnelle. Pilotez avec précaution", + "ja": "全方向障害物検知エラー。慎重に飛行してください", + "ko": "전방향 장애물 감지 오류. 비행 시 주의 필요", + "ru": "Ошибка определения препятствий на всех направлениях. Соблюдайте осторожность при полете", + "tr": "Çok yönlü engel algılama hatası. Dikkatlice uçurun", + "zh": "环视避障感知异常,请谨慎飞行" + }, + "fpv_tip_0x1A5104C7": { + "de": "Fehler: auf- und abwärts gerichtete Hinderniserkennung. Mit Vorsicht fliegen", + "en": "Upward and downward obstacle sensing error. Fly with caution", + "es": "Error de detección de obstáculos superior e inferior. Vuele con cuidado", + "fr": "Erreur de détection d'obstacles vers le haut et le bas. Pilotez avec précaution", + "ja": "上方および下方障害物検知エラー。慎重に飛行してください", + "ko": "상향 및 하향 장애물 감지 오류. 비행 시 주의 필요", + "ru": "Ошибка определения препятствий сверху и снизу. Соблюдайте осторожность при полете", + "tr": "Yukarı ve aşağı yönde engel algılama hatası. Dikkatlice uçurun", + "zh": "上下避障感知异常,请谨慎飞行" + }, + "fpv_tip_0x1A680040": { + "de": "Propellerschützer montiert. Hindernisvermeidung nicht verfügbar. Flugleistung und Windbeständigkeit herabgesetzt", + "en": "Propeller guards mounted. Obstacle Avoidance unavailable. Flight performance and wind resistance performance reduced", + "es": "Protectores para hélices instalados. Sistema anticolisión no disponible. Rendimiento de vuelo y rendimiento de resistencia al viento reducidos", + "fr": "Protections d’hélice installées. Évitement d’obstacles indisponible. Réduction des performances de vol et de résistance au vent", + "ja": "プロペラガードがマウントされました。障害物回避は使用できません。飛行性能と耐風性能が低下します", + "ko": "프로펠러 가드 장착됨. 장애물 회피 사용 불가. 비행 성능과 바람 저항 성능이 저하됩니다.", + "ru": "Установлена защита пропеллеров. Предотвращение столкновений недоступно. Эффективность полета и сопротивление ветру снижены", + "tr": "Pervane korumaları monte edildi. Engelden Kaçınma kullanılamıyor. Uçuş performansı ve rüzgar direnci performansı azaltıldı", + "zh": "桨叶保护罩已安装,避障功能失效,飞行性能和抗风性能降低" + }, + "fpv_tip_0x1A680080": { + "de": "Propellerschützer entfernt", + "en": "Propeller guards removed", + "es": "Protectores para hélices retirados", + "fr": "Protections d'hélice retirées", + "ja": "プロペラガードが取り外されました", + "ko": "프로펠러 가드 제거됨", + "ru": "Защита пропеллера снята", + "tr": "Pervane korumaları çıkarıldı", + "zh": "桨叶保护罩已移除" + }, + "fpv_tip_0x1AFD0040": { + "de": "Fehler: Sensorsystem. Kann nicht abheben. Fliegen untersagt", + "en": "Sensor system error. Unable to take off. Flight prohibited", + "es": "Error del sistema del sensor. No se puede despegar. Vuelo prohibido", + "fr": "Erreur système de capteurs. Décollage impossible. Vol interdit", + "ja": "センサーシステムエラー。離陸できません。飛行が禁止されています", + "ko": "센서 시스템 오류. 이륙 불가. 비행 금지", + "ru": "Ошибка системы датчиков. Невозможно выполнить взлет. Полет запрещен", + "tr": "Sensör sistem hatası. Kalkış yapamıyor. Uçuş yasaklandı", + "zh": "无法起飞:感知传感器系统异常,禁止起飞" + }, + "fpv_tip_0x1AFD0040_in_the_sky": { + "de": "Fehler: Sensorsystem. Sofort zurückkehren oder landen", + "en": "Sensor system error. Return to home or land promptly", + "es": "Error del sistema del sensor. Regresa al punto de origen o aterriza lo antes posible", + "fr": "Erreur système de capteurs. Revenez au point de départ et atterrissez immédiatement", + "ja": "センサーシステムエラー。直ちに帰還もしくは着陸してください", + "ko": "센서 시스템 오류. 즉시 RTH 또는 착륙 필요", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь немедленно", + "tr": "Sensör sistem hatası. Eve geri dönün veya düzgün iniş yapın", + "zh": "感知传感器系统异常,请尽快返航或降落" + }, + "fpv_tip_0x1AFE0040": { + "de": "Sichtsensoren überlastet. In offenen Bereich fliegen", + "en": "Vision system overloaded. Fly to open area", + "es": "Sistema de visión sobrecargado. Vuela a un espacio abierto", + "fr": "Système optique surchargé. Volez dans une zone dégagée", + "ja": "ビジョンシステム過負荷状態。開けた場所に飛行してください", + "ko": "비전 시스템 과부하. 개방 영역으로 비행하세요", + "ru": "Система обзора перегружена. Подлетите к открытому участку", + "tr": "Görüş sistemi aşırı yüklü. Aracı açık alanda uçurun", + "zh": "视觉系统负载过高,请谨慎飞行至开阔环境" + }, + "fpv_tip_0x1B010001": { + "de": "Systemfehler: Navigation . Fluggerät neu starten", + "en": "Navigation system error . Restart aircraft", + "es": "Error del sistema de navegación. Reinicia la aeronave", + "fr": "Erreur du système de navigation . Redémarrez l\\'appareil", + "ja": "ナビゲーションシステムエラー。機体を再起動してください", + "ko": "내비게이션 시스템 오류 . 기체 재시작 필요", + "ru": "Ошибка навигационной системы . Перезагрузите дрон", + "tr": "Navigasyon sistemi hatası. Aracı yeniden başlatın", + "zh": "导航系统异常,请重启飞行器" + }, + "fpv_tip_0x1B010002": { + "de": "Smarte Verfolgung für aktuelle Nutzlast nicht verfügbar", + "en": "Target Acquisition unavailable with current payload", + "es": "Smart Track no disponible con el instrumento actual", + "fr": "Smart Track indisponible avec la charge utile actuelle", + "ja": "現在のペイロードではスマートトラックを使用できません", + "ko": "현재 페이로드에서는 스마트 트랙을 사용할 수 없음", + "ru": "Интеллектуальное следование недоступно для текущей полезной нагрузки", + "tr": "Mevcut yük için Akıllı Takip kullanılamıyor", + "zh": "当前负载不支持目标锁定功能" + }, + "fpv_tip_0x1B010003": { + "de": "Zielerfassung im aktuellen Fotomodus nicht verfügbar", + "en": "Target Acquisition unavailable in current Photo mode", + "es": "Adquisición de objetivo no disponible en el modo Foto actual", + "fr": "Acquisition de sujet non disponible dans le mode Photo actuel", + "ja": "現在の写真モードでは被写体捕捉は利用できません", + "ko": "현재 사진 모드에서는 대상 수집을 사용할 수 없습니다", + "ru": "Захват цели недоступен в текущем режиме фото", + "tr": "Hedef Alımı mevcut Fotoğraf modunda kullanılamıyor", + "zh": "相机当前拍照模式下,无法开启目标锁定" + }, + "fpv_tip_0x1B010004": { + "de": "Ziel zu nah", + "en": "Target too close", + "es": "Objetivo demasiado cerca", + "fr": "Sujet trop proche", + "ja": "被写体が近すぎます", + "ko": "피사체 너무 가까움", + "ru": "Цель слишком близко", + "tr": "Hedef çok yakın", + "zh": "距离目标物体过近" + }, + "fpv_tip_0x1B010005": { + "de": "Ziel verloren. Smarte Verfolgung gestoppt", + "en": "Target lost. Target Acquisition paused", + "es": "Se ha perdido el objetivo. Smart Track detenido", + "fr": "Sujet perdu. Smart Track interrompu", + "ja": "ターゲットを見失いました。スマートトラック 停止", + "ko": "타겟 사라짐. 스마트 트랙 중지됨", + "ru": "Цель потеряна. Интеллектуальное следование остановлено", + "tr": "Hedef kayıp. Akıllı Takip durdu", + "zh": "目标已丢失,目标锁定功能停止" + }, + "fpv_tip_0x1B010006": { + "de": "Gimbal zeigt nicht in Flugrichtung. Vorsichtig fliegen", + "en": "Gimbal not facing flight direction. Fly with caution", + "es": "El estabilizador no está orientado en la dirección de vuelo. Vuela con precaución", + "fr": "La nacelle n'est pas orientée dans la direction du vol. Volez avec précaution", + "ja": "ジンバルが飛行方向を向いていません。慎重に飛行してください", + "ko": "짐벌, 비행 방향 향하지 않음. 비행 시 주의 필요", + "ru": "Стабилизатор направлен в сторону, отличную от направления полета. Будьте осторожны", + "tr": "Gimbal uçuş yönüne bakmıyor. Aracınızı dikkatli uçurun", + "zh": "云台已偏离航向,请谨慎飞行" + }, + "fpv_tip_0x1B010007": { + "de": "Smarte Verfolgung gestoppt . In P-Modus wechseln", + "en": "Target Acquisition paused . Switch to P mode", + "es": "Smart Track detenido. Cambia al modo P", + "fr": "Smart Track interrompu . Passez au mode P", + "ja": "スマートトラック停止。Pモードに切り替えてください", + "ko": "스마트 트랙 중지됨 . P 모드로 전환", + "ru": "Интеллектуальное следование остановлено . Переключитесь на режим P", + "tr": "Akıllı Takip durdu. P (Konumlandırma) moduna geçin", + "zh": "目标锁定功能停止,请切换飞行挡位至P挡" + }, + "fpv_tip_0x1B010007_n_mode": { + "de": "Zielerfassung gestoppt. Zu N-Modus wechseln", + "en": "Target Acquisition stopped. Switch to N mode", + "es": "Se ha detenido Adquisición de objetivo. Cambia al modo N", + "fr": "L'acquisition de la cible s'est arrêtée. Basculer en mode N", + "ja": "ターゲットを見失いました。Nモードに切り替えてください", + "ko": "대상 수집 중단됨. N 모드로 전환", + "ru": "Получение цели остановлено. Включите режим N", + "tr": "Hedef Alımı durduruldu. M moduna geçin", + "zh": "目标锁定功能停止,请切换飞行挡位至N挡" + }, + "fpv_tip_0x1B010008": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen", + "en": "Enabling Target Acquisition failed", + "es": "Error al activar Smart Track", + "fr": "Impossible d\\'activer Smart Track", + "ja": "スマートトラックを有効化できません", + "ko": "스마트 트랙 활성화 실패", + "ru": "Не удалось включить интеллектуальное следование", + "tr": "Akıllı Takip Etkinleştirme başarısız", + "zh": "目标锁定功能开启失败" + }, + "fpv_tip_0x1B010009": { + "de": "Hindernis erkannt. Fluggerät schwebt. Bitte manuell steuern, um Hindernissen auszuweichen", + "en": "Obstacle detected. Circling stopped. Manually control aircraft to avoid obstacle", + "es": "Obstáculo detectado. Vuelo en círculos detenido. Controla la aeronave manualmente para evitar los obstáculos", + "fr": "Obstacle détecté. Cercle interrompu. Contrôlez l\\'appareil manuellement pour éviter l\\'obstacle", + "ja": "障害物を検出。旋回を停止しました。機体を手動で操作し、障害物を避けてください", + "ko": "장애물 감지됨. 궤도 선회 정지됨. 기체 수동으로 제어해 장애물 피해야 함", + "ru": "Определено препятствие. Кружение остановлено. Управляйте дроном вручную, чтобы избегать препятствия", + "tr": "Engel tespit edildi. Turlama durdu. Engelleri aşmak için aracı manuel olarak kontrol edin", + "zh": "遇到障碍物,停止环绕,请手动控制飞机远离障碍" + }, + "fpv_tip_0x1B01000A": { + "de": "GEO-Zone in der Nähe. Fluggerät schwebt. Bitte manuell steuern, um GEO-Zone auszuweichen", + "en": "GEO Zone nearby. Circling stopped. Manually control aircraft to avoid GEO Zone", + "es": "Zona GEO cercana. Vuelo en círculos detenido. Controla la aeronave manualmente para evitar la zona GEO", + "fr": "Zone GEO proche. Cercle interrompu. Contrôlez l\\'appareil manuellement pour éviter la zone GEO", + "ja": "GEO区域が近くにあります。旋回を停止しました。機体を手動で操作し、GEO区域を避けてください", + "ko": "GEO 구역 인근. 궤도 선회 정지됨. 기체 수동으로 제어해 GEO 구역을 피해야 함", + "ru": "Зона GEO неподалеку. Кружение остановлено. Управляйте дроном вручную, чтобы не попасть в нее", + "tr": "GEO Bölgesi yakın. Turlama durdu. GEO Bölgesine girişi önlemek için aracı manuel olarak kontrol edin", + "zh": "遇到限飞区,停止环绕,请手动控制飞机远离限飞区" + }, + "fpv_tip_0x1B01000B": { + "de": "Smarte Verfolgung unterbrochen", + "en": "Smart Track paused", + "es": "Smart Track pausado", + "fr": "Smart Track mis en pause", + "ja": "スマートトラック一時停止", + "ko": "스마트 트랙 일시 중지됨", + "ru": "Интеллектуальное следование приостановлено", + "tr": "Akıllı Takip duraklatıldı", + "zh": "智能跟踪功能停止" + }, + "fpv_tip_0x1B01000C": { + "de": "Ziel bewegt sich zu schnell. Fluggerät schwebt.", + "en": "Target moving too fast. Circling stopped", + "es": "El objetivo se mueve demasiado rápido. Vuelo en círculos detenido", + "fr": "Sujet trop rapide. Cercle interrompu", + "ja": "被写体の移動が速すぎます。旋回を停止しました", + "ko": "피사체 움직임 너무 빠름. 궤도 선회 정지됨", + "ru": "Цель движется слишком быстро. Кружение остановлено", + "tr": "Hedef hızlı hareket ediyor. Turlama durdu", + "zh": "目标物体运动过快,停止环绕" + }, + "fpv_tip_0x1B01000D": { + "de": "Ungewöhnliche Zielbewegung. Ziel erneut durch Ziehen auswählen", + "en": "Unusual target movement. Drag-select target again", + "es": "Movimiento inusual del objetivo. Vuelve a arrastrar para seleccionar el objetivo", + "fr": "Mouvement du sujet inhabituel. Encadrez-le à nouveau", + "ja": "ターゲットの異常動作。ドラッグしてターゲットを再度選択してください", + "ko": "특이한 타겟 이동. 다시 타겟을 끌어서 선택하세요", + "ru": "Необычное перемещение цели. Снова перетащите и выберите цель", + "tr": "Hedef olağandışı bir şekilde hareket ediyor. Tekrar hedefi sürükleyip seçin", + "zh": "目标发生异常移动,请重新确认目标" + }, + "fpv_tip_0x1B01000E": { + "de": "GPS-Signal schwach und Sichtpositionierung nicht verfügbar. Fluggerät wechselt in den Modus \"A\". Fluggerät bitte manuell steuern (%alarmid)", + "en": "GPS signal weak and vision positioning unavailable. Aircraft switched to A mode. Control aircraft manually", + "es": "Señal GPS débil y posicionamiento visual no disponible. La aeronave ha cambiado al modo A. Controla la aeronave manualmente", + "fr": "Signal GPS faible et positionnement visuel non disponible. Appareil passé en mode A. Contrôlez l\\'appareil manuellement", + "ja": "GPS 信号が弱く、ビジョンポジショニングが使用できません。機体が A モードに切り替わりました。機体を手動で操作してください", + "ko": "GPS 신호가 약하고 비전 포지셔닝 사용 불가. 기체가 A 모드로 전환됨. 기체를 수동으로 조종", + "ru": "Слабый сигнал GPS и визуальное позиционирование недоступно Дрон переведен в режим A. Управляйте дроном вручную", + "tr": "GPS sinyali zayıf ve görüş konumlandırma kullanılamıyor. Araç A moduna geçti. Aracı manuel olarak kontrol edin", + "zh": "GPS信号弱且视觉定位失效,飞行器切换至姿态模式,请手动控制飞行器" + }, + "fpv_tip_0x1B01000F": { + "de": "Ziel verloren. Suche...", + "en": "Target lost. Searching...", + "es": "Se ha perdido el objetivo. Buscando...", + "fr": "Sujet perdu. Recherche en cours", + "ja": "ターゲットを見失いました。探索中...", + "ko": "타겟 사라짐. 검색 중...", + "ru": "Цель потеряна. Идет поиск...", + "tr": "Hedef kayıp. Arıyor…", + "zh": "目标丢失,正在搜索中" + }, + "fpv_tip_0x1B010010": { + "de": "Während der smarten Verfolgung können Gimbals innerhalb gewisser Grenzen gesteuert werden", + "en": "During Smart Track, you can control gimbals within a certain limit", + "es": "Durante Smart Track, puedes controlar los estabilizadores dentro un límite", + "fr": "Pendant Smart Track, vous pouvez contrôler les nacelles jusqu\\'à une certaine limite", + "ja": "スマートトラックの間、一定の制限内でジンバルを制御できます", + "ko": "스마트 트랙 중에 특정 제한 내에서 짐벌을 제어할 수 있습니다", + "ru": "При интеллектуальном следовании подвесами можно управлять с соблюдением определенного ограничения", + "tr": "Akıllı Takip sırasında gimbalları belirli bir sınır içinde kontrol edebilirsiniz", + "zh": "智能跟踪时只能在一定范围内控制云台" + }, + "fpv_tip_0x1B010011": { + "de": "Während der smarten Verfolgung kann das Zoomobjektiv innerhalb gewisser Grenzen gesteuert werden", + "en": "During Smart Track, you can control lens zoom within a certain limit", + "es": "Durante Smart Track, puedes controlar el zoom del objetivo dentro un límite", + "fr": "Pendant Smart Track, vous pouvez contrôler le zoom de l\\'objectif jusqu\\'à une certaine limite", + "ja": "スマートトラックの間、一定の制限内でレンズズームを制御できます", + "ko": "스마트 트랙 중에 특정 제한 내에서 렌즈 줌을 제어할 수 있습니다", + "ru": "При интеллектуальном следовании зумом объектива можно управлять с соблюдением определенного ограничения", + "tr": "Akıllı Takip sırasında lens yakınlaştırmalarını belirli bir sınır içinde kontrol edebilirsiniz", + "zh": "智能跟踪时只能在一定范围内控制变焦" + }, + "fpv_tip_0x1B010401": { + "de": "Fehler beim Senden von Daten durch die Kamera. Zielerfassung angehalten. Später erneut versuchen", + "en": "Camera sending data error. Target acquisition stopped. Try again later", + "es": "Ha fallado el envío de datos de la cámara. Se ha detenido la adquisición de objetivo. Inténtelo de nuevo más tarde", + "fr": "Erreur d'envoi des données par la caméra. L'acquisition de la cible s'est arrêtée. Réessayez plus tard", + "ja": "カメラのデータ送信エラーです。ターゲットを見失いました。後で再試行してください", + "ko": "카메라 전송 데이터 오류. 대상 수집 중단됨. 나중에 다시 시도하세요", + "ru": "Ошибка отправки данных с камеры. Получение цели остановлено. Повторите попытку позже", + "tr": "Kamera veri gönderme hatası. Hedef alımı durduruldu. Daha sonra tekrar deneyin", + "zh": "相机发送数据异常,目标锁定功能停止,请稍后重试" + }, + "fpv_tip_0x1B010402": { + "de": "Fehler beim Senden von Daten durch die Kamera. Smart Track angehalten. Später erneut versuchen", + "en": "Camera sending data error. Smart Track stopped. Try again later", + "es": "Ha fallado el envío de datos de la cámara. Se ha detenido Smart Track. Inténtelo de nuevo más tarde", + "fr": "Erreur d'envoi des données par la caméra. Smart Track s'est arrêté. Réessayez plus tard", + "ja": "カメラのデータ送信エラーです。スマートトラックが停止しました。後で再試行してください", + "ko": "카메라 전송 데이터 오류. 스마트 트랙 중단됨. 나중에 다시 시도하세요", + "ru": "Ошибка отправки данных с камеры. Интеллектуальное следование остановлено. Повторите попытку позже", + "tr": "Kamera veri gönderme hatası. Akıllı Takip durdu. Daha sonra tekrar deneyin", + "zh": "相机发送数据异常,智能跟踪功能停止,请稍后重试" + }, + "fpv_tip_0x1B010403": { + "ar": "", + "de": "Kamera: Fehler bei Datenversand. Smarte Verfolgung unterbrochen.", + "en": "Camera data sending error. Smart Track paused.", + "es": "Error de envío de datos de la cámara. Smart Track pausado.", + "fr": "Erreur d'envoi des données de la caméra. Smart Track mis en pause.", + "it": "", + "ja": "カメラデータ送信エラー。スマートトラック一時停止。", + "ko": "카메라 데이터 전송 오류. 스마트 트랙 일시 중지됨.", + "pt": "", + "ru": "Ошибка отправки данных камеры. Интеллектуальное следование приостановлено.", + "tr": "Kamera veri gönderme hatası. Akıllı Takip duraklatıldı.", + "zh": "相机发送数据异常,智能跟踪功能停止" + }, + "fpv_tip_0x1B010404": { + "de": "Fehler beim Senden von Daten durch die Kamera. Smart Track angehalten. Später erneut versuchen", + "en": "Camera sending data error. Smart Track stopped. Try again later", + "es": "Ha fallado el envío de datos de la cámara. Se ha detenido Smart Track. Inténtelo de nuevo más tarde", + "fr": "Erreur d'envoi des données par la caméra. Smart Track s'est arrêté. Réessayez plus tard", + "ja": "カメラのデータ送信エラーです。スマートトラックが停止しました。後で再試行してください", + "ko": "카메라 전송 데이터 오류. 스마트 트랙 중단됨. 나중에 다시 시도하세요", + "ru": "Ошибка отправки данных с камеры. Интеллектуальное следование остановлено. Повторите попытку позже", + "tr": "Kamera veri gönderme hatası. Akıllı Takip durdu. Daha sonra tekrar deneyin", + "zh": "相机数据发送异常,智能跟踪功能停止,请稍后重试" + }, + "fpv_tip_0x1B010405": { + "de": "Fehler beim Senden von Daten durch die Kamera. Smart Track angehalten. Später erneut versuchen", + "en": "Camera sending data error. Smart Track stopped. Try again later", + "es": "Ha fallado el envío de datos de la cámara. Se ha detenido Smart Track. Inténtelo de nuevo más tarde", + "fr": "Erreur d'envoi des données par la caméra. Smart Track s'est arrêté. Réessayez plus tard", + "ja": "カメラのデータ送信エラーです。スマートトラックが停止しました。後で再試行してください", + "ko": "카메라 전송 데이터 오류. 스마트 트랙 중단됨. 나중에 다시 시도하세요", + "ru": "Ошибка отправки данных с камеры. Интеллектуальное следование остановлено. Повторите попытку позже", + "tr": "Kamera veri gönderme hatası. Akıllı Takip durdu. Daha sonra tekrar deneyin", + "zh": "相机发送数据异常,智能跟踪功能停止,请稍后重试" + }, + "fpv_tip_0x1B010406": { + "de": "Fehler beim Senden von Daten durch die Kamera. Smart Track angehalten. Später erneut versuchen", + "en": "Camera sending data error. Smart Track stopped. Try again later", + "es": "Ha fallado el envío de datos de la cámara. Se ha detenido Smart Track. Inténtelo de nuevo más tarde", + "fr": "Erreur d'envoi des données par la caméra. Smart Track s'est arrêté. Réessayez plus tard", + "ja": "カメラのデータ送信エラーです。スマートトラックが停止しました。後で再試行してください", + "ko": "카메라 전송 데이터 오류. 스마트 트랙 중단됨. 나중에 다시 시도하세요", + "ru": "Ошибка отправки данных с камеры. Интеллектуальное следование остановлено. Повторите попытку позже", + "tr": "Kamera veri gönderme hatası. Akıllı Takip durdu. Daha sonra tekrar deneyin", + "zh": "相机发送数据异常,智能跟踪功能停止,请稍后重试" + }, + "fpv_tip_0x1B010407": { + "de": "Fehler beim Senden von Daten durch die Kamera. Smart Track angehalten. Später erneut versuchen", + "en": "Camera sending data error. Smart Track stopped. Try again later", + "es": "Ha fallado el envío de datos de la cámara. Se ha detenido Smart Track. Inténtelo de nuevo más tarde", + "fr": "Erreur d'envoi des données par la caméra. Smart Track s'est arrêté. Réessayez plus tard", + "ja": "カメラのデータ送信エラーです。スマートトラックが停止しました。後で再試行してください", + "ko": "카메라 전송 데이터 오류. 스마트 트랙 중단됨. 나중에 다시 시도하세요", + "ru": "Ошибка отправки данных с камеры. Интеллектуальное следование остановлено. Повторите попытку позже", + "tr": "Kamera veri gönderme hatası. Akıllı Takip durdu. Daha sonra tekrar deneyin", + "zh": "相机发送数据异常,智能跟踪功能停止,请稍后重试" + }, + "fpv_tip_0x1B010408": { + "de": "Fehler beim Senden von Daten durch die Kamera. Smart Track angehalten. Später erneut versuchen", + "en": "Camera sending data error. Smart Track stopped. Try again later", + "es": "Ha fallado el envío de datos de la cámara. Se ha detenido Smart Track. Inténtelo de nuevo más tarde", + "fr": "Erreur d'envoi des données par la caméra. Smart Track s'est arrêté. Réessayez plus tard", + "ja": "カメラのデータ送信エラーです。スマートトラックが停止しました。後で再試行してください", + "ko": "카메라 전송 데이터 오류. 스마트 트랙 중단됨. 나중에 다시 시도하세요", + "ru": "Ошибка отправки данных с камеры. Интеллектуальное следование остановлено. Повторите попытку позже", + "tr": "Kamera veri gönderme hatası. Akıllı Takip durdu. Daha sonra tekrar deneyin", + "zh": "相机发送数据异常,智能跟踪功能停止,请稍后重试" + }, + "fpv_tip_0x1B010801": { + "de": "Parameter der Kamera geändert. Smarte Verfolgung gestoppt", + "en": "DJI Pilot error. Target Acquisition paused. Restart DJI Pilot", + "es": "Parámetros de la cámara modificados. Smart Track detenido", + "fr": "Paramètres de caméra modifiés. Smart Track interrompu", + "ja": "カメラパラメーターを変更。スマートトラック停止", + "ko": "카메라 매개변수 변경됨. 스마트 트랙 중지됨", + "ru": "Параметры камеры изменены. Интеллектуальное следование остановлено", + "tr": "Kamera parametreleri değişti. Akıllı Takip durdu", + "zh": "APP状态异常,目标锁定功能停止,请重启APP" + }, + "fpv_tip_0x1B010802": { + "de": "Fehler: DJI Pilot. Smarte Verfolgung unterbrochen. DJI Pilot neu starten", + "en": "DJI Pilot error. Smart Track paused. Restart DJI Pilot", + "es": "Error de DJI Pilot. Smart Track pausado. Reinicia DJI Pilot", + "fr": "Erreur de DJI Pilot. Smart Track mis en pause. Redémarrez DJI Pilot", + "ja": "DJI Pilotエラー。スマートトラック一時停止。DJI Pilotを再起動してください", + "ko": "DJI Pilot 오류. 스마트 트랙 일시 중지됨. DJI Pilot 재시작 필요", + "ru": "Ошибка DJI Pilot. Интеллектуальное следование приостановлено. Перезапустите DJI Pilot", + "tr": "DJI Pilot hatası. Akıllı Takip duraklatıldı. DJI Pilot’u yeniden başlat", + "zh": "智能跟踪功能异常,请重启APP" + }, + "fpv_tip_0x1B010803": { + "de": "Fehler: DJI Pilot. Smarte Verfolgung unterbrochen. DJI Pilot neu starten", + "en": "DJI Pilot error. Smart Track paused. Restart DJI Pilot", + "es": "Error de DJI Pilot. Smart Track pausado. Reinicia DJI Pilot", + "fr": "Erreur de DJI Pilot. Smart Track mis en pause. Redémarrez DJI Pilot", + "ja": "DJI Pilotエラー。スマートトラック一時停止。DJI Pilotを再起動してください", + "ko": "DJI Pilot 오류. 스마트 트랙 일시 중지됨. DJI Pilot 재시작 필요", + "ru": "Ошибка DJI Pilot. Интеллектуальное следование приостановлено. Перезапустите DJI Pilot", + "tr": "DJI Pilot hatası. Akıllı Takip duraklatıldı. DJI Pilot’u yeniden başlat", + "zh": "智能跟踪功能异常,请重启APP" + }, + "fpv_tip_0x1B010C01": { + "de": "Ziel verloren. Smarte Verfolgung gestoppt", + "en": "Flight Controller data sending error. Target Acquisition paused. Restart aircraft", + "es": "Se ha perdido el objetivo. Smart Track detenido", + "fr": "Sujet perdu. Smart Track interrompu", + "ja": "ターゲットを見失いました。スマートトラック終了", + "ko": "타겟 사라짐. 스마트 트랙 중지됨", + "ru": "Цель потеряна. Интеллектуальное следование остановлено", + "tr": "Hedef kayıp. Akıllı Takip durdu", + "zh": "飞控数据发送异常,目标锁定功能停止,请重启飞行器" + }, + "fpv_tip_0x1B010C02": { + "de": "Flugregler: Fehler bei Datenversand. Smarte Verfolgung unterbrochen. Fluggerät neu starten", + "en": "Flight Controller data sending error. Smart Track paused. Restart aircraft", + "es": "Error de envío de datos del controlador de vuelo. Smart Track pausado. Reinicia la aeronave", + "fr": "Erreur d'envoi des données du contrôleur de vol. Smart Track mis en pause. Redémarrez l'appareil", + "ja": "フライトコントローラー データ送信エラー。スマートトラック一時停止。機体を再起動してください", + "ko": "비행 컨트롤러 데이터 전송 오류. 스마트 트랙 일시 중지됨. 기체 재시작 필요", + "ru": "Ошибка отправки данных полетного контроллера. Интеллектуальное следование приостановлено. Перезагрузите дрон", + "tr": "Uçuş Kumandası veri gönderme hatası. Akıllı Takip duraklatıldı. Aracı yeniden başlatın", + "zh": "飞控数据发送异常,智能跟踪功能停止,请重启飞行器" + }, + "fpv_tip_0x1B010C03": { + "de": "Flugregler: Fehler bei Datenversand. Smarte Verfolgung unterbrochen. Fluggerät neu starten", + "en": "Flight Controller data sending error. Smart Track paused. Restart aircraft", + "es": "Error de envío de datos del controlador de vuelo. Smart Track pausado. Reinicia la aeronave", + "fr": "Erreur d'envoi des données du contrôleur de vol. Smart Track mis en pause. Redémarrez l'appareil", + "ja": "フライトコントローラー データ送信エラー。スマートトラック一時停止。機体を再起動してください", + "ko": "비행 컨트롤러 데이터 전송 오류. 스마트 트랙 일시 중지됨. 기체 재시작 필요", + "ru": "Ошибка отправки данных полетного контроллера. Интеллектуальное следование приостановлено. Перезагрузите дрон", + "tr": "Uçuş Kumandası veri gönderme hatası. Akıllı Takip duraklatıldı. Aracı yeniden başlatın", + "zh": "飞控数据发送异常,智能跟踪功能停止,请重启飞行器" + }, + "fpv_tip_0x1B011001": { + "de": "Gimbal: Fehler bei Datenversand. Smarte Verfolgung gestoppt. Nutzlast neu installieren", + "en": "Gimbal data sending error. Target Acquisition paused. Reinstall payload", + "es": "Error de envío de datos del estabilizador. Smart Track detenido. Vuelve a instalar el instrumento", + "fr": "Erreur d\\'envoi de données de la nacelle. Smart Track interrompu. Réinstallez la charge utile", + "ja": "ジンバルデータ送信エラー。スマートトラック停止。ペイロードを再取り付けしてください", + "ko": "짐벌 데이터 전송 오류. 스마트 트랙 중지됨. 페이로드 재설치", + "ru": "Ошибка отправки данных подвеса. Интеллектуальное следование остановлено. Переустановите полезную нагрузку", + "tr": "Gimbal veri gönderme hatası. Akıllı Takip durdu. Yükü tekrar takın", + "zh": "云台数据发送异常,目标锁定功能停止,请重新拔插负载" + }, + "fpv_tip_0x1B011002": { + "de": "Gimbal: Fehler bei Datenversand. Smarte Verfolgung unterbrochen. Nutzlast neu installieren", + "en": "Gimbal data sending error. Smart Track paused. Reinstall payload", + "es": "Error de envío de datos del estabilizador. Smart Track pausado. Vuelve a instalar el instrumento", + "fr": "Erreur d'envoi des données de la nacelle. Smart Track mis en pause. Réinstallez la nacelle-caméra", + "ja": "ジンバルデータ送信エラー。スマートトラック一時停止。ペイロードを再度取り付けてください", + "ko": "짐벌 데이터 전송 오류. 스마트 트랙 일시 중지됨. 페이로드 재설치 필요", + "ru": "Ошибка отправки данных стабилизатора. Интеллектуальное следование приостановлено. Установите оборудование снова", + "tr": "Gimbal veri gönderme hatası. Akıllı Takip duraklatıldı. Yükü tekrar takın", + "zh": "云台数据发送异常,智能跟踪功能停止,请重新拔插负载" + }, + "fpv_tip_0x1B011003": { + "de": "Gimbal: Fehler bei Datenversand. Smarte Verfolgung unterbrochen. Nutzlast neu installieren", + "en": "Gimbal data sending error. Smart Track paused. Reinstall payload", + "es": "Error de envío de datos del estabilizador. Smart Track pausado. Vuelve a instalar el instrumento", + "fr": "Erreur d'envoi des données de la nacelle. Smart Track mis en pause. Réinstallez la nacelle-caméra", + "ja": "ジンバルデータ送信エラー。スマートトラック一時停止。ペイロードを再度取り付けてください", + "ko": "짐벌 데이터 전송 오류. 스마트 트랙 일시 중지됨. 페이로드 재설치 필요", + "ru": "Ошибка отправки данных стабилизатора. Интеллектуальное следование приостановлено. Установите оборудование снова", + "tr": "Gimbal veri gönderme hatası. Akıllı Takip duraklatıldı. Yükü tekrar takın", + "zh": "云台数据发送异常,智能跟踪功能停止,请重新拔插负载" + }, + "fpv_tip_0x1B011801": { + "de": "Fernsteuerung: Fehler bei Datenversand. Smarte Verfolgung gestoppt. Fernsteuerung neu starten", + "en": "Remote controller data sending error. Target Acquisition stopped. Restart RC", + "es": "Error de envío de datos del control remoto. Smart Track detenido. Reinicia el CR", + "fr": "Erreur d\\'envoi de données de la radiocommande (RC). Smart Track interrompu. Redémarrez la RC", + "ja": "送信機データ送信エラー。スマートトラック停止。送信機を再起動してください", + "ko": "조종기 데이터 전송 오류. 스마트 트랙 중지됨. 조종기 다시 시작", + "ru": "Ошибка отправки данных пульта ДУ. Интеллектуальное следование остановлено. Перезапустите пульт ДУ", + "tr": "Uzaktan kumanda veri gönderme hatası. Akıllı Takip durdu. Uzaktan kumandayı tekrar başlatın", + "zh": "遥控器数据发送异常,目标锁定功能停止,请重启遥控器" + }, + "fpv_tip_0x1B011802": { + "de": "Fernsteuerung: Fehler bei Datenversand. Smarte Verfolgung gestoppt. Verbindung zwischen Fernsteuerung und Fluggerät überprüfen", + "en": "Remote controller data sending error. Target Acquisition paused. Check connection between RC and aircraft", + "es": "Error de envío de datos del control remoto. Smart Track detenido. Comprueba la conexión entre el CR y la aeronave", + "fr": "Erreur d\\'envoi de données de la radiocommande (RC). Smart Track interrompu. Vérifiez la connexion entre la RC et l\\'appareil", + "ja": "送信機データ送信エラー。スマートトラック停止。送信機と機体の接続を確認してください", + "ko": "조종기 데이터 전송 오류. 스마트 트랙 중지됨. 조종기와 기체 간 연결을 확인하세요", + "ru": "Ошибка отправки данных пульта ДУ. Интеллектуальное следование остановлено. Проверьте соединение между пультом ДУ и дроном", + "tr": "Uzaktan kumanda veri gönderme hatası. Akıllı Takip durdu. Uzaktan kumanda ve araç arasındaki bağlantıyı kontrol edin", + "zh": "遥控器数据发送异常,目标锁定功能停止,请检查遥控器与飞行器的连接状况" + }, + "fpv_tip_0x1B030001": { + "de": "Hindernis erkannt. Rückkehr gestoppt. Fluggerät manuell steuern, um Hindernissen auszuweichen", + "en": "Obstacle detected. RTH stopped. Manually control aircraft to avoid obstacle", + "es": "Obstáculo detectado. RPO detenido. Controla la aeronave manualmente para evitar los obstáculos", + "fr": "Obstacle détecté. RTH interrompu. Contrôlez l\\'appareil manuellement pour éviter l\\'obstacle", + "ja": "障害物を検出。RTHを停止。機体を手動で操作し、障害物を避けてください", + "ko": "장애물 감지됨. RTH 중단. 기체 수동으로 제어해 장애물 피해야 함", + "ru": "Определено препятствие. Возврат домой остановлен. Управляйте дроном вручную, чтобы избегать препятствия", + "tr": "Engel tespit edildi. Eve dönüş durdu. Engelleri aşmak için aracı manuel olarak kontrol edin", + "zh": "遇到障碍物,自动返航停止,请手动控制飞机远离障碍" + }, + "fpv_tip_0x1B030002": { + "de": "GEO-Zone in der Nähe. Rückkehr gestoppt. Bitte manuell steuern, um GEO-Zone auszuweichen", + "en": "GEO Zone nearby. RTH stopped. Manually control aircraft to avoid GEO Zone", + "es": "Zona GEO cercana. RPO detenido. Controla la aeronave manualmente para evitar la zona GEO", + "fr": "Zone GEO proche. RTH interrompu. Contrôlez l\\'appareil manuellement pour éviter la zone GEO", + "ja": "GEO区域が近くにあります。RTHを停止。機体を手動で操作し、GEO区域を避けてください", + "ko": "GEO 구역 인근. RTH 중단. 기체 수동으로 제어해 GEO 구역을 피해야 함", + "ru": "Зона GEO неподалеку. Возврат домой остановлен. Управляйте дроном вручную, чтобы не попасть в нее", + "tr": "GEO Bölgesi yakın. Eve dönüş durdu. GEO Bölgesine girişi önlemek için aracı manuel olarak kontrol edin", + "zh": "遇到限飞区,自动返航停止,请手动控制飞机远离限飞区" + }, + "fpv_tip_0x1B030003": { + "de": "Rückkehrfehler. Fluggerät manuell steuern", + "en": "RTH error. Fly aircraft manually", + "es": "Error de RPO. Vuela la aeronave manualmente", + "fr": "Erreur RTH. Contrôlez l\\'appareil manuellement", + "ja": "RTHエラー。機体を手動で飛行してください", + "ko": "RTH 오류. 기체 수동 비행 필요", + "ru": "Ошибка возврата домой. Управляйте дроном вручную", + "tr": "Eve dönüş hatası. Aracı manuel olarak uçurun", + "zh": "自动返航异常,请切换至手动飞行" + }, + "fpv_tip_0x1B030004": { + "de": "Fluggerätsignal verloren. Rückkehrfunktion (RTH) gestartet", + "en": "Aircraft signal lost. RTH started", + "es": "Se ha perdido la señal de la aeronave. RPO iniciado", + "fr": "Signal de l'appareil perdu. RTH lancé", + "ja": "機体の信号ロストです。RTHが開始しました", + "ko": "기체 신호 끊김. RTH 시작됨", + "ru": "Сигнал дрона потерян. Возврат домой начался", + "tr": "Hava aracı sinyali kayboldu. Eve Dönüş başladı", + "zh": "飞行器失联,开始返航" + }, + "fpv_tip_0x1B030005": { + "de": "Aktivieren der Hindernisvermeidung bei Rückkehr fehlgeschlagen. Fluggerät manuell steuern, um zurückzukehren", + "en": "Enabling RTH Obstacle Check failed. Control aircraft to return to home manually", + "es": "Error al activar la comprobación de obstáculos de RPO. Controla la aeronave manualmente para regresar al punto de origen", + "fr": "Impossible d\\'activer la détection d\\'obstacles RTH. Contrôlez l\\'appareil manuellement pour retourner au point de départ", + "ja": "RTH障害物確認の有効化に失敗しました。機体を操作して手動でホームに帰還してください", + "ko": "\\'RTH 장애물 확인\\' 활성화 실패. 기체 수동으로 제어해 RTH 진행해야 함", + "ru": "Сбой активации проверки препятствий при возврате домой. Управляйте дроном вручную", + "tr": "Eve Dönüş Engel Kontrolü etkinleştirme başarısız. Aracı eve döndürmek için manuel olarak kumanda edin", + "zh": "自动返航避障功能启动失败,请切换至手动返航" + }, + "fpv_tip_0x1B030006": { + "de": "Hindernis oder Gegenlicht erkannt. Pause-Taste auf der Fernsteuerung drücken, um autom. Rückkehr abzubrechen und das Fluggerät manuell zurückzufliegen", + "en": "Obstacle avoidance or backlight detected. Press the Pause button on the remote controller to exit RTH and manually control aircraft to return to home", + "es": "Detectado sistema anticolisión o luz trasera. Pulsa el botón de pausa del control remoto para abandonar el RPO y controla manualmente la aeronave para regresar al punto de origen", + "fr": "Évitement d'obstacles ou rétroéclairage détecté. Appuyez sur le bouton Pause de la radiocommande pour sortir du RTH et contrôler manuellement le retour au point de départ", + "ja": "障害物または逆光を検知。送信機の一時停止ボタンを押してRTHを終了し、手動で機体を制御して帰還させてください", + "ko": "장애물 회피 또는 백라이트 감지. 조종기의 '일시 정지' 버튼 눌러 RTH 종료하고 기체 수동으로 홈 복귀 필요", + "ru": "Обнаружено распознавание препятствий или подсветка. Нажмите кнопку паузы на пульте управления, чтобы отменить возврат домой, и вручную управляйте дроном, чтобы вернуться в домашнюю точку", + "tr": "Engellerden kaçınma veya arka ışık tespit edildi. Hava aracının RTH özelliği iptal edildi", + "zh": "遇到障碍物或环境逆光,请按遥控器上暂停键退出自动返航,进行手动返航" + }, + "fpv_tip_0x1B030007": { + "de": "Steuerknüppel nach unten gedrückt. Fluggerät sinkt. Rückkehr abgebrochen", + "en": "Control stick pushed down. Aircraft descending. Aircraft RTH canceled", + "es": "Palanca de control movida hacia abajo. Aeronave en descenso. RPO cancelado", + "fr": "Joystick abaissé. L'appareil descend. RTH appareil annulé", + "ja": "操作スティックが下に倒され、機体が下降中。機体のRTHはキャンセルされました", + "ko": "조종 스틱 아래로 눌림. 기체 하강. 기체 RTH 취소됨", + "ru": "Джойстик опущен вниз. Дрон снижается. Возврат домой отменен", + "tr": "Kontrol çubuğu aşağı bastırıldı. Hava aracı alçalıyor. Hava aracının RTH özelliği iptal edildi", + "zh": "检测到打杆下降,已退出自动返航" + }, + "fpv_tip_0x1B030008": { + "de": "Steuerknüppel nach unten gedrückt. Fluggerät fliegt rückwärts. Rückkehr abgebrochen", + "en": "Control stick pushed down. Aircraft flying backward. Aircraft RTH canceled", + "es": "Palanca de control movida hacia abajo. Aeronave volando hacia atrás. RPO cancelado", + "fr": "Joystick abaissé. L'appareil vole vers l'arrière. RTH appareil annulé", + "ja": "操作スティックが下に倒され、機体は後方に飛行。機体のRTHはキャンセルされました", + "ko": "조종 스틱 아래로 눌림. 기체 후방 비행. 기체 RTH 취소됨", + "ru": "Джойстик опущен вниз. Дрон летит назад. Возврат домой отменен", + "tr": "Kontrol çubuğu aşağı bastırıldı. Hava aracı geri geri uçuyor. Hava aracının RTH özelliği iptal edildi", + "zh": "检测到打杆后退,已退出自动返航" + }, + "fpv_tip_0x1B03000D": { + "de": "Schlechte Positionierung beim Ausführen der Rückkehrfunktion (RTH). Rückkehrfunktion (RTH) kann nicht fortgesetzt werden. Fluggerät von Hand zurückfliegen", + "en": "Positioning poor during RTH. Unable to continue RTH. Manually control aircraft to return to home", + "es": "Posicionamiento deficiente durante RPO. El RPO no puede continuar. Controle la aeronave manualmente para regresar al punto de origen", + "fr": "Mauvais positionnement pendant le RTH. Impossible de continuer le RTH. Contrôlez manuellement l'appareil pour la fonction Return-to-Home", + "ja": "RTH中の測位が不良。RTHを続行できません。手動で機体を操作して帰還させてください", + "ko": "RTH 중 포지셔닝 불량. RTH를 계속 진행할 수 없습니다. 기체를 수동으로 조종해 RTH를 수행하세요", + "ru": "Несоответствующее позиционирование во время возврата домой. Не удается продолжить возврат домой. Вручную управляйте дроном, чтобы вернуться домой", + "tr": "RTH sırasında konumlama zayıf. RHT'ye devam edilemiyor. Başlangıç noktasına dönmek için hava aracını manuel olarak kontrol edin", + "zh": "返航过程中定位不佳,无法继续返航。请手动控制飞机返航" + }, + "fpv_tip_0x1B030010": { + "de": "Es wird bald Abend. Einstellung der RTH-Flughöhe empfohlen.", + "en": "Approaching evening. Setting RTH altitude recommended", + "es": "Se acerca la noche. Configuración de la altitud de RPO recomendada", + "fr": "Approche du soir. Réglage de l'altitude RTH recommandé", + "ja": "夕刻に近づいています。RTH高度の設定が推奨されます", + "ko": "저녁이 가까워지고 있습니다. RTH 고도 설정을 권장합니다.", + "ru": "Приближается вечер. Рекомендуется установка высоты RTH", + "tr": "Akşam yaklaşıyor. BND irtifasının ayarlanması önerilir", + "zh": "临近夜晚,请提前设置好返航高度" + }, + "fpv_tip_0x1B030011": { + "de": "Fehler beim Fliegen der optimalen Rückkehrroute. Fluggerät kehrt auf voreingestellter Flughöhe zurück", + "en": "Failed to fly optimal RTH route. Aircraft returning at preset altitude", + "es": "No se ha podido volar por la ruta RPO óptima. La aeronave está regresando a la altitud preestablecida.", + "fr": "Échec de trajectoire RTH optimale. L'appareil retourne au point de départ à une altitude prédéfinie", + "ja": "最適なRTHルートの飛行に失敗。機体はプリセット高度で帰還中です", + "ko": "최적의 RTH 경로로 비행 실패. 기체가 사전 설정된 고도에서 귀환 중", + "ru": "Не удалось выполнить полет по оптимальному маршруту возврата на базу. Дрон возвращается на заданную высоту", + "tr": "Optimum BND rotasında uçulamıyor. Hava aracı önceden ayarlanan irtifaya dönüyor", + "zh": "智能返航失效,将执行设定高度返航" + }, + "fpv_tip_0x1B030012": { + "de": "Fluggerät beschleunigt. Akku entlädt sich schneller", + "en": "Aircraft accelerating. Battery draining faster", + "es": "Aeronave acelerando. La batería se está agotando más rápido.", + "fr": "Appareil en cours d'accélération. La batterie se décharge plus vite", + "ja": "機体が加速中。バッテリーの消耗が早くなります", + "ko": "기체 가속 중. 배터리 소모 속도 증가 중", + "ru": "Дрон разгоняется. АКБ разряжается быстрее", + "tr": "Hava aracı hızlanıyor. Pil daha hızlı tükeniyor", + "zh": "返航加速中,电量消耗加速" + }, + "fpv_tip_0x1B030013": { + "de": "Umgekehrte Steuerknüppelbewegung erkannt. Rückkehrfunktion (RTH) beendet", + "en": "RTH stopped. Control stick moved opposite to flight direction", + "es": "Se ha detectado el movimiento inverso de la palanca de control. Se ha salido del RPO", + "fr": "Joystick en mouvement détecté en sens inverse. RTH quitté", + "ja": "逆方向への操作スティックの動きを検出しました。RTHを終了しました", + "ko": "조종 스틱 역방향 움직임이 감지되었습니다. RTH 종료됨", + "ru": "Обнаружено перемещение ручки управления в обратном направлении. Выполнен выход из режима возврата домой", + "tr": "Kontrol çubuğunun ters hareketi algılandı. RTH'den çıkıldı", + "zh": "返航过程中用户反向打杆,退出返航。" + }, + "fpv_tip_0x1B030014": { + "ar": "", + "de": "", + "en": "Battery level low. Return to home promptly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "电量不足请尽快返航", + "zh-Hant": "" + }, + "fpv_tip_0x1B030015": { + "de": "Startpunkt in der Höhenlagezone. Das Fluggerät kehrt in niedrigerer Höhe zurück", + "en": "Home Point in Altitude Zone. Aircraft will return at lower altitude", + "es": "Punto de origen en la zona de altitud. Las aeronaves regresarán a menor altitud", + "fr": "Point de départ dans une zone à altitude limitée. L’appareil reviendra à une altitude inférieure", + "ja": "高度制限区域のホームポイント。機体は高度を下げて帰還します", + "ko": "고도 제한 구역 내에 홈포인트. 기체가 더 낮은 고도에서 돌아갑니다", + "ru": "Домашняя точка в зоне ограничения высоты полета. Дрон вернется на меньшей высоте", + "tr": "Başlangıç Noktası İrtifa Bölgesinde. Hava aracı daha düşük irtifada dönecek", + "zh": "返航点在限高区内,将降低返航高度" + }, + "fpv_tip_0x1B030016": { + "de": "Komplexes Umfeld. Rückkehrfunktion (RTH) angehalten. Fluggerät von Hand zurückfliegen", + "en": "Complex environment. RTH stopped. Manually control aircraft to return to home", + "es": "Entorno complejo. RPO detenido. Controle la aeronave manualmente para regresar al punto de origen", + "fr": "Environnement complexe. RTH arrêté. Contrôlez manuellement l'appareil pour la fonction Return-to-Home", + "ja": "環境が複雑です。RTHが停止しました。手動で機体を操作して帰還させてください", + "ko": "환경이 복잡합니다. RTH 중단됨. 기체를 수동으로 조종해 RTH를 수행하세요", + "ru": "Сложная среда. Возврат домой остановлен. Вручную управляйте дроном, чтобы вернуться домой", + "tr": "Karmaşık ortam. RTH durduruldu. Başlangıç noktasına dönmek için hava aracını manuel olarak kontrol edin", + "zh": "环境复杂,返航中断,请手动返航。" + }, + "fpv_tip_0x1B030017": { + "de": "Akku schwach. Fluggerät muss möglicherweise zwangslanden. Vorher nach einem geeigneten Landeplatz Ausschau halten", + "en": "Low battery. Aircraft may be forced to land. Find appropriate place to land in advance", + "es": "Batería baja. La aeronave puede verse obligada a aterrizar. Encuentre el lugar apropiado para aterrizar con anticipación", + "fr": "Batterie faible. L'appareil pourra être forcé d'atterrir. Trouvez un endroit approprié pour atterrir à l'avance", + "ja": "ローバッテリー。機体が強制着陸する可能性があります。事前に適切な着陸場所を見つけてください", + "ko": "배터리 부족. 기체를 강제 착륙시킬 수 있습니다. 먼저 적절한 착륙 장소를 찾으세요", + "ru": "Низкий заряд аккумулятора. Дрон может быть вынужден приземлиться. Найдите подходящее место для посадки заранее", + "tr": "Düşük pil. Hava aracı inişte zorlanabilir. Önce inmek için uygun yeri bulun", + "zh": "返航过程中估计的电量无法成功返航,可能提前低电量降落" + }, + "fpv_tip_0x1B030018": { + "de": "Max. Flughöhenlimit zu niedrig. Flugsicherheit beim Ausführen der Rückkehrfunktion (RTH) beeinträchtigt", + "en": "Max flight altitude limit too low. Flight safety during RTH affected", + "es": "Límite de altitud máxima de vuelo demasiado bajo. Seguridad de vuelo durante RPO afectada", + "fr": "Limite d'altitude en vol max trop basse. Sécurité en vol pendant le RTH affectée", + "ja": "飛行高度の上限値が低すぎます。RTH中の飛行安全性に影響します", + "ko": "최고 비행 고도 한도가 너무 낮습니다. RTH 중 비행 안전에 영향을 미칩니다", + "ru": "Ограничение по максимальной высоте слишком низкое. Это может повлиять на безопасность полета во время возврата домой", + "tr": "Maksimum uçuş irtifası sınırı çok düşük. RHT esnasında uçuş güvenliği etkilendi", + "zh": "限高过低影响返航飞行安全" + }, + "fpv_tip_0x1B030019": { + "de": "Fluggerät fliegt nicht entlang der Route. Sichere Rückkehrfunktion beendet.", + "en": "Aircraft not flying along route. Safe RTH exited", + "es": "Aeronave que no vuela por la ruta. Salió de RPO seguro", + "fr": "L’appareil ne suit pas la trajectoire. RTH sécurisé quitté", + "ja": "機体はルートに沿って飛行していません。セーフRTHが終了しました", + "ko": "기체가 경로를 따라 비행하지 않음. 안전한 RTH가 종료되었습니다.", + "ru": "Дрон не летит по маршруту. Функция безопасного возврата домой отключена", + "tr": "Hava aracı rota üzerinde uçmuyor. Güvenli BND'den çıkıldı", + "zh": "飞行器已偏离航线,航线安全返航失效" + }, + "fpv_tip_0x1B030C01": { + "zh": "" + }, + "fpv_tip_0x1B030C02": { + "de": "Schwaches GPS-Signal. RTH-Genauigkeit ist beeinträchtigt. Manuelle Rückkehr wird empfohlen", + "en": "GPS signal weak. RTH accuracy affected. Manual RTH recommended", + "es": "Señal GPS débil. Precisión de RPO afectada. Se recomienda RPO manual", + "fr": "Signal GPS faible. Précision du RTH affectée. RTH manuel recommandé", + "ja": "GPS信号 弱。RTHの精度に影響があります。手動でのRTHを推奨します", + "ko": "GPS 신호 약함. RTH 정확도 영향받음. 수동 RTH 권장", + "ru": "Слабый сигнал GPS снижает точность при возврате домой. Управляйте дроном вручную", + "tr": "GPS sinyali zayıf. Eve Dönüş kesinliği etkilendi. Manuel olarak eve dönüş önerilmekte", + "zh": "GPS信号弱,自动返航精度低,建议切换至手动返航" + }, + "fpv_tip_0x1B040001": { + "de": "KI-Stellenüberprüfung mit aktueller Nutzlast nicht verfügbar", + "en": "Focused shooting unavailable with current payload", + "es": "Focalización por inteligencia artificial no disponible con el instrumento actual", + "fr": "AI Spot-Check indisponible avec la charge utile actuelle", + "ja": "現在のペイロードではAIスポット確認ができません", + "ko": "이 페이로드는 \\'AI 현장 확인\\' 사용 불가", + "ru": "Фокусировка недоступна при съемке с данным оборудованием", + "tr": "Yapay Zeka Nokta Kontrolü mevcut yük ile kullanılamıyor", + "zh": "当前负载不支持精准拍照" + }, + "fpv_tip_0x1B040002": { + "de": "KI-Stellenüberprüfung fehlgeschlagen . Zur normalen Aufnahme gewechselt", + "en": "Focused shooting failed . Switched to normal shooting mode", + "es": "Error de Focalización por inteligencia artificial. Cambiado al modo de captura Normal", + "fr": "AI Spot-Check échoué . Passage au mode de prise de vue normal", + "ja": "AIスポットチェックに失敗しました。ノーマル撮影モードに切り替えます", + "ko": "\\'AI 현장 확인\\' 실패 . 일반 촬영 모드로 전환됨", + "ru": "Сбой съемки с фокусировкой . Включен обычный режим", + "tr": "Yapay Zeka Nokta Kontrolü başarısız. Normal çekim moduna geçti", + "zh": "精准拍照失败,执行普通拍照" + }, + "fpv_tip_0x1B040003": { + "de": "KI-Stellenüberprüfung fehlgeschlagen. Zum normalen Aufnahmemodus gewechselt", + "en": "AI Spot-Check failed. Switched to normal shooting mode", + "es": "Error de Focalización por inteligencia artificial. Cambiado al modo de captura Normal", + "fr": "Échec d'AI spot-check. Mode de prise de vue normal activé", + "ja": "AIスポットチェックに失敗しました。ノーマル撮影モードに切り替えます", + "ko": "AI 현장 확인 실패. 일반 촬영 모드로 전환됨", + "ru": "Не удалось выполнить выборочную проверку с помощью ИИ. Переключено на обычный режим съемки", + "tr": "Yapay Zeka Nokta Kontrolü başarısız. Normal çekim moduna geçti", + "zh": "精准复拍失败,执行普通拍照" + }, + "fpv_tip_0x1B040004": { + "de": "Kamera nicht befestigt. KI-Stellenüberprüfung fehlgeschlagen", + "en": "Camera not mounted. Focused shooting failed", + "es": "La cámara no está montada. Error de Focalización por inteligencia artificial", + "fr": "Caméra non installée. AI Spot-Check échoué", + "ja": "カメラが搭載されていません。AIスポットチェックに失敗しました", + "ko": "카메라 장착 안 됨. \\'AI 현장 확인\\' 실패", + "ru": "Камера не установлена. Сбой съемки с фокусировкой", + "tr": "Kamera monte edilmemiş. Yapay Zeka Nokta Kontrolü başarısız", + "zh": "未挂载相机,精准拍照失败" + }, + "fpv_tip_0x1B040401": { + "de": "Zeitüberschreitung beim Kamerazoom. KI-Stellenüberprüfung fehlgeschlagen. Später erneut versuchen", + "en": "Camera zoom timed out. AI Spot-Check failed. Try again later", + "es": "Se ha agotado el tiempo de zoom de la cámara. Ha fallado la focalización por IA (AI Spot-Check). Inténtelo de nuevo más tarde", + "fr": "Expiration du dézoom de la caméra. Échec de l'AI Spot-Check. Réessayez plus tard", + "ja": "カメラのズームがタイムアウトしました。AIスポット点検に失敗しました。後で再試行してください", + "ko": "카메라 줌 시간 초과. AI 현장 확인 실패. 나중에 다시 시도하세요", + "ru": "Время ожидания регулировки зума камеры истекло. Ошибка выборочной проверки с помощью ИИ. Повторите попытку позже", + "tr": "Kamera yakınlaştırma süresi doldu. Yapay Zeka Nokta Kontrolü başarısız. Daha sonra tekrar deneyin", + "zh": "相机变焦超时,精准复拍失败,请稍后重试" + }, + "fpv_tip_0x1B040402": { + "de": "Wechsel des Aufnahmemodus fehlgeschlagen. KI-Stellenüberprüfung fehlgeschlagen. Später erneut versuchen", + "en": "Switching shooting modes failed. AI Spot-Check failed. Try again later", + "es": "Ha fallado el cambio de modo de captura. Ha fallado la focalización por IA (AI Spot-Check). Inténtelo de nuevo más tarde", + "fr": "Échec du changement de mode de prise de vue. Échec de l'AI Spot-Check. Réessayez plus tard", + "ja": "撮影モードの切り替えに失敗しました。AIスポット点検に失敗しました。後で再試行してください", + "ko": "촬영 모드 전환 실패. AI 현장 확인 실패. 나중에 다시 시도하세요", + "ru": "Сбой переключения режимов съемки. Ошибка выборочной проверки с помощью ИИ. Повторите попытку позже", + "tr": "Çekim modları değiştirme başarısız. Yapay Zeka Nokta Kontrolü başarısız. Daha sonra tekrar deneyin", + "zh": "切换相机拍照模式失败,精准复拍失败,请稍后重试" + }, + "fpv_tip_0x1B040403": { + "de": "Zeitüberschreitung beim Kamerazoom. KI-Stellenüberprüfung fehlgeschlagen. Später erneut versuchen", + "en": "Camera zoom timed out. AI Spot-Check failed. Try again later", + "es": "Se ha agotado el tiempo de zoom de la cámara. Ha fallado la focalización por IA (AI Spot-Check). Inténtelo de nuevo más tarde", + "fr": "Expiration du dézoom de la caméra. Échec de l'AI Spot-Check. Réessayez plus tard", + "ja": "カメラのズームがタイムアウトしました。AIスポット点検に失敗しました。後で再試行してください", + "ko": "카메라 줌 시간 초과. AI 현장 확인 실패. 나중에 다시 시도하세요", + "ru": "Время ожидания регулировки зума камеры истекло. Ошибка выборочной проверки с помощью ИИ. Повторите попытку позже", + "tr": "Kamera yakınlaştırma süresi doldu. Yapay Zeka Nokta Kontrolü başarısız. Daha sonra tekrar deneyin", + "zh": "相机变焦超时,精准复拍失败,请稍后重试" + }, + "fpv_tip_0x1B040801": { + "de": "Beispiel für KI-Stellenüberprüfung kann nicht aufgefunden werden. Flugroute erneut hochladen", + "en": "Unable to locate focused shooting sample. Reupload flight route", + "es": "No se puede localizar la muestra de Focalización por inteligencia artificial. Vuelve a cargar la ruta de vuelo", + "fr": "Impossible de localiser l\\'échantillon AI Spot-Check. Transférez-le à nouveau", + "ja": "AIスポットチェックサンプルが見つかりません。飛行ルートを再アップロードしてください", + "ko": "\\'AI 현장 확인\\' 샘플 위치 찾을 수 없음. 비행경로 다시 업로드해야 함", + "ru": "Невозможно найти образец съемки с фокусировкой. Перезагрузите маршрут полета", + "tr": "Yapay Zeka Nokta Kontrolü örneğini konumlandıramıyor. Uçuş rotasını yeniden yükle", + "zh": "精准拍照示意图未找到,请重新上传航线" + }, + "fpv_tip_0x1B040802": { + "de": "Fehler: Zielmarkierung neu einstellen", + "en": "Target box parameter error. Readjust target box", + "es": "Error de parámetros del cuadro de objetivo. Vuelve a ajustarlo", + "fr": "Erreur de réglage du cadre du sujet. Réajustez-le", + "ja": "被写体ボックス パラメーター エラー。被写体ボックスを再調整してください", + "ko": "피사체 박스 매개변수 오류. 피사체 박스 재조정 필요", + "ru": "Ошибка параметров рамки. Измените ее размеры", + "tr": "Hedef kutu parametre hatası. Hedef kutusunu tekrar ayarlayın", + "zh": "目标框参数错误,请调整目标框" + }, + "fpv_tip_0x1B041001": { + "de": "Gimbalfehler. KI-Stellenüberprüfung fehlgeschlagen. Nutzlast neu installieren", + "en": "Gimbal error. Focused shooting failed. Reinstall payload", + "es": "Error del estabilizador. Error de Focalización por inteligencia artificial. Vuelve a instalar el instrumento", + "fr": "Erreur nacelle. AI Spot-Check échouée. Réinstallez la charge utile", + "ja": "ジンバルエラー。AIスポットチェックに失敗しました。ペイロードを再度取り付けてください", + "ko": "짐벌 오류. \\'AI 현장 확인\\' 실패. 페이로드 재설치 필요", + "ru": "Ошибка стабилизатора. Сбой съемки с фокусировкой. Переустановите оборудование", + "tr": "Gimbal hatası. Yapay Zeka Nokta Kontrolü başarısız. Yükü tekrar takın", + "zh": "云台异常,精准拍照失败,请重新拔插负载" + }, + "fpv_tip_0x1B060001": { + "de": "Fluggeschwindigkeit beschränkt. Firmware-Aktualisierung erforderlich", + "en": "Flight speed limited. Firmware update required", + "es": "Velocidad de vuelo limitada. Es necesario actualizar el firmware.", + "fr": "Vitesse de vol limitée. Mise à jour du firmware requise", + "ja": "飛行速度に制限あり。ファームウェア更新が必要です", + "ko": "비행 속도 제한됨. 펌웨어 업데이트 필요", + "ru": "Скорость полета ограничена. Требуется обновить прошивку", + "tr": "Uçuş hızı sınırlı. Ürün yazılımı güncellemesi gerekiyor", + "zh": "飞行速度受限,固件需要升级" + }, + "fpv_tip_0x1B070001": { + "ar": "", + "de": "", + "en": "Payload exceeds capacity. Reduce payload or adjust flight plan", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货物超重,请减少货物或修改飞行计划", + "zh-Hant": "" + }, + "fpv_tip_0x1B070001_in_the_sky": { + "ar": "", + "de": "", + "en": "Payload exceeds capacity. Land promptly and reduce payload", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货物超重,请尽快降落,减少货物", + "zh-Hant": "" + }, + "fpv_tip_0x1B070002": { + "ar": "", + "de": "", + "en": "Payload weight not evenly distributed. Adjust payload placement", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货物重心偏移,请重新摆放货物", + "zh-Hant": "" + }, + "fpv_tip_0x1B070002_in_the_sky": { + "ar": "", + "de": "", + "en": "Payload weight not evenly distributed. Land promptly and adjust payload placement", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货物重心偏移,请尽快降落,重新摆放货物", + "zh-Hant": "" + }, + "fpv_tip_0x1B070003": { + "ar": "", + "de": "", + "en": "Cargo case weight sensor error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货箱称重传感器异常", + "zh-Hant": "" + }, + "fpv_tip_0x1B070004": { + "ar": "", + "de": "", + "en": "Weight sensor error. Calibrate cargo case weight sensor", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "称重异常,请重新校准货箱称重传感器", + "zh-Hant": "" + }, + "fpv_tip_0x1B070005": { + "ar": "", + "de": "", + "en": "Weight sensor error. Calibrate cargo case weight sensor", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "称重异常,请重新校准货箱称重传感器", + "zh-Hant": "" + }, + "fpv_tip_0x1B070006": { + "ar": "", + "de": "", + "en": "Payload exceeds capacity. Reduce payload or adjust flight plan", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货物超重,请减少货物或修改飞行计划", + "zh-Hant": "" + }, + "fpv_tip_0x1B070006_in_the_sky": { + "ar": "", + "de": "", + "en": "Payload exceeds capacity. Land promptly and reduce payload", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货物超重,请尽快降落,减少货物", + "zh-Hant": "" + }, + "fpv_tip_0x1B070008": { + "ar": "", + "de": "", + "en": "Winch system weight sensor error", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊称重传感器异常", + "zh-Hant": "" + }, + "fpv_tip_0x1B070009": { + "ar": "", + "de": "", + "en": "Weight sensor error. Calibrate winch system weight sensor", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "称重异常,请重新校准空吊称重传感器", + "zh-Hant": "" + }, + "fpv_tip_0x1B07000A": { + "ar": "", + "de": "", + "en": "Weight sensor error. Calibrate winch system weight sensor", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "称重异常,请重新校准空吊称重传感器", + "zh-Hant": "" + }, + "fpv_tip_0x1B07000B": { + "ar": "", + "de": "", + "en": "Swing angle too large. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊摆角过大,请谨慎飞行", + "zh-Hant": "" + }, + "fpv_tip_0x1B07000C": { + "ar": "", + "de": "", + "en": "Cable broke. Check payload on winch system", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊绳索断裂,请检查吊挂货物", + "zh-Hant": "" + }, + "fpv_tip_0x1B07000D": { + "ar": "", + "de": "", + "en": "Winch system motor stalled. Check payload on winch system", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电机堵转,请检查吊挂货物", + "zh-Hant": "" + }, + "fpv_tip_0x1B07000E": { + "ar": "", + "de": "", + "en": "Winch system motor overheated. Check if payload exceeds capacity", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊电机温度过高,请检查货物是否超重", + "zh-Hant": "" + }, + "fpv_tip_0x1B080001": { + "ar": "", + "de": "", + "en": "Remote ID broadcast error. Failed to obtain remote controller location", + "es": "", + "fr": "", + "it": "", + "ja": "", + "ko": "", + "pt": "", + "ru": "", + "tr": "", + "zh": "Remote ID 播报异常,无法获取遥控器位置" + }, + "fpv_tip_0x1B080002": { + "ar": "", + "de": "", + "en": "Remote ID module error. Contact DJI Support", + "es": "", + "fr": "", + "it": "", + "ja": "", + "ko": "", + "pt": "", + "ru": "", + "tr": "", + "zh": "Remote ID 模块异常,请联系售后服务" + }, + "fpv_tip_0x1B090001": { + "de": "Zielerfassung gestoppt", + "en": "Target tracking stopped", + "es": "Smart Track detenido", + "fr": "Smart Track interrompu", + "ja": "スマートトラック停止", + "ko": "스마트 트랙 중지됨", + "ru": "Интеллектуальное следование остановлено", + "tr": "Akıllı Takip durdu", + "zh": "停止目标追踪" + }, + "fpv_tip_0x1B090002": { + "de": "Zielverfolgung gestoppt", + "en": "Target tracking stopped", + "es": "Seguimiento del objetivo detenido", + "fr": "Suivi du sujet arrêté", + "ja": "被写体トラック停止", + "ko": "타겟 추적 중지됨", + "ru": "Следование за целью остановлено", + "tr": "Hedef takip durdu", + "zh": "停止智能跟随" + }, + "fpv_tip_0x1B090003": { + "de": "Zielverfolgung gestoppt", + "en": "Target tracking stopped", + "es": "Seguimiento del objetivo detenido", + "fr": "Suivi du sujet arrêté", + "ja": "被写体トラック停止", + "ko": "타겟 추적 중지됨", + "ru": "Следование за целью остановлено", + "tr": "Hedef takip durdu", + "zh": "停止智能跟随" + }, + "fpv_tip_0x1B092C01": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d\\'identification du sujet", + "ja": "被写体特定エラー", + "ko": "피사체 인식 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C02": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C03": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C04": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C05": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C06": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C07": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C08": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C09": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C0A": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C0B": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C0C": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C0D": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C0E": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C0F": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C10": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C11": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C12": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C13": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C14": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C15": { + "de": "Zielidentifikationsfehler", + "en": "Target identification error", + "es": "Error de identificación del objetivo", + "fr": "Erreur d'identification du sujet", + "ja": "被写体特定エラー", + "ko": "타겟 식별 오류", + "ru": "Ошибка определения цели", + "tr": "Hedef tanımlama hatası", + "zh": "目标识别异常" + }, + "fpv_tip_0x1B092C16": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C17": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C18": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C19": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C1A": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C1B": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C1C": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C1D": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C1E": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C1F": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C20": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Sicherstellen, dass ausgewähltes Ziel gültig ist", + "en": "Enabling Smart Track failed. Ensure selected target is valid", + "es": "Error al activar Smart Track. Asegúrate de que el objetivo seleccionado sea válido", + "fr": "Impossible d'activer Smart Track. Vérifiez que le sujet sélectionné est valide", + "ja": "スマートトラックを有効化できません 。選択した被写体が有効であるか確認してください", + "ko": "스마트 트랙 활성화 실패. 선택된 타겟이 유효한지 확인하세요", + "ru": "Не удалось включить интеллектуальное следование. Выберите подходящую цель", + "tr": "Akıllı Takip etkinleştirme başarısız. Geçerli bir hedef seçtiğinizden emin olun", + "zh": "智能追踪功能启动失败,请确保框选有效目标" + }, + "fpv_tip_0x1B092C21": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C22": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Zielauswahl verkleinern", + "en": "Enabling Smart Track failed. Reduce selected area", + "es": "Error al activar Smart Track. Reduce la zona seleccionada", + "fr": "Impossible d'activer Smart Track. Réduisez la zone de sélection", + "ja": "スマートトラックを有効化できません。選択エリアを小さくしてください", + "ko": "스마트 트랙 활성화 실패. 선택된 영역을 줄이세요", + "ru": "Не удалось включить интеллектуальное следование. Выберите участок меньшего размера", + "tr": "Akıllı Takip etkinleştirme başarısız. Seçilen alanı azaltın", + "zh": "智能追踪功能启动失败,请缩小目标区域" + }, + "fpv_tip_0x1B092C23": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Zielauswahl vergrößern", + "en": "Enabling Smart Track failed. Increase selected area", + "es": "Error al activar Smart Track. Aumenta la zona seleccionada", + "fr": "Impossible d'activer Smart Track. Augmentez la zone de sélection", + "ja": "スマートトラックを有効化できません。選択エリアを大きくしてください", + "ko": "스마트 트랙 활성화 실패. 선택된 영역을 늘리세요", + "ru": "Не удалось включить интеллектуальное следование. Выберите участок большего размера", + "tr": "Akıllı Takip etkinleştirme başarısız. Seçilen alanı arttırın", + "zh": "智能追踪功能启动失败,请扩大目标区域" + }, + "fpv_tip_0x1B092C24": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Sicherstellen, dass ausgewähltes Ziel gültig ist", + "en": "Enabling Smart Track failed. Ensure selected target is valid", + "es": "Error al activar Smart Track. Asegúrate de que el objetivo seleccionado sea válido", + "fr": "Impossible d'activer Smart Track. Assurez-vous que le sujet sélectionné est valide", + "ja": "スマートトラックを有効化できません。選択した被写体が有効であることを確認してください", + "ko": "스마트 트랙 활성화 실패. 선택된 타겟이 유효한지 확인하세요", + "ru": "Не удалось включить интеллектуальное следование. Выберите подходящую цель", + "tr": "Akıllı Takip etkinleştirme başarısız. Geçerli bir hedef seçtiğinizden emin olun", + "zh": "智能跟踪功能启动失败,请确保框选有效目标" + }, + "fpv_tip_0x1B092C25": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B092C26": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093001": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093002": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093003": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093004": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093005": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093006": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093007": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093008": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093009": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Zielauswahl vergrößern", + "en": "Enabling Smart Track failed. Increase selected area", + "es": "Error al activar Smart Track. Aumenta la zona seleccionada", + "fr": "Impossible d'activer Smart Track. Augmentez la zone sélectionnée", + "ja": "スマートトラックを有効化できません。選択範囲を拡大してください", + "ko": "스마트 트랙 활성화 실패. 선택된 영역을 늘리세요", + "ru": "Не удалось включить интеллектуальное следование. Выберите участок большего размера", + "tr": "Akıllı Takip etkinleştirme başarısız. Seçilen alanı arttırın", + "zh": "智能跟踪功能启动失败,请扩大目标区域" + }, + "fpv_tip_0x1B09300A": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Sicherstellen, dass ausgewähltes Ziel gültig ist", + "en": "Enabling Smart Track failed. Ensure selected target is valid", + "es": "Error al activar Smart Track. Asegúrate de que el objetivo seleccionado sea válido", + "fr": "Impossible d'activer Smart Track. Assurez-vous que le sujet sélectionné est valide", + "ja": "スマートトラックを有効化できません。選択した被写体が有効であることを確認してください", + "ko": "스마트 트랙 활성화 실패. 선택된 타겟이 유효한지 확인하세요", + "ru": "Не удалось включить интеллектуальное следование. Выберите подходящую цель", + "tr": "Akıllı Takip etkinleştirme başarısız. Geçerli bir hedef seçtiğinizden emin olun", + "zh": "智能跟踪功能启动失败,请确保框选有效目标" + }, + "fpv_tip_0x1B09300B": { + "de": "Ziel verloren. Smarte Verfolgung gestoppt", + "en": "Target lost. Exited Target Acquisition", + "es": "Se ha perdido el objetivo. Smart Track detenido", + "fr": "Sujet perdu. Smart Track interrompu", + "ja": "ターゲットを見失いました。スマートトラック停止", + "ko": "타겟 사라짐. 스마트 트랙 중지됨", + "ru": "Цель потеряна. Интеллектуальное следование остановлено", + "tr": "Hedef kayıp. Akıllı Takip durdu", + "zh": "目标已丢失,目标锁定功能已退出" + }, + "fpv_tip_0x1B09300C": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B09300D": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B09300E": { + "de": "Parameter der Kamera geändert. Smarte Verfolgung gestoppt", + "en": "Camera parameters changed. Exited Target Acquisition", + "es": "Parámetros de la cámara modificados. Smart Track detenido", + "fr": "Paramètres de caméra modifiés. Smart Track interrompu", + "ja": "カメラパラメーターを変更。スマートトラック停止", + "ko": "카메라 매개변수 변경됨. 스마트 트랙 중지됨", + "ru": "Параметры камеры изменены. Интеллектуальное следование остановлено", + "tr": "Kamera parametreleri değişti. Akıllı Takip durdu", + "zh": "相机参数被修改,目标锁定功能退出" + }, + "fpv_tip_0x1B09300F": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093010": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093011": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093012": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093013": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093014": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093015": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093016": { + "de": "Ziel verloren. Smarte Verfolgung beendet", + "en": "Target lost. Exited Smart Track", + "es": "Se ha perdido el objetivo. Smart Track se ha desactivado", + "fr": "Sujet perdu. Fin de Smart Track", + "ja": "被写体を見失いました。スマートトラックを終了します", + "ko": "타겟 사라짐. 스마트 트랙 종료됨", + "ru": "Цель потеряна. Режим интеллектуального следования закрыт", + "tr": "Hedef kayıp. Akıllı Takipten çıkıldı", + "zh": "目标已丢失,智能跟踪功能已退出" + }, + "fpv_tip_0x1B093017": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B093018": { + "de": "Ziel zu weit entfernt. Smarte Verfolgung gestoppt", + "en": "Target too far away. Exited Target Acquisition", + "es": "Objetivo demasiado lejos. Smart Track detenido", + "fr": "Sujet trop éloigné. Smart Track interrompu", + "ja": "被写体が遠すぎます。スマートトラック停止", + "ko": "타겟이 너무 멀리 있음. 스마트 트랙 중지됨", + "ru": "Цель слишком далеко. Интеллектуальное следование остановлено", + "tr": "Hedef çok uzak. Akıllı Takip durdu", + "zh": "目标距离过远,目标锁定功能已退出" + }, + "fpv_tip_0x1B093019": { + "de": "Parameter der Kamera geändert. Smarte Verfolgung beendet", + "en": "Camera parameters changed. Exited Smart Track", + "es": "Parámetros de la cámara modificados. Smart Track se ha desactivado", + "fr": "Les paramètres de la caméra ont changé. Fin de Smart Track", + "ja": "カメラパラメーターが変更されました。スマートトラックを終了します", + "ko": "카메라 매개변수 변경됨. 스마트 트랙 종료됨", + "ru": "Параметры камеры изменены. Режим интеллектуального следования закрыт", + "tr": "Kamera parametreleri değişti. Akıllı Takipten çıkıldı", + "zh": "相机参数被修改,智能跟踪功能退出" + }, + "fpv_tip_0x1B09301A": { + "de": "Aktivierung von smarter Verfolgung fehlgeschlagen. Bitte erneut versuchen", + "en": "Enabling Smart Track failed. Check and try again", + "es": "Error al activar Smart Track. Comprueba y vuelve a intentarlo", + "fr": "Impossible d'activer Smart Track. Vérifiez et refaites une tentative", + "ja": "スマートトラックを有効化できません。確認して再試行してください", + "ko": "스마트 트랙 활성화 실패. 확인 후 다시 시도하세요", + "ru": "Не удалось включить интеллектуальное следование. Проверьте и повторите попытку", + "tr": "Akıllı Takip etkinleştirme başarısız. Kontrol edin ve tekrar deneyin", + "zh": "智能跟踪功能启动失败,请重试" + }, + "fpv_tip_0x1B0A0001": { + "de": "GPS-Signal schwach. Geo-Awareness-Funktion beeinträchtigt. Mit Vorsicht fliegen.", + "en": "GPS signal weak. Geo-awareness function degraded. Fly with caution", + "es": "Señal GPS débil. Función de reconocimiento geográfico deteriorada. Vuela con cuidado", + "fr": "Signal GPS faible. Fonction de géovigilance dégradée. Pilotez avec précaution.", + "ja": "GPS信号が微弱です。ジオアウェアネス機能が低下しています。慎重に飛行してください", + "ko": "GPS 신호가 약함. 지리 인식 기능 저하됨. 비행 시 주의 필요.", + "ru": "Слабый сигнал GPS. Функция гео-осведомленности ухудшилась. Будьте осторожны в полете", + "tr": "GPS sinyali zayıf. Coğrafi farkındalık işlevi bozuldu. Dikkatlice uçurun", + "zh": "GPS 信号弱,地理感知功能降级,请谨慎飞行" + }, + "fpv_tip_0x1B0A0002": { + "de": "Laden der dynamischen Sicherheitsdatenbank fehlgeschlagen. Geo-Awareness-Funktion beeinträchtigt", + "en": "Loading dynamic safety database failed. Geo-awareness function degraded", + "es": "Error al cargar la base de datos de seguridad dinámica. Función de reconocimiento geográfico deteriorada", + "fr": "Échec du chargement de la base de données de sécurité dynamique. Fonction de géovigilance dégradée", + "ja": "動的安全性データベースのロードが失敗しました。ジオアウェアネス機能が低下しています", + "ko": "동적 안전 데이터베이스 로드 실패. 지리 인식 기능 저하됨", + "ru": "Не удалось загрузить динамическую базу данных безопасности. Функция гео-осведомленности ухудшилась", + "tr": "Dinamik güvenlik veritabanı güncellenemedi. Coğrafi farkındalık işlevi bozuldu", + "zh": "动态安全数据加载失败,地理感知功能降级" + }, + "fpv_tip_0x1B0A0003": { + "de": "Dynamische Sicherheitsdaten konnten nicht abgefragt werden. Geo-Awareness-Funktion beeinträchtigt", + "en": "Failed to query dynamic safety data. Geo-awareness function degraded", + "es": "Error al consultar los datos de seguridad dinámicos. Función de reconocimiento geográfico deteriorada", + "fr": "Échec de la requête des données de sécurité dynamiques. Fonction de géovigilance dégradée", + "ja": "動的安全性データを照会できません。ジオアウェアネス機能が低下しています", + "ko": "쿼리 동적 안전 데이터를 로드하지 못함. 지리 인식 기능 저하됨", + "ru": "Не удалось запросить динамические данные безопасности. Функция гео-осведомленности ухудшилась", + "tr": "Dinamik güvenlik verileri sorgulanamadı. Coğrafi farkındalık işlevi bozuldu", + "zh": "动态安全数据查询失败,地理感知功能降级" + }, + "fpv_tip_0x1B0A0004": { + "de": "FlySafe-Datendichte ist in der aktuellen Region hoch. Fluggerät kann Daten möglicherweise nicht vollständig verarbeiten. Es wird empfohlen, die FlySafe-Datenbank zu aktualisieren.", + "en": "FlySafe data density high in current region. Aircraft may not be able to fully process data. It is recommended to update FlySafe database", + "es": "Densidad de datos de VuelaSeguro alta en la región actual. Es posible que la aeronave no pueda procesar completamente los datos. Se recomienda actualizar la información de VuelaSeguro", + "fr": "Densité élevée des données FlySafe dans la région actuelle. L'appareil peut ne pas être en mesure de traiter complètement les données. Il est recommandé de mettre à jour la base de données FlySafe", + "ja": "現在の地域の安全飛行データ密度が高くなっています。機体がデータを完全に処理できない可能性があります。安全飛行データベースを更新することをお勧めします", + "ko": "현재 지역에서 FlySafe 데이터 밀도가 높습니다. 기체가 데이터를 완전히 처리하지 못할 수 있습니다. FlySafe 데이터베이스를 업데이트하는 것이 좋습니다.", + "ru": "Высокая плотность данных FlySafe в текущем регионе. Дрон может быть не в состоянии полностью обработать данные. Рекомендуется обновить базу данных FlySafe", + "tr": "Mevcut bölgede FlySafe veri yoğunluğu yüksek. Hava aracı, verileri tam olarak işleyemeyebilir. FlySafe veri tabanının güncellenmesi önerilir", + "zh": "限飞数据库在当前区域数据密度较高,可能会出现飞行器解析不完整的情况,建议更新飞行安全数据库。" + }, + "fpv_tip_0x1B100000": { + "de": "Ziel verloren. Tracking gestoppt", + "en": "Target lost. Tracking stopped", + "es": "Se ha perdido el objetivo. Seguimiento detenido", + "fr": "Sujet perdu. Suivi arrêté", + "ja": "ターゲットロストです。トラッキングが停止しました", + "ko": "타겟 사라짐. 트래킹 중지됨", + "ru": "Цель потеряна. Отслеживание остановлено", + "tr": "Hedef kayboldu. Takip durdu", + "zh": "目标丢失,跟踪停止" + }, + "fpv_tip_0x1B100001": { + "de": "Das Ziel ist zu klein. Leicht zu verlieren", + "en": "Target too small. Easy to lose", + "es": "Objetivo demasiado pequeño. Fácil de perder", + "fr": "Cible trop petite. Facile à perdre", + "ja": "被写体が小さすぎます。見失いやすくなっています", + "ko": "타겟이 너무 작습니다. 쉽게 분실될 수 있습니다", + "ru": "Слишком маленькая цель. Легко потерять", + "tr": "Hedef çok küçük. Kolayca kaybolabilir", + "zh": "目标较小,容易丢失" + }, + "fpv_tip_0x1B300001": { + "ar": "", + "de": "", + "en": "Unable to obtain cargo case data. Make sure cargo case is installed properly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "无法获得货箱数据,请检查安装情况", + "zh-Hant": "" + }, + "fpv_tip_0x1B300002": { + "ar": "", + "de": "", + "en": "Winch system communication error. Check winch system connection", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "空吊设备通信异常,请检查设备连接状况", + "zh-Hant": "" + }, + "fpv_tip_0x1B300003": { + "ar": "", + "de": "", + "en": "Payload exceeds capacity. Reduce payload and adjust flight plan", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货物过重,请减少货物和修改飞行计划", + "zh-Hant": "" + }, + "fpv_tip_0x1B300004": { + "ar": "", + "de": "", + "en": "Payload exceeds capacity. Cancel flight", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货物超重,请终止飞行计划", + "zh-Hant": "" + }, + "fpv_tip_0x1B300005": { + "ar": "", + "de": "", + "en": "Payload weight not evenly distributed. Secure payload in center of cargo case", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货物偏离中心,请把货物摆放在货箱中心", + "zh-Hant": "" + }, + "fpv_tip_0x1B300006": { + "ar": "", + "de": "", + "en": "Cargo case severely imbalanced. Secure payload in center of cargo case", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货物严重偏离中心,请把货物摆放在货箱中心", + "zh-Hant": "" + }, + "fpv_tip_0x1B300007": { + "ar": "", + "de": "", + "en": "Cargo case wobbling. Secure cargo case and payload inside", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货箱晃动,请绑好货箱或固定货物在货箱中的位置", + "zh-Hant": "" + }, + "fpv_tip_0x1B300008": { + "ar": "", + "de": "", + "en": "Cargo case wobbles significantly. Secure cargo case and payload inside", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "货箱晃动严重,请绑好货箱或固定货物在货箱中的位置", + "zh-Hant": "" + }, + "fpv_tip_0x1B300009": { + "ar": "", + "de": "", + "en": "Payload on winch system exceeds capacity. Reduce payload and adjust flight plan", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "挂载货物过重,请减少货物和修改飞行计划", + "zh-Hant": "" + }, + "fpv_tip_0x1B30000A": { + "ar": "", + "de": "", + "en": "Payload on winch system exceeds capacity. Cancel flight", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "挂载货物超重,请终止飞行计划", + "zh-Hant": "" + }, + "fpv_tip_0x1B30000B": { + "ar": "", + "de": "", + "en": "Payload swings slightly. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "挂载货物小幅摆动,请注意飞行安全", + "zh-Hant": "" + }, + "fpv_tip_0x1B30000C": { + "ar": "", + "de": "", + "en": "Payload swings significantly. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "挂载货物大幅摆动,请注意飞行安全", + "zh-Hant": "" + }, + "fpv_tip_0x1B30000D": { + "ar": "", + "de": "", + "en": "Payload on winch system approaching obstacle. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "挂载货物接近障碍物,请注意飞行安全", + "zh-Hant": "" + }, + "fpv_tip_0x1B30000E": { + "ar": "", + "de": "", + "en": "Payload on winch system very close to obstacle. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "挂载货物非常接近障碍物,请注意飞行安全", + "zh-Hant": "" + }, + "fpv_tip_0x1B30000F": { + "en": "Extending or retracting winch cable is prohibited during flight. Make sure aircraft is hovering before extending or retracting winch cable", + "zh": "飞行过程中禁止收放空吊线缆,请悬停后再进行线缆收放" + }, + "fpv_tip_0x1B310001": { + "ar": "", + "de": "", + "en": "Battery level too low to complete flight mission. Adjust flight plan", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "当前电量不够完成航线任务,请更改飞行计划", + "zh-Hant": "" + }, + "fpv_tip_0x1B310001_in_the_sky": { + "ar": "", + "de": "", + "en": "Battery level too low to complete flight mission. Adjust flight plan", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "当前电量不够完成航线任务,请更改飞行计划", + "zh-Hant": "" + }, + "fpv_tip_0x1B310002": { + "ar": "", + "de": "", + "en": "Battery level too low to fly to alternate landing site. Land promptly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "当前电量不够前往备降点,请尽快降落", + "zh-Hant": "" + }, + "fpv_tip_0x1B310002_in_the_sky": { + "ar": "", + "de": "", + "en": "Battery level too low to fly to alternate landing site. Land promptly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "当前电量不够前往备降点,请尽快降落", + "zh-Hant": "" + }, + "fpv_tip_0x1B310003": { + "ar": "", + "de": "", + "en": "Current payload exceeds propulsion system capability limit. Motors may be overheated. Reduce payload weight before taking off", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "当前载重超过动力系统载重限制,可能导致电机超温,请降低载重后起飞", + "zh-Hant": "" + }, + "fpv_tip_0x1B310003_in_the_sky": { + "ar": "", + "de": "", + "en": "Current payload exceeds propulsion system capability limit. Motors may be overheated. Return to home or land promptly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "当前载重超过动力系统载重限制,可能导致电机超温,请尽快返航或降落", + "zh-Hant": "" + }, + "fpv_tip_0x1B310004": { + "ar": "", + "de": "", + "en": "Current payload exceeds battery capability limit. Battery may be damaged. Reduce payload weight before taking off", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "当前载重超过电池限制,可能导致电池损坏,请降低载重后起飞", + "zh-Hant": "" + }, + "fpv_tip_0x1B310004_in_the_sky": { + "ar": "", + "de": "", + "en": "Current payload exceeds battery capability limit. Battery may be damaged. Return to home or land promptly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "当前载重超过电池限制,可能导致电池损坏,请尽快返航或降落", + "zh-Hant": "" + }, + "fpv_tip_0x1B310005": { + "en": "Altitude detection function of radar module unavailable. Safe altitude changed. Fly with caution", + "zh": "雷达模块高度探测失效,安全飞行高度发生变更,请注意飞行安全" + }, + "fpv_tip_0x1B310006": { + "en": "Altitude detection function of radar module available. Safe altitude changed. Fly with caution", + "zh": "雷达模块高度探测恢复正常,安全飞行高度发生变更,请注意飞行安全" + }, + "fpv_tip_0x1B310007": { + "en": "Aircraft in area with terrain data. Fly under safe altitude", + "zh": "飞行器处于地形数据区域,请在安全飞行高度以下飞行" + }, + "fpv_tip_0x1B310007_in_the_sky": { + "en": "Aircraft entered area with terrain data. Safe altitude changed", + "zh": "飞行器进入地形数据区域,安全飞行高度发生变更" + }, + "fpv_tip_0x1B310008": { + "en": "Aircraft not in area with terrain data. Apply terrain data", + "zh": "飞行器不在地形数据区域,请应用地形数据" + }, + "fpv_tip_0x1B310008_in_the_sky": { + "en": "Aircraft out of area with terrain data. Safe altitude changed. Fly with caution", + "zh": "飞行器飞出地形数据区域,安全飞行高度发生变更,请注意飞行安全" + }, + "fpv_tip_0x1B310009": { + "en": "Aircraft flight altitude exceeded safe altitude. Fly aircraft under safe altitude", + "zh": "飞行器当前飞行高度超过安全飞行高度,请在安全飞行高度以下飞行" + }, + "fpv_tip_0x1BA10000": { + "ar": "", + "de": "", + "en": "Cruise control enabled", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "当前在杆量保持中", + "zh-Hant": "" + }, + "fpv_tip_0x1BA10001": { + "ar": "", + "de": "Fluggerät nicht im Flugbetrieb. Tempomat deaktiviert", + "en": "Aircraft not in flight. Cruise control disabled", + "es": "La aeronave no está en vuelo. Control de crucero desactivado", + "fr": "L'appareil n'est pas en vol. Régulateur de vitesse désactivé", + "id": "", + "it": "", + "ja": "機体が飛行していません。クルーズコントロールが無効", + "ko": "기체가 비행 상태가 아님. 크루즈 컨트롤 비활성화됨", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Дрон не находится в полете. Круиз-контроль отключен", + "th": "", + "tr": "Hava araç uçuşta değil. Hız sabitleyici devre dışı", + "ug": "", + "vi": "", + "zh": "飞机未起飞,无法进入杆量保持", + "zh-Hant": "" + }, + "fpv_tip_0x1BA10002": { + "ar": "", + "de": "Flugmodus wird gewechselt. Tempomat deaktiviert", + "en": "Switching flight modes. Cruise control disabled", + "es": "Cambiando modos de vuelo. Control de crucero desactivado", + "fr": "Changement de mode de vol. Régulateur de vitesse désactivé", + "id": "", + "it": "", + "ja": "フライトモードの切り替え中です。クルーズコントロールが無効", + "ko": "비행 모드 전환 중. 크루즈 컨트롤 비활성화됨", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Переключение режимов полета. Круиз-контроль отключен", + "th": "", + "tr": "Uçuş modları değiştiriliyor. Hız sabitleyici devre dışı", + "ug": "", + "vi": "", + "zh": "飞机模式改变,退出杆量保持", + "zh-Hant": "" + }, + "fpv_tip_0x1BA10003": { + "ar": "", + "de": "Fluggerät bremst. Tempomat deaktiviert", + "en": "Aircraft braking. Cruise control disabled", + "es": "Aeronave frenando. Control de crucero desactivado", + "fr": "Freinage de l'appareil. Régulateur de vitesse désactivé", + "id": "", + "it": "", + "ja": "機体がブレーキ中です。クルーズコントロールが無効", + "ko": "기체 제동. 크루즈 컨트롤 비활성화됨", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Дрон тормозит. Круиз-контроль отключен", + "th": "", + "tr": "Hava aracı fren yapıyor. Hız sabitleyici devre dışı", + "ug": "", + "vi": "", + "zh": "飞机正在刹停中,无法进入和退出杆量保持", + "zh-Hant": "" + }, + "fpv_tip_0x1BA10004": { + "ar": "", + "de": "Fluggeschwindigkeit beschränkt. Tempomat deaktiviert", + "en": "Flight speed limited. Cruise control disabled", + "es": "Velocidad de vuelo limitada. Control de crucero desactivado", + "fr": "Vitesse de vol limitée. Régulateur de vitesse désactivé", + "id": "", + "it": "", + "ja": "飛行速度が制限されています。クルーズコントロールが無効", + "ko": "비행 속도 제한됨. 크루즈 컨트롤 비활성화됨", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Скорость полета ограничена. Круиз-контроль отключен", + "th": "", + "tr": "Uçuş hızı sınırlı. Hız sabitleyici devre dışı", + "ug": "", + "vi": "", + "zh": "飞机被限速,退出杆量保持", + "zh-Hant": "" + }, + "fpv_tip_0x1BA10005": { + "ar": "", + "de": "Fluggerät nähert sich der festgelegten maximalen Flughöhe oder -distanz. Tempomat deaktiviert", + "en": "Aircraft approaching the set max flight altitude or distance. Cruise control disabled", + "es": "Aeronave aproximándose a la altitud o distancia máxima de vuelo establecida. Control de crucero desactivado", + "fr": "L'appareil s'approche de la distance ou de l'altitude en vol maximale définie. Régulateur de vitesse désactivé", + "id": "", + "it": "", + "ja": "設定した最大飛行高度または距離に機体が近づいています。クルーズコントロールが無効", + "ko": "기체가 설정된 최대 비행 고도 또는 거리에 접근하는 중. 크루즈 컨트롤 비활성화됨", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Дрон приближается к установленной максимальной высоте полета или расстоянию. Круиз-контроль отключен", + "th": "", + "tr": "Hava aracı ayarlanan maksimum uçuş yüksekliğine veya mesafesine yaklaşıyor. Hız sabitleyici devre dışı", + "ug": "", + "vi": "", + "zh": "飞机接近限飞区,无法进入和退出杆量保持", + "zh-Hant": "" + }, + "fpv_tip_0x1BA10006": { + "ar": "", + "de": "Tempomat im aktuellen Flugmodus nicht verfügbar. Tempomat deaktiviert", + "en": "Cruise control unavailable in current flight mode. Cruise control disabled", + "es": "El control de crucero no está disponible en el modo de vuelo actual. Control de crucero desactivado", + "fr": "Régulateur de vitesse non disponible avec le mode de vol actuel. Régulateur de vitesse désactivé", + "id": "", + "it": "", + "ja": "現在のフライトモードではクルーズコントロールを使用できません。クルーズコントロールが無効", + "ko": "현재 비행 모드에서 크루즈 컨트롤을 사용할 수 없습니다. 크루즈 컨트롤 비활성화됨", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Круиз-контроль недоступен в текущем режиме полета. Круиз-контроль отключен", + "th": "", + "tr": "Mevcut uçuş modunda hız sabitleyici kullanılamıyor. Hız sabitleyici devre dışı", + "ug": "", + "vi": "", + "zh": "当前模式,不支持杆量保持", + "zh-Hant": "" + }, + "fpv_tip_0x1BA10007": { + "ar": "", + "de": "Fluggerät bremst. Tempomat deaktiviert", + "en": "Aircraft braking. Cruise control disabled", + "es": "Aeronave frenando. Control de crucero desactivado", + "fr": "Freinage de l'appareil. Régulateur de vitesse désactivé", + "id": "", + "it": "", + "ja": "機体がブレーキ中です。クルーズコントロールが無効", + "ko": "기체 제동. 크루즈 컨트롤 비활성화됨", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Дрон тормозит. Круиз-контроль отключен", + "th": "", + "tr": "Hava aracı fren yapıyor. Hız sabitleyici devre dışı", + "ug": "", + "vi": "", + "zh": "紧急刹车中,已终止杆量保持", + "zh-Hant": "" + }, + "fpv_tip_0x1BA10008": { + "de": "Fernsteuerungssignal verloren. Tempomat deaktiviert", + "en": "Remote controller signal lost. Cruise control disabled", + "es": "Señal del control remoto perdida. Control de crucero desactivado", + "fr": "Signal de la radiocommande perdu. Régulateur de vitesse désactivé", + "ja": "送信機信号ロスト。クルーズコントロールが無効", + "ko": "조종기 신호가 끊김. 크루즈 컨트롤 비활성화됨", + "ru": "Сигнал пульта управления потерян. Круиз-контроль отключен", + "tr": "Uzaktan kumanda sinyali kayboldu. Hız sabitleyici devre dışı", + "zh": "遥控器信号丢失,已终止定速巡航" + }, + "fpv_tip_0x1BA10009": { + "de": "Das Fluggerät hat den Zielpunkt erreicht. Tempomat deaktiviert", + "en": "Aircraft reached the destination point. Cruise Control exited", + "es": "La aeronave ha llegado al punto de destino. Se ha salido del control de crucero", + "fr": "L'appareil a atteint le point de destination. Sortie du régulateur de vitesse", + "ja": "機体が目的地に到達しました。クルーズコントロールを終了しました", + "ko": "기체가 목적지에 도착했습니다. 크루즈 컨트롤 종료됨", + "ru": "Дрон достиг точки назначения. Выполнен выход из режима круиз-контроля", + "tr": "Hava aracı, varış noktasına ulaştı. Hız Sabitleyiciden çıkıldı", + "zh": "到达航线终点,定速巡航已退出" + }, + "fpv_tip_0x1C000001": { + "de": "", + "en": "", + "es": "", + "fr": "Surchauffe caméra X . Attendez que la température de la caméra revienne à la normale avant usage", + "ja": "", + "ko": "", + "ru": "", + "tr": "", + "zh": "X号云台相机过热,请等待降温后再使用" + }, + "fpv_tip_0x1C000103": { + "de": "Hohe Temperatur des Kameraprozessors (%alarmid). Fluggerät ausschalten und vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature high (%alarmid). Power off aircraft and wait for temperature to return to normal before use", + "es": "Temperatura alta del procesador de la cámara (%alarmid). Apaga la aeronave y espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "La température du processeur de la caméra est élevée (%alarmid). Éteignez l'appareil et attendez que sa température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高い(%alarmid)。機体の電源を切り、通常の温度に戻ってからご使用ください", + "ko": "카메라 프로세서 온도 높음(%alarmid). 사용 전에 기체의 전원을 끄고 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Высокая температура процессора камеры (%alarmid). Перед использованием выключите питание дрона и дождитесь, пока температура опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı yüksek (%alarmid). Aracı kapatın ve kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度高(%alarmid),请关闭飞机,等待冷却后再使用" + }, + "fpv_tip_0x1C000103_in_the_sky": { + "de": "Hohe Temperatur des Kameraprozessors (%alarmid). Umgehend zum Startpunkt zurückkehren oder landen. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature high (%alarmid). Return to home or land promptly. Wait for temperature to return to normal before use", + "es": "Temperatura alta del procesador de la cámara (%alarmid). Regresa al punto de origen o aterriza rápidamente. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "La température du processeur de la caméra est élevée (%alarmid). Retournez au point de départ ou atterrissez rapidement. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高い(%alarmid)。直ちに帰還するか、着陸してください。常温に戻るまで待ってからご使用ください", + "ko": "카메라 프로세서 온도 높음(%alarmid). 즉시 리턴 투 홈 또는 착륙 필요. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Высокая температура процессора камеры (%alarmid). Как можно скорее вернитесь на базу или приземлитесь. Перед использованием подождите, пока температура не опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı yüksek (%alarmid). Ana konuma geri dönün veya derhal iniş yapın. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度高(%alarmid),请尽快返航或降落,等待冷却后重启使用" + }, + "fpv_tip_0x1C000104": { + "de": "Temperatur des Kameraprozessors zu hoch. Fluggerät ausschalten. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature too high. Power off aircraft. Wait for temperature to return to normal before use", + "es": "Temperatura demasiado alta del procesador de la cámara. Apaga la aeronave. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra trop élevée. Éteignez l'appareil. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高すぎる。機体電源オフ。常温に戻るまで待ってからご使用ください", + "ko": "카메라 프로세서 온도 너무 높음. 기체 전원을 끄세요. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Чрезмерно высокая температура процессора камеры. Выключите питание дрона. Перед использованием подождите, пока температура не опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı çok yüksek. Aracı kapatın. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请关闭飞机,等待冷却后再使用" + }, + "fpv_tip_0x1C000104_in_the_sky": { + "de": "Temperatur des Kameraprozessors zu hoch. Umgehend zum Startpunkt zurückkehren oder landen. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature too high. Return to home or land promptly. Wait for temperature to return to normal before use", + "es": "Temperatura demasiado alta del procesador de la cámara. Regresa al punto de origen o aterriza rápidamente. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra trop élevée. Retournez au point de départ ou atterrissez rapidement. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高すぎる。直ちに帰還するか、着陸してください。常温に戻るまで待ってからご使用ください", + "ko": "카메라 프로세서 온도 너무 높음. 즉시 리턴 투 홈 또는 착륙 필요. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Чрезмерно высокая температура процессора камеры. Как можно скорее вернитесь на базу или приземлитесь. Перед использованием подождите, пока температура не опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı çok yüksek. Ana konuma geri dönün veya derhal iniş yapın. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请尽快返航或降落,等待冷却后重启使用" + }, + "fpv_tip_0x1C000201": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C000202": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C000203": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C000204": { + "de": "Bildsensor der Kamera überhitzt", + "en": "Camera image sensor overheated", + "es": "Sensor de imagen de la cámara sobrecalentado", + "fr": "Surchauffe du capteur d\\'images de la caméra", + "it": "", + "ja": "カメライメージセンサー高温", + "ko": "카메라 이미지 센서 과열", + "pt": "", + "ru": "Датчик изображения камеры перегрет", + "tr": "Kamera görüntü sensörü aşırı ısındı", + "zh": "相机图像传感器温度过高" + }, + "fpv_tip_0x1C000207": { + "en": "Check if camera connection cable is loose or has been eroded", + "zh": "请检查FPV接线是否松脱或腐蚀" + }, + "fpv_tip_0x1C00020A": { + "ar": "", + "de": "Kalibrierungsdaten Bildsensor fehlerhaft. Fluggerät neu starten", + "en": "Image sensor calibration data error. Restart aircraft", + "es": "Error de datos de calibración del sensor de imagen. Reinicie la aeronave", + "fr": "Erreur de données de l'étalonnage du capteur d'image. Redémarrez l’appareil", + "id": "", + "it": "", + "ja": "イメージセンサーキャリブレーションデータエラーです。機体を再起動してください", + "ko": "이미지 센서 캘리브레이션 데이터 오류. 기체를 재시동하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка данных калибровки датчика изображения. Перезапустите дрон", + "th": "", + "tr": "Görüntü sensörü kalibrasyonu veri hatası. Hava aracını yeniden başlatın", + "ug": "", + "vi": "", + "zh": "图像传感器标定数据异常,请重启", + "zh-Hant": "" + }, + "fpv_tip_0x1C000303": { + "de": "Kameraverbindungsfehler. Kamera neu starten und prüfen, ob Kamera ordnungsgemäß installiert ist", + "en": "Camera connection error. Restart camera and check whether camera is installed properly", + "es": "Error de conexión de la cámara. Reiníciala y comprueba si está correctamente instalada", + "fr": "Erreur de connexion de la caméra. Redémarrez la caméra et vérifiez que la caméra est installée correctement", + "it": "", + "ja": "カメラ接続エラー。カメラを再起動して、カメラが正しく取り付けられているか確認してください", + "ko": "카메라 연결 오류. 카메라 재시작 및 카메라 올바르게 설치되었는지 확인 필요", + "pt": "", + "ru": "Ошибка подключения камеры. Проверьте, правильно ли установлена камера, и перезапустите ее", + "tr": "Kamera bağlantısı hatası. Kamerayı yeniden başlatın ve düzgün takılıp takılmadığını kontrol edin", + "zh": "镜头连接异常,请检查镜头是否正确安装" + }, + "fpv_tip_0x1C000305": { + "de": "Verschluss 100.000 Mal (Designlimit) ausgelöst", + "en": "Shutter trigger count reached 100K design limit", + "es": "El recuento del disparador del obturador ha alcanzado el límite de diseño (100 000)", + "fr": "Limite de conception de 100 000 déclenchements de l\\'obturateur atteinte", + "it": "", + "ja": "シャッタートリガー回数が設計限界の 100K に達しました", + "ko": "셔터 트리거 수가 100,000회 설계 한도에 도달함", + "pt": "", + "ru": "Количество срабатываний затвора достигло проектного предела в 100 тысяч", + "tr": "Deklanşör tetiklenme sayısı 100 bin tasarım sınırına ulaştı", + "zh": "快门使用次数达到十万次" + }, + "fpv_tip_0x1C000306": { + "de": "Objektiv von Drittanbieter", + "en": "Non-DJI Enterprise lens", + "es": "Objetivo que no es de DJI Enterprise", + "fr": "Objectif non DJI Enterprise", + "it": "", + "ja": "DJI Enterprise製以外のレンズ", + "ko": "비순정 DJI 기업 솔루션 렌즈", + "pt": "", + "ru": "Объектив не от DJI Enterprise", + "tr": "DJI Enterprise marka olmayan mercek", + "zh": "非DJI ENTERPRISE镜头" + }, + "fpv_tip_0x1C000310": { + "de": "Kameraobjektiv nicht erkannt", + "en": "Camera lens not detected", + "es": "Objetivo de la cámara no detectado", + "fr": "Objectif de caméra non détecté", + "ja": "カメラレンズが検出されませんでした", + "ko": "카메라 렌즈가 감지되지 않습니다", + "ru": "Объектив камеры не обнаружен", + "tr": "Kamera lensi algılanmadı", + "zh": "相机镜头未连接" + }, + "fpv_tip_0x1C000311": { + "de": "Fehler: Kameraobjektiv. Objektiv erneut installieren", + "en": "Camera lens error. Re-install lens", + "es": "Error del objetivo de la cámara. Vuelva a instalar el objetivo", + "fr": "Erreur de l'objectif de caméra. Réinstaller l'objectif", + "ja": "カメラレンズエラー。レンズを取り付け直してください", + "ko": "카메라 렌즈 오류. 렌즈를 재설치하세요.", + "ru": "Ошибка объектива камеры. Переустановите объектив", + "tr": "Kamera merceği hatası. Merceği yeniden takın", + "zh": "相机镜头故障,请尝试重新安装镜头" + }, + "fpv_tip_0x1C000312": { + "de": "Fehler: Kameraobjektiv. Objektiv erneut installieren", + "en": "Camera lens error. Re-install lens", + "es": "Error del objetivo de la cámara. Vuelva a instalar el objetivo", + "fr": "Erreur de l'objectif de caméra. Réinstaller l'objectif", + "ja": "カメラレンズエラー。レンズを取り付け直してください", + "ko": "카메라 렌즈 오류. 렌즈를 재설치하세요.", + "ru": "Ошибка объектива камеры. Переустановите объектив", + "tr": "Kamera merceği hatası. Merceği yeniden takın", + "zh": "相机镜头故障,请尝试重新安装镜头" + }, + "fpv_tip_0x1C000313": { + "de": "Fehler: Kameraobjektiv. Objektiv erneut installieren", + "en": "Camera lens error. Re-install lens", + "es": "Error del objetivo de la cámara. Vuelva a instalar el objetivo", + "fr": "Erreur de l'objectif de caméra. Réinstaller l'objectif", + "ja": "カメラレンズエラー。レンズを取り付け直してください", + "ko": "카메라 렌즈 오류. 렌즈를 재설치하세요.", + "ru": "Ошибка объектива камеры. Переустановите объектив", + "tr": "Kamera merceği hatası. Merceği yeniden takın", + "zh": "相机镜头故障,请尝试重新安装镜头" + }, + "fpv_tip_0x1C000314": { + "de": "Fehler: Kameraobjektiv. Objektiv erneut installieren", + "en": "Camera lens error. Re-install lens", + "es": "Error del objetivo de la cámara. Vuelva a instalar el objetivo", + "fr": "Erreur de l'objectif de caméra. Réinstaller l'objectif", + "ja": "カメラレンズエラー。レンズを取り付け直してください", + "ko": "카메라 렌즈 오류. 렌즈를 재설치하세요.", + "ru": "Ошибка объектива камеры. Переустановите объектив", + "tr": "Kamera merceği hatası. Merceği yeniden takın", + "zh": "相机镜头故障,请尝试重新安装镜头" + }, + "fpv_tip_0x1C000317": { + "de": "Kalibrierungsdaten Objektiv fehlerhaft. Objektiv erneut installieren oder Fluggerät neu starten", + "en": "Lens calibration data error. Re-install lens or restart aircraft", + "es": "Error de datos de calibración de objetivo. Vuelva a instalar el objetivo o reinicie la aeronave", + "fr": "Erreur de données de l'étalonnage de l'objectif. Réinstallez l'objectif ou redémarrez l'appareil", + "ja": "レンズキャリブレーションデータエラーです。レンズを取り付け直すか、機体を再起動してください", + "ko": "렌즈 캘리브레이션 데이터 오류. 렌즈를 재설치하거나 기체를 재시동하세요", + "pt": "", + "ru": "Ошибка данных калибровки объектива. Переустановите объектив или перезапустите дрон", + "tr": "Lens kalibrasyonu veri hatası. Lensi yeniden takın veya aracı yeniden başlatın", + "zh": "镜头标定数据异常,请插拔镜头或重启" + }, + "fpv_tip_0x1C000401": { + "de": "Ungültige Speicherkarte. Karte austauschen (%alarmid).", + "en": "Invalid memory card. Replace card (%alarmid)", + "es": "Tarjeta de memoria no válida. Cambie la tarjeta (%alarmid)", + "fr": "Carte mémoire non valide. Remplacez la carte (%alarmid)", + "ja": "メモリーカードが無効です。 カードを交換してください(%alarmid)", + "ko": "잘못된 메모리 카드입니다. 카드를 교체하세요(%alarmid)", + "ru": "Недопустимая карта памяти. Замените карту (%alarmid)", + "tr": "Geçersiz hafıza kartı. Kartı değiştirin (%alarmid)", + "zh": "无效存储卡,请更换存储卡(%alarmid)" + }, + "fpv_tip_0x1C000402": { + "de": "Niedrige Speicherkartengeschwindigkeit. Durch schnellere Karte austauschen.", + "en": "Memory card speed low. Replace with faster card", + "es": "Velocidad baja de la tarjeta de memoria. Cambie la tarjeta por una más rápida", + "fr": "Vitesse de la carte mémoire lente. Remplacez-la par une carte plus rapide", + "ja": "メモリーカードが低速です。 より高速のカードと交換してください", + "ko": "메모리 카드 속도 느림. 더 빠른 카드로 교체하세요", + "ru": "Низкая скорость карты памяти. Замените карту на более быструю", + "tr": "Hafıza kartının hızı yavaş. Daha hızlı bir hafıza kartı ile değiştirin", + "zh": "存储卡为慢速卡,请更换" + }, + "fpv_tip_0x1C000403": { + "de": "Speicherkartenfehler. Karte austauschen (%alarmid).", + "en": "Memory card error. Replace card (%alarmid)", + "es": "Error de la tarjeta de memoria. Cambie la tarjeta (%alarmid)", + "fr": "Erreur de carte mémoire. Remplacez la carte (%alarmid)", + "ja": "メモリーカードにエラーが発生しました。 カードを交換してください(%alarmid)", + "ko": "메모리 카드 오류. 카드를 교체하세요(%alarmid)", + "ru": "Ошибка карты памяти. Замените карту (%alarmid)", + "tr": "Hafıza kartı hatası. Kartı değiştirin (%alarmid)", + "zh": "存储卡异常,请更换存储卡(%alarmid)" + }, + "fpv_tip_0x1C000404": { + "de": "Keine Speicherkarte", + "en": "No memory card", + "es": "No hay tarjeta de memoria", + "fr": "Aucune carte mémoire", + "ja": "メモリーカードがありません", + "ko": "메모리 카드 없음", + "ru": "Нет карты памяти", + "tr": "Hafıza kartı yok", + "zh": "无存储卡" + }, + "fpv_tip_0x1C000405": { + "de": "Lese- und Schreibberechtigungen für Speicherkarte bestätigen", + "en": "Confirm memory card read and write permissions", + "es": "Confirme los permisos de lectura y escritura de la tarjeta de memoria", + "fr": "Confirmez les autorisations de lecture et d'écriture de la carte mémoire", + "it": "", + "ja": "メモリーカードの読み取り/書き込み権限を確認してください", + "ko": "메모리 카드 읽기 및 쓰기 권한을 확인하세요", + "pt": "", + "ru": "Подтвердите наличие разрешений на чтение и запись карты памяти", + "tr": "Hafıza kartı okuma ve yazma izinlerini onaylayın", + "zh": "请确认存储卡读写属性" + }, + "fpv_tip_0x1C000407": { + "de": "Speicherkarte wird formatiert...", + "en": "Formatting memory card...", + "es": "Formateando la tarjeta de memoria...", + "fr": "Formatage de la carte mémoire…", + "it": "", + "ja": "メモリーカードのフォーマット中...", + "ko": "메모리 카드 포맷 중...", + "pt": "", + "ru": "Форматирование карты памяти...", + "tr": "Hafıza kartı biçimlendiriliyor...", + "zh": "存储卡正在格式化,请等待" + }, + "fpv_tip_0x1C000408": { + "de": "Dateisystem der Speicherkarte wird nicht unterstützt. Karte vor Gebrauch formatieren.", + "en": "Memory card file system not supported. Format card before use", + "es": "Sistema de archivos de la tarjeta de memoria no compatible. Formatee la tarjeta antes del uso", + "fr": "Système de fichiers de la carte mémoire non pris en charge. Formatez la carte avant utilisation", + "it": "", + "ja": "メモリーカードファイルシステムはサポートされていません。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드 파일 시스템이 지원되지 않습니다. 사용 전에 카드를 포맷하세요", + "pt": "", + "ru": "Файловая система карты памяти не поддерживается. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı dosya sistemi desteklenmiyor. Kullanmadan önce kartı biçimlendirin", + "zh": "不支持该存储卡文件系统,请格式化后使用" + }, + "fpv_tip_0x1C00040A": { + "de": "Speicherkarte voll. Speicherplatz freigeben.", + "en": "Memory card full. Clear space", + "es": "Tarjeta de memoria llena. Libere espacio", + "fr": "Carte mémoire pleine. Libérez de l'espace", + "it": "", + "ja": "メモリーカードが満杯です。 領域をクリア", + "ko": "메모리 카드 공간 없음. 공간을 확보하세요", + "pt": "", + "ru": "Карта памяти заполнена. Освободите место", + "tr": "Hafıza kartı dolu. Yer açın", + "zh": "存储卡已满,请清除内存" + }, + "fpv_tip_0x1C00040B": { + "de": "Max. Dateiindex überschritten. SD-Karte formatieren", + "en": "Max file index exceeded. Format SD card", + "es": "Se ha superado el índice máximo de archivos. Formatear tarjeta SD", + "fr": "Index de fichier max. dépassé. Formater la carte SD", + "it": "", + "ja": "ファイルインデックスの最大値を超えました。SDカードをフォーマット", + "ko": "최대 파일 색인을 초과함. SD 카드 포맷", + "pt": "", + "ru": "Превышен максимальный индекс файла. Форматировать карту памяти SD", + "tr": "Maks. dosya dizini aşıldı. SD kartı biçimlendir", + "zh": "文件索引超出最大限制,请格式化SD卡" + }, + "fpv_tip_0x1C00040C": { + "de": "Speicherkarte wird initialisiert...", + "en": "Initializing memory card...", + "es": "Inicializando tarjeta de memoria...", + "fr": "Initialisation de la carte mémoire…", + "it": "", + "ja": "メモリーカードの初期化中...", + "ko": "메모리 카드 초기화 중...", + "pt": "", + "ru": "Инициализация карты памяти...", + "tr": "Hafıza kartı başlatılıyor...", + "zh": "存储卡正在初始化,请等待" + }, + "fpv_tip_0x1C00040D": { + "de": "Speicherkartenfehler. Karte vor Gebrauch formatieren.", + "en": "Memory card error. Format card before use", + "es": "Error de la tarjeta de memoria. Formatee la tarjeta antes del uso", + "fr": "Erreur de carte mémoire. Formatez la carte avant utilisation", + "it": "", + "ja": "メモリーカードにエラーが発生しました。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드 오류. 사용 전에 카드를 포맷하세요", + "pt": "", + "ru": "Ошибка карты памяти. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı hatası. Kullanmadan önce kartı biçimlendirin", + "zh": "存储卡异常,请格式化存储卡后使用" + }, + "fpv_tip_0x1C00040E": { + "de": "Niedrige Speicherkarten-Schreibgeschwindigkeit", + "en": "Memory card write speed low", + "es": "Velocidad baja de escritura de la tarjeta de memoria", + "fr": "Vitesse d'écriture de la carte mémoire lente", + "it": "", + "ja": "メモリーカード書き込みが低速です", + "ko": "메모리 카드 쓰기 속도 느림", + "pt": "", + "ru": "Низкая скорость записи карты памяти", + "tr": "Hafıza kartının yazma hızı düşük", + "zh": "存储卡写入速度过慢" + }, + "fpv_tip_0x1C00040F": { + "de": "Niedrige Speicherkarten-Schreibgeschwindigkeit", + "en": "Memory card write speed low", + "es": "Velocidad baja de escritura de la tarjeta de memoria", + "fr": "Vitesse d'écriture de la carte mémoire lente", + "ja": "メモリーカード書き込みが低速です", + "ko": "메모리 카드 쓰기 속도 느림", + "ru": "Низкая скорость записи карты памяти", + "tr": "Hafıza kartının yazma hızı düşük", + "zh": "存储卡写入速度过慢" + }, + "fpv_tip_0x1C000411": { + "de": "Schreibfehler auf SD-Karte. SD-Karte austauschen", + "en": "SD card write error. Replace SD card", + "es": "Error de escritura de la tarjeta SD. Cambie la tarjeta SD", + "fr": "Erreur écriture carte SD. Remplacez la carte SD", + "ja": "SDカード書き込みエラー。SDカードを交換してください", + "ko": "SD 카드 쓰기 오류. SD 카드를 교체하세요", + "ru": "Ошибка записи SD-карты. Замените SD-карту", + "tr": "SD kart yazma hatası. SD kartı değiştirin", + "zh": "SD卡写入异常,请更换" + }, + "fpv_tip_0x1C000412": { + "ar": "", + "de": "", + "en": "Verification required before using memory card. Enter password to verify", + "es": "", + "fr": "", + "it": "", + "ja": "", + "ko": "", + "pt": "", + "ru": "", + "tr": "", + "zh": "存储卡加密待验证,请输入密码验证后使用" + }, + "fpv_tip_0x1C000602": { + "de": "Umgebungslicht zu dunkel", + "en": "Ambient Light Too Low", + "es": "Luz ambiente demasiado baja", + "fr": "Lumière ambiante trop faible", + "it": "", + "ja": "周辺光が暗すぎます", + "ko": "주변 조명 너무 어두움", + "pt": "", + "ru": "Слишком слабое освещение", + "tr": "Ortam Işığı Çok Düşük", + "zh": "相机拍照环境过暗" + }, + "fpv_tip_0x1C000603": { + "de": "Fotos können unterbelichtet sein", + "en": "Photos may be underexposed", + "es": "Las fotos pueden aparecer subexpuestas", + "fr": "Les photos peuvent être sous-exposées", + "ja": "写真の露出不足の可能性があります", + "ko": "사진이 노출 부족일 수 있음", + "ru": "Фотографии могут быть недоэкспонированы", + "tr": "Fotoğraflar yetersiz pozlanmış olabilir", + "zh": "照片存在欠曝风险" + }, + "fpv_tip_0x1C000604": { + "de": "Fotos können überbelichtet sein", + "en": "Photos may be overexposed", + "es": "Las fotos pueden aparecer sobreexpuestas", + "fr": "Les photos peuvent être sur-exposées", + "ja": "写真の露出オーバーの可能性があります", + "ko": "사진이 노출 과다일 수 있음", + "ru": "Фотографии могут быть переэкспонированы", + "tr": "Fotoğraflar aşırı pozlanmış olabilir", + "zh": "照片存在过曝风险" + }, + "fpv_tip_0x1C000901": { + "de": "Fehler: Senden von PPS-Signal", + "en": "PPS signal sending error", + "es": "Error de envío de la señal PPS", + "fr": "Erreur d\\'envoi du signal PPS", + "it": "", + "ja": "PPS 信号送信エラー", + "ko": "PPS 신호 전송 오류", + "pt": "", + "ru": "Ошибка отправки сигнала PPS", + "tr": "PPS sinyali gönderim hatası", + "zh": "PPS对时信号异常" + }, + "fpv_tip_0x1C000902": { + "de": "Fehler: Zeitsynchronisierung der Kamera", + "en": "Camera time synchronization error", + "es": "Error de sincronización de la hora de la cámara", + "fr": "Erreur de synchronisation de l\\'heure de la caméra", + "it": "", + "ja": "カメラの時間同期エラー", + "ko": "카메라 시간 동기화 오류", + "pt": "", + "ru": "Ошибка синхронизации времени камеры", + "tr": "Kamera saati senkronizasyon hatası", + "zh": "相机时间同步异常" + }, + "fpv_tip_0x1C000903": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C000904": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C000905": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C000906": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C000907": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C000908": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C000909": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C00090A": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C000A01": { + "de": "Bei der Aufnahme wurden Bildformate verworfen. Firmware-Aktualisierung empfohlen", + "en": "Frames dropped in recording. Firmware update recommended", + "es": "Drop frames en la grabación. Se recomienda actualizar el firmware", + "fr": "Images perdues lors de l’enregistrement. Mise à jour du firmware recommandée", + "ja": "撮影中にコマ落ちがありました。ファームウェア更新をお勧めします", + "ko": "녹화 중 프레임이 떨어졌습니다. 펌웨어 업데이트를 권장합니다", + "ru": "Потеря кадров в записи. Рекомендуется обновить прошивку", + "tr": "Kayıt sırasında kare sayısı düştü. Ürün yazılımını güncellemeniz önerilir", + "zh": "录像丢帧,建议升级固件" + }, + "fpv_tip_0x1C000A02": { + "de": "Bei der Aufnahme wurden Bildformate verworfen. Firmware-Aktualisierung empfohlen", + "en": "Frames dropped in recording. Firmware update recommended", + "es": "Drop frames en la grabación. Se recomienda actualizar el firmware", + "fr": "Images perdues lors de l’enregistrement. Mise à jour du firmware recommandée", + "ja": "撮影中にコマ落ちがありました。ファームウェア更新をお勧めします", + "ko": "녹화 중 프레임이 떨어졌습니다. 펌웨어 업데이트를 권장합니다", + "ru": "Потеря кадров в записи. Рекомендуется обновить прошивку", + "tr": "Kayıt sırasında kare sayısı düştü. Ürün yazılımını güncellemeniz önerilir", + "zh": "录像丢帧,建议升级固件" + }, + "fpv_tip_0x1C000B01": { + "de": "Hardwarefehler: Kamera. Neu starten und erneut versuchen", + "en": "Camera hardware error. Restart and try again", + "es": "Error de hardware de la cámara. Reinicia y vuelve a intentarlo.", + "fr": "Erreur matérielle de caméra. Redémarrez et réessayez", + "ja": "カメラのハードウェアエラー。再起動してやり直してください", + "ko": "카메라 하드웨어 오류. 재시작한 후 다시 시도하세요.", + "ru": "Аппаратная ошибка камеры. Перезапустите дрон и повторите попытку", + "tr": "Kamera donanım hatası. Yeniden başlatın ve tekrar deneyin", + "zh": "相机硬件异常,请尝试重新启动" + }, + "fpv_tip_0x1C000D01": { + "de": "Fokussierung fehlgeschlagen", + "en": "Focusing failed", + "es": "Error de enfoque", + "fr": "Échec de la mise au point", + "it": "", + "ja": "フォーカス失敗", + "ko": "포커스 맞추기 실패", + "pt": "", + "ru": "Сбой фокусировки", + "tr": "Odaklama başarısız", + "zh": "对焦失败" + }, + "fpv_tip_0x1C000D02": { + "de": "Unendlichkeitsfokus des Objektives nicht kalibriert", + "en": "Lens infinity focus not calibrated", + "es": "Enfoque infinito del objetivo no calibrado", + "fr": "Objectif mise au point infinie non étalonné", + "it": "", + "ja": "レンズの無限遠フォーカスがキャリブレーションされていません", + "ko": "렌즈 무한대 초점 캘리브레이션 안 됨", + "pt": "", + "ru": "Сбой загрузки файла калибровки камеры", + "tr": "Mercek sonsuz odağı kalibre edilmemiş", + "zh": "镜头未进行无穷远标定" + }, + "fpv_tip_0x1C000D03": { + "de": "Kalibrierungsdaten von Unendlichkeitsfokus abgelaufen. Erneut kalibrieren", + "en": "Infinity focus calibration data expired. Recalibrate", + "es": "Los datos de calibración de enfoque infinito han caducado. Vuelve a calibrar", + "fr": "Données d\\'étalonnage de la mise au point infinie expirées. Étalonnez à nouveau", + "it": "", + "ja": "無限遠フォーカスのキャリブレーションデータの期限が切れています。再キャリブレーションしてください", + "ko": "무한대 포커스 캘리브레이션 데이터 만료. 다시 캘리브레이션 하세요", + "pt": "", + "ru": "Истек срок действия данных калибровки фокусировки на бесконечность. Выполните повторную калибровку", + "tr": "Sonsuz odak kalibrasyonu verilerinin süresi doldu. Tekrar kalibre edin", + "zh": "无穷远标定数据过期,请重新标定" + }, + "fpv_tip_0x1C000D04": { + "de": "Kalibrierungsdaten von Unendlichkeitsfokus abgelaufen. Erneut kalibrieren", + "en": "Infinity focus calibration data expired. Recalibrate", + "es": "Los datos de calibración de enfoque infinito han caducado. Vuelve a calibrar", + "fr": "Données d'étalonnage de la mise au point infinie expirées. Étalonnez à nouveau", + "it": "", + "ja": "無限遠フォーカスのキャリブレーションデータの期限が切れています。再キャリブレーションしてください", + "ko": "무한대 포커스 캘리브레이션 데이터 만료. 다시 캘리브레이션 하세요", + "pt": "", + "ru": "Истек срок действия данных калибровки фокусировки на бесконечность. Выполните повторную калибровку", + "tr": "Sonsuz odak kalibrasyonu verilerinin süresi doldu. Tekrar kalibre edin", + "zh": "无穷远标定数据过期,请重新标定" + }, + "fpv_tip_0x1C000E01": { + "de": "Kalibrierungsparameter von Kamera und Objektiv stimmen nicht überein", + "en": "Camera and lens intrinsic parameters calibration data do not match", + "es": "Los datos de calibración de los parámetros internos de la cámara y el objetivo no coinciden", + "fr": "Données d\\'étalonnage des paramètres intrinsèques de la caméra et de l\\'objectif incohérents", + "it": "", + "ja": "カメラとレンズの内部パラメーターのキャリブレーションデータが不一致", + "ko": "카메라 및 렌즈 내부 매개변수 캘리브레이션 데이터 불일치", + "pt": "", + "ru": "Параметры калибровки не соответствуют камере или объективу", + "tr": "Kamera ve mercek yapısal parametre kalibrasyonu verileri eşleşmiyor", + "zh": "镜头与相机内参检校不匹配" + }, + "fpv_tip_0x1C000E02": { + "de": "Kalibrierungsparameter abgelaufen", + "en": "Intrinsic parameters calibration data expired", + "es": "Los datos de calibración de los parámetros internos han caducado", + "fr": "Données d\\'étalonnage des paramètres intrinsèques de la caméra expirées", + "it": "", + "ja": "内部パラメーターのキャリブレーションデータが期限切れ", + "ko": "내부 매개변수 캘리브레이션 데이터 만료", + "pt": "", + "ru": "Срок действия данных калибровки внутренних параметров камеры истек", + "tr": "Yapısal parametre kalibrasyonu verilerinin süresi doldu", + "zh": "内参检校参数过旧" + }, + "fpv_tip_0x1C001001": { + "de": "DJI PROSSD-Fragmentierungsrisiko erkannt. Formatierung des Speichergeräts empfohlen", + "en": "DJI PROSSD fragmentation risk detected. Formatting storage device recommended", + "es": "Riesgo de fragmentación de DJI PROSSD detectado. Se recomienda formatear el dispositivo de almacenamiento", + "fr": "Risque de fragmentation DJI PROSSD détecté. Formatage du périphérique de stockage recommandé", + "ja": "DJI PROSSDの断片化のリスクが検出されました。ストレージ機器のフォーマットをお勧めします", + "ko": "DJI PROSSD 단편화 위험이 감지되었습니다. 저장 장치 포맷을 권장합니다", + "ru": "Обнаружен риск фрагментации DJI PROSSD. Рекомендуется форматирование устройства хранения", + "tr": "DJI PROSSD parçalanma riski algılandı. Depolama cihazının biçimlendirilmesi önerilir", + "zh": "DJI PROSSD存储碎片化即将满,建议格式化" + }, + "fpv_tip_0x1C001002": { + "de": "DJI PROSSD fragmentiert. Formatierung des Speichergeräts empfohlen", + "en": "DJI PROSSD fragmented. Formatting storage device recommended", + "es": "DJI PROSSD fragmentado. Se recomienda formatear el dispositivo de almacenamiento", + "fr": "DJI PROSSD fragmenté. Formatage du périphérique de stockage recommandé", + "ja": "DJI PROSSDが断片化しています。ストレージ機器のフォーマットをお勧めします", + "ko": "DJI PROSSD가 단편화되었습니다. 저장 장치 포맷을 권장합니다", + "ru": "DJI PROSSD фрагментирован. Рекомендуется форматирование устройства хранения", + "tr": "DJI PROSSD parçalandı. Depolama cihazının biçimlendirilmesi önerilir", + "zh": "DJI PROSSD存储碎片化已满,建议格式化" + }, + "fpv_tip_0x1C001003": { + "de": "", + "en": "", + "es": "", + "fr": "Surchauffe du processeur de la caméra . Retournez au point de départ ou atterrissez immédiatement et attendez que la température de la caméra revienne à la normale avant usage\r\r\n\r\r\nSurchauffe du processeur de la caméra . Retournez au point de départ ou atterrissez immédiatement et attendez que la température de la caméra revienne à la normale avant usage", + "ja": "", + "ko": "", + "ru": "", + "tr": "", + "zh": "获取 DJI PROSSD 存储信息失败,避免存储风险,请备份素材后格式化" + }, + "fpv_tip_0x1C001101": { + "de": "Das Ende der Lebensdauer von DJI PROSSD ist bald erreicht. Austausch des Speichergeräts empfohlen.", + "en": "DJI PROSSD approaching end of lifespan. Replacing storage device recommended", + "es": "DJI PROSSD cerca del final de su vida útil. Se recomienda sustituir el dispositivo de almacenamiento", + "fr": "DJI PROSSD bientôt en fin de vie. Remplacement du périphérique de stockage recommandé", + "ja": "DJI PROSSDが有効期限に近づいています。ストレージ機器の交換をお勧めします", + "ko": "DJI PROSSD가 수명을 거의 다했습니다. 저장 장치 교체를 권장합니다", + "ru": "Срок службы DJI PROSSD подходит к концу. Рекомендуется замена устройства хранения", + "tr": "DJI PROSSD kullanım ömrünün sonuna yaklaşıyor. Depolama cihazının yenilenmesi önerilir", + "zh": "DJI PROSSD读写量即将到达上限,建议更换" + }, + "fpv_tip_0x1C001102": { + "de": "Das Ende der Lebensdauer von DJI PROSSD ist erreicht. Austausch des Speichergeräts empfohlen", + "en": "DJI PROSSD reached end of lifespan. Replacing storage device recommended", + "es": "DJI PROSSD ha alcanzado el final de su vida útil. Se recomienda sustituir el dispositivo de almacenamiento", + "fr": "DJI PROSSD a atteint sa fin de vie. Remplacement du périphérique de stockage recommandé", + "ja": "DJI PROSSDが有効期限に達しました。ストレージ機器の交換をお勧めします", + "ko": "DJI PROSSD가 수명을 다했습니다. 저장 장치 교체를 권장합니다", + "ru": "Срок службы DJI PROSSD подошел к концу. Рекомендуется замена устройства хранения", + "tr": "DJI PROSSD kullanım ömrünün sonuna erişti. Depolama cihazının yenilenmesi önerilir", + "zh": "DJI PROSSD读写量已达上限,建议更换" + }, + "fpv_tip_0x1C001103": { + "de": "In DJI PROSSD gespeicherte Daten konnten nicht abgerufen werden. Sichere die Dateien, bevor du DJI PROSSD formatierst, um Datenverlust zu vermeiden", + "en": "Failed to obtain data stored in DJI PROSSD. Back up files before formatting DJI PROSSD to avoid data loss", + "es": "Error al obtener los datos almacenados en DJI PROSSD. Para evitar la pérdida de datos, realice una copia de seguridad de los archivos antes de formatear DJI PROSSD", + "fr": "Impossible d'obtenir les données stockées dans DJI PROSSD. Sauvegardez les fichiers avant de formater DJI PROSSD pour éviter toute perte de données", + "ja": "DJI ProSSDに保存されているデータの取得に失敗しました。データの消失を回避するため、DJI ProSSDをフォーマットする前にファイルをバックアップしてください", + "ko": "DJI PROSSD에 저장된 데이터를 가져오지 못했습니다. 데이터 손실을 방지하기 위해 DJI PROSSD를 포맷하기 전에 파일을 백업하세요.", + "ru": "Не удалось получить данные из DJI PROSSD. Во избежание потери данных выполните резервное копирование файлов перед форматированием DJI PROSSD", + "tr": "DJI PROSSD'de saklanan veriler alınamadı. Veri kaybını önlemek için DJI PROSSD'yi biçimlendirmeden önce dosyaları yedekleyin", + "zh": "获取 DJI PROSSD 存储信息失败,避免存储风险,请备份素材后格式化" + }, + "fpv_tip_0x1C001201": { + "de": "DJI PROSSD zum Starten der Aufnahme verwenden", + "en": "Use DJI PROSSD to start recording", + "es": "Utilizar DJI PROSSD para iniciar grabación", + "fr": "Utiliser DJI PROSSD pour lancer l’enregistrement", + "ja": "DJI PROSSDを使用して撮影を開始してください", + "ko": "DJI PROSSD를 사용해 녹화를 시작하세요", + "ru": "Используйте DJI PROSSD, чтобы начать запись", + "tr": "Kayda başlamak için DJI PROSSD'yi kullanın", + "zh": "请使用DJI PROSSD以正常使用录像功能" + }, + "fpv_tip_0x1C001301": { + "de": "Das Video konnte nicht in den Speicher geschrieben werden. Aufnahme wird gestoppt...", + "en": "Failed to write video to storage. Stopping recording...", + "es": "No se ha podido registrar el video en el almacenamiento. Deteniendo la grabación...", + "fr": "Échec de l’écriture de la vidéo dans le stockage. Arrêt de l’enregistrement en cours...", + "ja": "ストレージへの動画の書き込みに失敗しました。撮影を停止しています...", + "ko": "동영상을 저장 장치에 쓰기하지 못했습니다. 녹화 중단 중...", + "ru": "Не удалось записать видео в хранилище. Выполняется остановка записи...", + "tr": "Video, depolama alanına yazılamadı. Kayıt durduruluyor...", + "zh": "视频写入失败,正在停止录像" + }, + "fpv_tip_0x1C001302": { + "de": "Niedrige DJI PROSSD-Schreibgeschwindigkeit. Aufnahme wird gestoppt...", + "en": "DJI PROSSD write speed low. Stopping recording...", + "es": "Baja velocidad de escritura en DJI PROSSD. Deteniendo la grabación...", + "fr": "Vitesse d’écriture DJI PROSSD faible. Arrêt de l’enregistrement en cours...", + "ja": "DJI PROSSDの書き込みが低速です。撮影を停止しています...", + "ko": "DJI PROSSD 쓰기 속도가 낮습니다. 녹화 중단 중...", + "ru": "Низкая скорость записи DJI PROSSD. Выполняется остановка записи...", + "tr": "DJI PROSSD yazma hızı düşük. Kayıt durduruluyor...", + "zh": "DJI PROSSD写入速度慢,正在停止录像" + }, + "fpv_tip_0x1C001303": { + "de": "Unzureichender Speicherplatz auf DJI PROSSD. Aufnahme wird gestoppt...", + "en": "Insufficient storage on DJI PROSSD. Stopping recording...", + "es": "Almacenamiento insuficiente en DJI PROSSD. Deteniendo la grabación...", + "fr": "Stockage insuffisant sur DJI PROSSD. Arrêt de l’enregistrement en cours...", + "ja": "DJI PROSSDのストレージが不足しています。撮影を停止しています...", + "ko": "DJI PROSSD에 저장 공간이 충분하지 않습니다. 녹화 중단 중...", + "ru": "Недостаточно места на DJI PROSSD. Выполняется остановка записи...", + "tr": "DJI PROSSD'de yetersiz depolama alanı. Kayıt durduruluyor...", + "zh": "DJI PROSSD剩余空间不足,正在停止录像" + }, + "fpv_tip_0x1C001306": { + "en": "System busy. Recording not allowed", + "zh": "系统业务繁忙,禁止录像" + }, + "fpv_tip_0x1C001307": { + "en": "System not busy. Recording available", + "zh": "业务繁忙解除,允许录像" + }, + "fpv_tip_0x1C001401": { + "de": "Die Kameraverbindung ist instabil. Den Gimbal lösen und wieder montieren", + "en": "Camera connection unstable. Detach and remount gimbal", + "es": "La conexión de la cámara es inestable. Retira el estabilizador y vuélvelo a montar", + "fr": "Connexion caméra instable. Détacher et remonter la nacelle", + "ja": "カメラの接続が不安定です。ジンバルを取り付け直してください", + "ko": "카메라 연결이 불안정합니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Нестабильное соединение с камерой. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera bağlantısı güvenilir değil. Gimbalı çıkarın ve yeniden takın", + "zh": "相机信号链路不稳定,请尝试重新拔插云台" + }, + "fpv_tip_0x1C001402": { + "de": "Die Kameraverbindung ist instabil. Den Gimbal lösen und wieder montieren.", + "en": "Camera connection unstable. Detach and remount gimbal", + "es": "La conexión de la cámara es inestable. Retira el estabilizador y vuélvelo a montar", + "fr": "Connexion caméra instable. Détacher et remonter la nacelle", + "ja": "カメラの接続が不安定です。ジンバルを取り付け直してください", + "ko": "카메라 연결이 불안정합니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Нестабильное соединение с камерой. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera bağlantısı güvenilir değil. Gimbalı çıkarın ve yeniden takın", + "zh": "相机信号链路不稳定,请尝试重新拔插云台" + }, + "fpv_tip_0x1C001403": { + "de": "Die Kameraverbindung ist instabil. Den Gimbal lösen und wieder montieren", + "en": "Camera connection unstable. Detach and remount gimbal", + "es": "La conexión de la cámara es inestable. Retira el estabilizador y vuélvelo a montar", + "fr": "Connexion caméra instable. Détacher et remonter la nacelle", + "ja": "カメラの接続が不安定です。ジンバルを取り付け直してください", + "ko": "카메라 연결이 불안정합니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Нестабильное соединение с камерой. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera bağlantısı güvenilir değil. Gimbalı çıkarın ve yeniden takın", + "zh": "相机信号链路不稳定,请尝试重新拔插云台" + }, + "fpv_tip_0x1C001404": { + "de": "Die Kameraverbindung ist instabil. Den Gimbal lösen und wieder montieren", + "en": "Camera connection unstable. Detach and remount gimbal", + "es": "La conexión de la cámara es inestable. Retira el estabilizador y vuélvelo a montar", + "fr": "Connexion caméra instable. Détacher et remonter la nacelle", + "ja": "カメラの接続が不安定です。ジンバルを取り付け直してください", + "ko": "카메라 연결이 불안정합니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Нестабильное соединение с камерой. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera bağlantısı güvenilir değil. Gimbalı çıkarın ve yeniden takın", + "zh": "相机信号链路不稳定,请尝试重新拔插云台" + }, + "fpv_tip_0x1C001405": { + "de": "Die Kameraverbindung ist instabil. Den Gimbal lösen und wieder montieren", + "en": "Camera connection unstable. Detach and remount gimbal", + "es": "La conexión de la cámara es inestable. Retira el estabilizador y vuélvelo a montar", + "fr": "Connexion caméra instable. Détacher et remonter la nacelle", + "ja": "カメラの接続が不安定です。ジンバルを取り付け直してください", + "ko": "카메라 연결이 불안정합니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Нестабильное соединение с камерой. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera bağlantısı güvenilir değil. Gimbalı çıkarın ve yeniden takın", + "zh": "相机信号链路不稳定,请尝试重新拔插云台" + }, + "fpv_tip_0x1C001406": { + "de": "Die Kameraverbindung ist instabil. Den Gimbal lösen und wieder montieren", + "en": "Camera connection unstable. Detach and remount gimbal", + "es": "La conexión de la cámara es inestable. Retira el estabilizador y vuélvelo a montar", + "fr": "Connexion caméra instable. Détacher et remonter la nacelle", + "ja": "カメラの接続が不安定です。ジンバルを取り付け直してください", + "ko": "카메라 연결이 불안정합니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Нестабильное соединение с камерой. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera bağlantısı güvenilir değil. Gimbalı çıkarın ve yeniden takın", + "zh": "相机信号链路不稳定,请尝试重新拔插云台" + }, + "fpv_tip_0x1C001407": { + "de": "Die Kameraverbindung ist instabil. Den Gimbal lösen und wieder montieren", + "en": "Camera connection unstable. Detach and remount gimbal", + "es": "La conexión de la cámara es inestable. Retira el estabilizador y vuélvelo a montar", + "fr": "Connexion caméra instable. Détacher et remonter la nacelle", + "ja": "カメラの接続が不安定です。ジンバルを取り付け直してください", + "ko": "카메라 연결이 불안정합니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Нестабильное соединение с камерой. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera bağlantısı güvenilir değil. Gimbalı çıkarın ve yeniden takın", + "zh": "相机信号链路不稳定,请尝试重新拔插云台" + }, + "fpv_tip_0x1C001408": { + "de": "Die Kameraverbindung ist instabil. Den Gimbal lösen und wieder montieren", + "en": "Camera connection unstable. Detach and remount gimbal", + "es": "La conexión de la cámara es inestable. Retira el estabilizador y vuélvelo a montar", + "fr": "Connexion caméra instable. Détacher et remonter la nacelle", + "ja": "カメラの接続が不安定です。ジンバルを取り付け直してください", + "ko": "카메라 연결이 불안정합니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Нестабильное соединение с камерой. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera bağlantısı güvenilir değil. Gimbalı çıkarın ve yeniden takın", + "zh": "相机信号链路不稳定,请尝试重新拔插云台" + }, + "fpv_tip_0x1C001409": { + "de": "Die Kameraverbindung ist instabil. Den Gimbal lösen und wieder montieren", + "en": "Camera connection unstable. Detach and remount gimbal", + "es": "La conexión de la cámara es inestable. Retira el estabilizador y vuélvelo a montar", + "fr": "Connexion caméra instable. Détacher et remonter la nacelle", + "ja": "カメラの接続が不安定です。ジンバルを取り付け直してください", + "ko": "카메라 연결이 불안정합니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Нестабильное соединение с камерой. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera bağlantısı güvenilir değil. Gimbalı çıkarın ve yeniden takın", + "zh": "相机信号链路不稳定,请尝试重新拔插云台" + }, + "fpv_tip_0x1C00140A": { + "de": "Die Kameraverbindung ist instabil. Den Gimbal lösen und wieder montieren", + "en": "Camera connection unstable. Detach and remount gimbal", + "es": "La conexión de la cámara es inestable. Retira el estabilizador y vuélvelo a montar", + "fr": "Connexion caméra instable. Détacher et remonter la nacelle", + "ja": "カメラの接続が不安定です。ジンバルを取り付け直してください", + "ko": "카메라 연결이 불안정합니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Нестабильное соединение с камерой. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera bağlantısı güvenilir değil. Gimbalı çıkarın ve yeniden takın", + "zh": "相机信号链路不稳定,请尝试重新拔插云台" + }, + "fpv_tip_0x1C00140E": { + "de": "Kamerafehler. Neustart des Fluggeräts empfohlen", + "en": "Camera error. Restarting aircraft recommended", + "es": "Error de la cámara. Se recomienda reiniciar la aeronave", + "fr": "Erreur caméra. Redémarrage de l’appareil recommandé", + "ja": "カメラエラー。機体の再起動をお勧めします", + "ko": "카메라 오류. 기체 재시작을 권장합니다", + "ru": "Ошибка камеры. Рекомендуется перезапуск дрона", + "tr": "Kamera hatası. Hava aracının yeniden başlatılması önerilir", + "zh": "相机异常,建议重启飞行器" + }, + "fpv_tip_0x1C00140F": { + "de": "Die Kameraverbindung ist instabil. Den Gimbal lösen und wieder montieren", + "en": "Camera connection unstable. Detach and remount gimbal", + "es": "La conexión de la cámara es inestable. Retira el estabilizador y vuélvelo a montar", + "fr": "Connexion caméra instable. Détacher et remonter la nacelle", + "ja": "カメラの接続が不安定です。ジンバルを取り付け直してください", + "ko": "카메라 연결이 불안정합니다. 짐벌을 분리했다가 다시 장착하세요", + "ru": "Нестабильное соединение с камерой. Отсоедините и переустановите гиростабилизатор", + "tr": "Kamera bağlantısı güvenilir değil. Gimbalı çıkarın ve yeniden takın", + "zh": "相机信号链路不稳定,请尝试重新拔插云台" + }, + "fpv_tip_0x1C001501": { + "de": "Lichtsensorfehler. DJI Support kontaktieren", + "en": "Light sensor error. Contact DJI Support", + "es": "Error del sensor de luz. Póngase en contacto con la Asistencia técnica de DJI", + "fr": "Erreur du capteur de lumière. Contactez le service client DJI", + "ja": "光センサーエラーです。DJIサポートまでお問い合わせください", + "ko": "광 센서 오류. DJI 고객지원으로 문의하세요", + "ru": "Ошибка датчика освещенности. Свяжитесь со службой поддержки DJI", + "tr": "Işık sensörü hatası. DJI Destek birimiyle iletişime geçin", + "zh": "光照传感器异常,请联系售后服务" + }, + "fpv_tip_0x1C001502": { + "de": "Lichtsensorfehler. DJI Support kontaktieren.", + "en": "Light sensor error. Contact DJI Support", + "es": "Error del sensor de luz. Póngase en contacto con la Asistencia técnica de DJI", + "fr": "Light sensor error. Contact DJI Support", + "ja": "光センサーエラーです。DJIサポートまでお問い合わせください", + "ko": "광 센서 오류. DJI 고객지원으로 문의하세요", + "ru": "Ошибка датчика освещенности. Свяжитесь со службой поддержки DJI", + "tr": "Işık sensörü hatası. DJI Destek birimiyle iletişime geçin", + "zh": "光照传感器异常,请联系售后服务" + }, + "fpv_tip_0x1C001503": { + "de": "Kalibrierungsdaten Lichtsensor fehlerhaft. DJI Support kontaktieren", + "en": "Light sensor calibration data error. Contact DJI Support", + "es": "Error de datos de calibración del sensor de luz. Póngase en contacto con la Asistencia técnica de DJI", + "fr": "Erreur de données de l'étalonnage du capteur de lumière. Contact DJI Support", + "ja": "光センサーキャリブレーションデータエラーです。DJIサポートまでお問い合わせください", + "ko": "광 센서 캘리브레이션 데이터 오류. DJI 고객지원으로 문의하세요", + "ru": "Ошибка данных калибровки датчика освещенности. Свяжитесь со службой поддержки DJI", + "tr": "Işık sensörü kalibrasyonu veri hatası. DJI Destek birimiyle iletişime geçin", + "zh": "光照传感器标定数据异常,请联系售后服务" + }, + "fpv_tip_0x1C001603": { + "de": "DJI PROSSD kann nicht verwendet werden. Speichergerät entfernen und wieder einsetzen", + "en": "Unable to use DJI PROSSD. Remove and insert storage device again", + "es": "No se puede utilizar DJI PROSSD. Retira el dispositivo de almacenamiento e insértalo de nuevo", + "fr": "Impossible d’utiliser DJI PROSSD. Retirer et réinsérer le périphérique de stockage", + "ja": "DJI PROSSDを使用できません。ストレージ機器を取り付け直してください", + "ko": "DJI PROSSD를 사용할 수 없습니다. 저장 장치를 제거했다가 다시 삽입하세요", + "ru": "Использование DJI PROSSD невозможно. Извлеките и повторно вставьте устройство хранения", + "tr": "DJI PROSSD kullanılamıyor. Depolama cihazını çıkarın ve yeniden takın", + "zh": "DJI PROSSD存储不可挂载,请重新拔插" + }, + "fpv_tip_0x1C001604": { + "ar": "", + "de": "Keine Speicherkarte", + "en": "No memory card", + "es": "No hay tarjeta de memoria", + "fr": "Aucune carte mémoire", + "it": "", + "ja": "メモリーカードがありません", + "ko": "메모리 카드 없음", + "pt": "", + "ru": "Нет карты памяти", + "tr": "Hafıza kartı yok", + "zh": "无存储卡" + }, + "fpv_tip_0x1C001605": { + "ar": "", + "de": "SSD-Dateisystemfehler. SSD entnehmen und wieder einsetzen. SSD-Dateien sichern und SSD-Karte dann formatieren, wenn das Problem weiterhin besteht", + "en": "SSD file system error. Remove and insert SSD again. Back up SSD files and then format SSD card if issue persists", + "es": "Error del sistema de archivos SSD. Retire el SSD e insértalo de nuevo. Haga una copia de seguridad de los archivos SSD y luego formatee la tarjeta SSD si el problema continúa", + "fr": "Erreur système du fichier SSD. Retirer et réinsérer le SSD. Sauvegardez les fichiers SSD, puis formatez la carte SSD si le problème persiste", + "id": "", + "it": "", + "ja": "SSDのファイルシステムエラー。SSDを取り外し、挿入し直してください。問題が解決しない場合は、SSDのファイルをバックアップしてから、SSDカードをフォーマットしてください", + "ko": "SSD 파일 시스템 오류. SSD를 제거했다가 다시 삽입하세요. 문제가 지속되면 SSD 파일을 백업한 SSD 카드를 포맷하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Ошибка файловой системы SSD. Извлеките и снова вставьте SSD. Сделайте резервную копию файлов SSD, а затем отформатируйте карту SSD, если проблема не устранена", + "th": "", + "tr": "SSD dosya sistemi hatası. SSD'yi çıkarın ve tekrar takın. SSD dosyalarını yedekleyin ve ardından sorun devam ederse SSD kartı biçimlendirin", + "ug": "", + "vi": "", + "zh": "SSD文件系统异常,请重新拔插SSD,若无效请备份后格式化", + "zh-Hant": "" + }, + "fpv_tip_0x1C001606": { + "ar": "", + "de": "DJI PROSSD nicht formatiert", + "en": "DJI PROSSD not formatted", + "es": "DJI PROSSD no formateado", + "fr": "DJI PROSSD non formaté", + "it": "", + "ja": "DJI PROSSDがフォーマットされていません", + "ko": "DJI PROSSD가 포맷되지 않은 상태입니다", + "pt": "", + "ru": "DJI PROSSD не отформатирован", + "tr": "DJI PROSSD biçimlendirilmemiş", + "zh": "DJI PROSSD存储未格式化" + }, + "fpv_tip_0x1C001607": { + "ar": "", + "de": "DJI PROSSD wird formatiert...", + "en": "Formatting DJI PROSSD...", + "es": "Formateando DJI PROSSD...", + "fr": "Formatage DJI PROSSD en cours...", + "it": "", + "ja": "DJI PROSSDのフォーマット中...", + "ko": "DJI PROSSD 포맷 중...", + "pt": "", + "ru": "Выполняется форматирование DJI PROSSD...", + "tr": "DJI PROSSD biçimlendiriliyor...", + "zh": "DJI PROSSD正在格式化" + }, + "fpv_tip_0x1C001608": { + "ar": "", + "de": "DJI PROSSD-Dateisystemformat nicht unterstützt", + "en": "DJI PROSSD file system format not supported", + "es": "Formato del sistema de archivos de DJI PROSSD no compatible", + "fr": "Format de système de fichiers DJI PROSSD non pris en charge", + "it": "", + "ja": "DJI PROSSDのファイルシステム形式には対応していません", + "ko": "DJI PROSSD 파일 시스템 포맷이 지원되지 않습니다", + "pt": "", + "ru": "Формат файловой системы DJI PROSSD не поддерживается", + "tr": "DJI PROSSD dosya sistemi biçimi desteklenmiyor.", + "zh": "DJI PROSSD文件系统不支持" + }, + "fpv_tip_0x1C001609": { + "ar": "", + "de": "DJI PROSSD wird aktualisiert...", + "en": "Refreshing DJI PROSSD...", + "es": "Actualizando DJI PROSSD...", + "fr": "Actualisation de DJI PROSSD...", + "it": "", + "ja": "DJI PROSSDの更新中...", + "ko": "DJI PROSSD 새로고침 중...", + "pt": "", + "ru": "Выполняется обновление DJI PROSSD...", + "tr": "DJI PROSSD yenileniyor...", + "zh": "DJI PROSSD正在刷新" + }, + "fpv_tip_0x1C00160A": { + "de": "DJI PROSSD voll", + "en": "DJI PROSSD full", + "es": "DJI PROSSD lleno", + "fr": "DJI PROSSD plein", + "ja": "DJI PROSSDが満杯です", + "ko": "DJI PROSSD에 공간이 없습니다", + "ru": "DJI PROSSD заполнен", + "tr": "DJI PROSSD dolu", + "zh": "DJI PROSSD存储空间已满" + }, + "fpv_tip_0x1C00160B": { + "de": "DJI PROSSD-Dateibenennungsindex voll. Zusätzliche Dateien löschen", + "en": "DJI PROSSD file naming index full. Delete extra files", + "es": "Índice de nomenclatura de archivo DJI PROSSD completo. Elimina los archivos adicionales", + "fr": "Index de nommage des fichiers DJI PROSSD plein. Supprimer les fichiers excédentaires", + "ja": "DJI PROSSDのファイルネーミングインデックスが満杯です。余分なファイルを削除してください", + "ko": "DJI PROSSD 파일 이름 지정 인덱스에 공간이 없습니다. 불필요한 파일을 삭제하세요", + "ru": "Индекс имен файлов DJI PROSSD заполнен. Удалите лишние файлы", + "tr": "DJI PROSSD adlandırma dizini dolu. Fazla dosyaları sil", + "zh": "DJI PROSSD文件序号溢出,请删除多余素材" + }, + "fpv_tip_0x1C00160C": { + "de": "DJI PROSSD wird initialisiert...", + "en": "Initializing DJI PROSSD…", + "es": "Inicializando DJI PROSSD...", + "fr": "Initialisation de DJI PROSSD…", + "ja": "DJI PROSSDの初期化中...", + "ko": "DJI PROSSD 초기화 중…", + "ru": "Инициализация DJI PROSSD…", + "tr": "DJI PROSSD başlatılıyor…", + "zh": "DJI PROSSD正在初始化" + }, + "fpv_tip_0x1C00160D": { + "de": "Neuformatierung von DJI PROSSD empfohlen", + "en": "Reformatting DJI PROSSD recommended", + "es": "Se recomienda volver a formatear DJI PROSSD", + "fr": "Reformatage de DJI PROSSD recommandé", + "ja": "DJI PROSSDの再フォーマットをお勧めします", + "ko": "DJI PROSSD 재포맷 권장", + "ru": "Рекомендуется переформатировать DJI PROSSD", + "tr": "DJI PROSSD'nin yeniden biçimlendirilmesi önerilir", + "zh": "DJI PROSSD建议重新格式化" + }, + "fpv_tip_0x1C00160E": { + "de": "Dateien auf DJI PROSSD werden wiederhergestellt...", + "en": "Restoring files on DJI PROSSD...", + "es": "Restaurando archivos en DJI PROSSD...", + "fr": "Restauration des fichiers sur DJI PROSSD...", + "ja": "DJI PROSSDのファイルの復元中...", + "ko": "DJI PROSSD 파일 복구 중...", + "ru": "Восстановление файлов на DJI PROSSD...", + "tr": "DJI PROSSD'deki dosyalar geri yükleniyor...", + "zh": "DJI PROSSD存储文件正在修复中" + }, + "fpv_tip_0x1C00160F": { + "de": "Niedrige DJI PROSSD-Geschwindigkeit. Austausch des Speichergeräts empfohlen", + "en": "DJI PROSSD speed low. Replacing storage device recommended", + "es": "Baja velocidad en DJI PROSSD. Se recomienda sustituir el dispositivo de almacenamiento", + "fr": "Vitesse de DJI PROSSD faible. Remplacement du périphérique de stockage recommandé", + "ja": "DJI PROSSDの速度が遅くなっています。ストレージ機器の交換をお勧めします", + "ko": "DJI PROSSD 속도가 낮습니다. 저장 장치 교체를 권장합니다", + "ru": "Низкая скорость DJI PROSSD. Рекомендуется замена устройства хранения", + "tr": "DJI PROSSD hızı düşük. Depolama cihazının yenilenmesi önerilir", + "zh": "DJI PROSSD存储速度慢,建议更换" + }, + "fpv_tip_0x1C001701": { + "de": "Zeitauslöserintervall zu kurz. Aufnahmen können nicht gestartet werden.", + "en": "Timed shot interval too short. Unable to start shooting", + "es": "Intervalo de foto con temporizador demasiado corto. No puede empezar a disparar", + "fr": "Intervalle de prise de vue trop court. Impossible de lancer la prise de vue", + "ja": "タイマー撮影の間隔が短すぎます。撮影を開始できません", + "ko": "인터벌 타이머 인터벌이 너무 짧습니다. 촬영을 시작할 수 없습니다", + "ru": "Интервал слишком короткий. Не удается начать съемку", + "tr": "Zamanlanmış çekim aralığı çok kısa. Çekim başlatılamıyor", + "zh": "定时拍间隔过小,无法开始拍摄" + }, + "fpv_tip_0x1C001702": { + "de": "Zeitauslöserintervall zu kurz. Kameras können nicht umgeschaltet werden.", + "en": "Timed shot interval too short. Unable to switch cameras", + "es": "Intervalo de foto con temporizador demasiado corto. No se puede cambiar de cámara", + "fr": "Intervalle de prise de vue trop court. Impossible de basculer entre les caméras", + "ja": "タイマー撮影の間隔が短すぎます。カメラの切り替えができません", + "ko": "인터벌 타이머 인터벌이 너무 짧습니다. 카메라 전환 불가", + "ru": "Интервал слишком короткий. Не удается переключиться между камерами", + "tr": "Zamanlanmış çekim aralığı çok kısa. Kameralar arasında geçiş yapılamıyor", + "zh": "定时拍间隔过小,无法切换相机" + }, + "fpv_tip_0x1C001703": { + "de": "Fotoformat stimmt nicht überein. Kameras können nicht umgeschaltet werden.", + "en": "Photo format inconsistent. Unable to switch cameras", + "es": "Formato de foto incoherente. No se puede cambiar de cámara", + "fr": "Format de photo incohérent. Impossible de basculer entre les caméras", + "ja": "写真フォーマットが一致しません。カメラの切り替えができません", + "ko": "사진 형식이 일치하지 않습니다. 카메라 전환 불가", + "ru": "Несоответствие формата фото. Не удается переключиться между камерами", + "tr": "Fotoğraf biçimi uyumsuz. Kameralar arasında geçiş yapılamıyor", + "zh": "照片格式不同,无法切换相机" + }, + "fpv_tip_0x1C001801": { + "de": "Zeitcodefehler. Fluggerät neu starten", + "en": "Timecode error. Restart aircraft", + "es": "Error de código de tiempo. Reinicia la aeronave", + "fr": "Erreur de code temporel. Redémarrer l’appareil", + "ja": "タイムコードエラー。機体を再起動してください", + "ko": "타임코드 오류. 기체를 재시작하세요", + "ru": "Ошибка кода времени. Перезапустите дрон", + "tr": "Zaman kodu hatası. Hava aracını yeniden başlatın", + "zh": "TIMECODE错误,请重启飞行器" + }, + "fpv_tip_0x1C001901": { + "ar": "", + "de": "ProRes-RAW-Codec nicht autorisiert", + "en": "ProRes RAW codec not authorized,purchase on the official website", + "es": "Códec ProRes RAW no autorizado", + "fr": "Codec ProRes RAW non autorisé", + "id": "", + "it": "", + "ja": "ProRes RAWコーデックが承認されていません", + "ko": "ProRes RAW 코덱이 승인되지 않았습니다", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Кодек ProRes RAW не авторизован", + "th": "", + "tr": "ProRes RAW kodeği yetkilendirilmedi", + "ug": "", + "vi": "", + "zh": "ProRes RAW编码格式未授权,请到官网购买使用授权", + "zh-Hant": "" + }, + "fpv_tip_0x1C001902": { + "ar": "", + "de": "Kompressionsverfahren CinemaDNG nicht zugelassen. Lizenz auf der offiziellen Website erwerben", + "en": "CinemaDNG encoding format not authorized. Purchase license from official website", + "es": "Formato de codificación CinemaDNG no autorizado. Comprar licencia desde el sitio web oficial", + "fr": "Format d'encodage CinemaDNG non autorisé. Achetez une licence sur le site officiel", + "id": "", + "it": "", + "ja": "CinemaDNGエンコードフォーマットは未承認です。公式ウェブサイトからライセンスを購入してください", + "ko": "승인되지 않은 CinemaDNG 인코딩 형식. 공식 웹 사이트에서 라이선스를 구매하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Формат кодирования CinemaDNG не авторизован. Приобретите лицензию на официальном сайте", + "th": "", + "tr": "CinemaDNG kodlama formatı yetkilendirilmedi. Resmi web sitesinden lisans satın alın", + "ug": "", + "vi": "", + "zh": "CinemaDNG编码格式未授权,请到官网购买使用授权", + "zh-Hant": "" + }, + "fpv_tip_0x1C001903": { + "ar": "", + "de": "ProRes-RAW-Codec nicht autorisiert", + "en": "ProRes RAW codec not authorized,purchase on the official website", + "es": "Códec ProRes RAW no autorizado", + "fr": "Codec ProRes RAW non autorisé", + "id": "", + "it": "", + "ja": "ProRes RAWコーデックが承認されていません", + "ko": "ProRes RAW 코덱이 승인되지 않았습니다", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Кодек ProRes RAW не авторизован", + "th": "", + "tr": "ProRes RAW kodeği yetkilendirilmedi", + "ug": "", + "vi": "", + "zh": "ProRes RAW编码格式未授权,请到官网购买使用授权", + "zh-Hant": "" + }, + "fpv_tip_0x1C001904": { + "ar": "", + "de": "", + "en": "CinemaDNG encoding format not authorized,purchase on the official website", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "CinemaDNG编码格式未授权,请到官网购买使用授权", + "zh-Hant": "" + }, + "fpv_tip_0x1C001A01": { + "de": "Niedrige DJI PROSSD-Schreibgeschwindigkeit. Neustart des Fluggeräts empfohlen", + "en": "DJI PROSSD write speed low. Restarting aircraft recommended", + "es": "Baja velocidad de escritura en DJI PROSSD. Se recomienda reiniciar la aeronave", + "fr": "Vitesse d’écriture DJI PROSSD faible. Redémarrage de l’appareil recommandé", + "ja": "DJI PROSSDの書き込みが低速です。機体の再起動をお勧めします", + "ko": "DJI PROSSD 쓰기 속도가 낮습니다. 기체 재시작을 권장합니다", + "ru": "Низкая скорость записи DJI PROSSD. Рекомендуется перезапуск дрона", + "tr": "DJI PROSSD yazma hızı düşük. Hava aracının yeniden başlatılması önerilir", + "zh": "DJI PROSSD写入速度慢,建议重新启动飞行器" + }, + "fpv_tip_0x1C001B01": { + "de": "Nutzungshäufigkeit Gimbal-Anschluss erreicht", + "en": "Usage count of gimbal port reached", + "es": "Se ha alcanzado el recuento de usos del puerto del estabilizador", + "fr": "Nombre d'utilisations du port de nacelle atteint", + "ja": "ジンバルポートの使用回数に達しました", + "ko": "짐벌 포트 사용 횟수 한도에 도달했습니다", + "ru": "Достигнуто количество использований порта гиростабилизатора", + "tr": "Gimbal bağlantı noktası kullanım sayısına ulaşıldı", + "zh": "云台接口已达预设使用次数" + }, + "fpv_tip_0x1C001E04": { + "en": "System busy. Photo is not allowed", + "zh": "系统业务繁忙,禁止拍照" + }, + "fpv_tip_0x1C001E05": { + "en": "System not busy.Photo available", + "zh": "业务繁忙解除,允许拍照" + }, + "fpv_tip_0x1C001F01": { + "en": "System busy. Zoom is not available", + "zh": "系统业务繁忙,禁止变焦" + }, + "fpv_tip_0x1C001F02": { + "en": "System not busy. Zoom available", + "zh": "业务繁忙解除,允许变焦" + }, + "fpv_tip_0x1C002001": { + "de": "Zeitüberschreitung der Radardaten empfangenen Kamera. Neustart des Fluggeräts versuchen", + "en": "Camera receiving radar data timed out. Try restarting aircraft", + "es": "Se agotó el tiempo de espera de recepción de datos del radar de la cámara. Intente reiniciar la aeronave", + "fr": "La caméra recevant les données du radar a expiré. Essayez de redémarrer l'appareil", + "ja": "カメラのレーダーデータ受信がタイムアウトになりました。機体を再起動してみてください", + "ko": "카메라 수신 레이더 데이터가 시간 초과되었습니다. 기체를 재시작해보세요", + "ru": "Время приема данных радара камерой истекло. Попробуйте перезапустить дрон", + "tr": "Radar verilerini alan kamera zaman aşımına uğradı. Hava aracını yeniden başlatmayı deneyin", + "zh": "系统业务繁忙,禁止切换相机" + }, + "fpv_tip_0x1C002002": { + "de": "Punktwolkendaten-Frames gedroppt. Das endgültige Punktwolkenmodell ist möglicherweise nicht vollständig. Fluggerät neu starten", + "en": "Point cloud data frames dropped. The ultimate point cloud model may not be complete. Restart aircraft", + "es": "Se eliminaron los fotogramas de datos de la nube de puntos. Es posible que el modelo de nube de puntos definitivo no esté completo. Reinicie la aeronave", + "fr": "Les trames de données des nuages de points ont été supprimées. Le modèle ultime des nuages de points n’est peut-être pas complet. Redémarrez l’appareil", + "ja": "点群データフレームがドロップしました。最終的な点群モデルが完成していない可能性があります。機体を再起動してください", + "ko": "포인트 클라우드 데이터 프레임이 삭제되었습니다. 포인트 클라우드 모델 결과물이 완전하지 않을 수 있습니다. 기체를 재시작하세요", + "ru": "Пропущены кадры данных облака точек. Окончательная модель облака точек может быть неполной. Перезапустите дрон", + "tr": "Nokta bulutu veri çerçeveleri düştü. Nihai nokta bulutu modeli tam olmayabilir. Hava aracını yeniden başlatın", + "zh": "业务繁忙解除,允许切换相机" + }, + "fpv_tip_0x1C002004": { + "de": "", + "en": "", + "es": "", + "fr": "Erreur du processeur de transmission d'images du capteur de la caméra H20", + "ja": "", + "ko": "", + "ru": "", + "tr": "", + "zh": "H20 相机图像传感器 芯片异常" + }, + "fpv_tip_0x1C002101": { + "ar": "", + "de": "Zeitüberschreitung der Radardaten empfangenen Kamera. Neustart des Fluggeräts versuchen", + "en": "Camera receiving radar data timed out. Try restarting aircraft", + "es": "Se agotó el tiempo de espera de recepción de datos del radar de la cámara. Intente reiniciar la aeronave", + "fr": "La caméra recevant les données du radar a expiré. Essayez de redémarrer l'appareil", + "id": "", + "it": "", + "ja": "カメラのレーダーデータ受信がタイムアウトになりました。機体を再起動してみてください", + "ko": "카메라 수신 레이더 데이터가 시간 초과되었습니다. 기체를 재시작해보세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Время приема данных радара камерой истекло. Попробуйте перезапустить дрон", + "th": "", + "tr": "Radar verilerini alan kamera zaman aşımına uğradı. Hava aracını yeniden başlatmayı deneyin", + "ug": "", + "vi": "", + "zh": "相机接收雷达数据超时,请尝试重启飞行器", + "zh-Hant": "" + }, + "fpv_tip_0x1C002102": { + "ar": "", + "de": "Punktwolkendaten-Frames gedroppt. Das endgültige Punktwolkenmodell ist möglicherweise nicht vollständig. Fluggerät neu starten", + "en": "Point cloud data frames dropped. The ultimate point cloud model may not be complete. Restart aircraft", + "es": "Se eliminaron los fotogramas de datos de la nube de puntos. Es posible que el modelo de nube de puntos definitivo no esté completo. Reinicie la aeronave", + "fr": "Les trames de données des nuages de points ont été supprimées. Le modèle ultime des nuages de points n’est peut-être pas complet. Redémarrez l’appareil", + "id": "", + "it": "", + "ja": "点群データフレームがドロップしました。最終的な点群モデルが完成していない可能性があります。機体を再起動してください", + "ko": "포인트 클라우드 데이터 프레임이 삭제되었습니다. 포인트 클라우드 모델 결과물이 완전하지 않을 수 있습니다. 기체를 재시작하세요", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Пропущены кадры данных облака точек. Окончательная модель облака точек может быть неполной. Перезапустите дрон", + "th": "", + "tr": "Nokta bulutu veri çerçeveleri düştü. Nihai nokta bulutu modeli tam olmayabilir. Hava aracını yeniden başlatın", + "ug": "", + "vi": "", + "zh": "点云数据丢帧,最终点云模型可能不完整,请重启飞行器", + "zh-Hant": "" + }, + "fpv_tip_0x1C002103": { + "de": "Das Radar ist möglicherweise blockiert oder außerhalb des Messbereichs", + "en": "Radar may be blocked or out of measuring range", + "es": "El radar puede estar bloqueado o fuera del rango de medición", + "fr": "Le radar est peut-être bloqué ou hors de la plage de mesure", + "ja": "レーダーがブロックされているか、測定範囲外にある可能性があります", + "ko": "레이더가 차단되었거나 측정 범위를 벗어났습니다.", + "ru": "Возможно, радар заблокирован или вне диапазона измерения", + "tr": "Radar engellenmiş veya ölçüm aralığının dışında olabilir", + "zh": "雷达可能被遮挡,或者不在量程内" + }, + "fpv_tip_0x1C003001": { + "de": "", + "en": "", + "es": "", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "", + "ko": "", + "ru": "", + "tr": "", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C004001": { + "de": "Ungültige Speicherkarte. Karte austauschen.", + "en": "Invalid memory card. Replace card", + "es": "Tarjeta de memoria no válida. Cambie la tarjeta", + "fr": "Carte mémoire non valide. Remplacez la carte", + "ja": "メモリーカードが無効です。 メモリーカードを交換してください", + "ko": "잘못된 메모리 카드입니다. 카드를 교체하세요", + "ru": "Недопустимая карта памяти. Замените карту", + "tr": "Geçersiz hafıza kartı. Kartı değiştirin", + "zh": "无效存储卡,请更换存储卡" + }, + "fpv_tip_0x1C004002": { + "de": "Niedrige Speicherkartengeschwindigkeit. Durch schnellere Karte austauschen.", + "en": "Memory card speed low. Replace with faster card", + "es": "Velocidad baja de la tarjeta de memoria. Cambie la tarjeta por una más rápida", + "fr": "Vitesse de la carte mémoire lente. Remplacez-la par une carte plus rapide", + "ja": "メモリーカードが低速です。 より高速のカードと交換してください", + "ko": "메모리 카드 속도 느림. 더 빠른 카드로 교체하세요", + "ru": "Низкая скорость карты памяти. Замените карту на более быструю", + "tr": "Hafıza kartının hızı yavaş. Daha hızlı bir hafıza kartı ile değiştirin", + "zh": "存储卡为慢速卡,请更换快速存储卡" + }, + "fpv_tip_0x1C004003": { + "de": "Speicherkartenfehler. Karte austauschen.", + "en": "Memory card error. Replace card", + "es": "Error de la tarjeta de memoria. Cambie la tarjeta", + "fr": "Erreur de carte mémoire. Remplacez la carte", + "ja": "メモリーカードにエラーが発生しました。 メモリーカードを交換してください", + "ko": "메모리 카드 오류. 카드를 교체하세요", + "ru": "Ошибка карты памяти. Замените карту", + "tr": "Hafıza kartı hatası. Kartı değiştirin", + "zh": "存储卡异常,请更换存储卡" + }, + "fpv_tip_0x1C004004": { + "de": "Keine Speicherkarte", + "en": "No memory card", + "es": "No hay tarjeta de memoria", + "fr": "Aucune carte mémoire", + "ja": "メモリーカードがありません", + "ko": "메모리 카드 없음", + "ru": "Нет карты памяти", + "tr": "Hafıza kartı yok", + "zh": "无存储卡" + }, + "fpv_tip_0x1C100001": { + "de": "Kamera %component_index überhitzt. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera %component_index overheated. Wait for temperature to return to normal before use", + "es": "Cámara %component_index sobrecalentada. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Surchauffe du %component_index de la caméra. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラ %component_index 高温。常温に戻るまで待ってからご使用ください", + "ko": "카메라 %component_index 과열. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요", + "ru": "Камера %component_index перегрелась. Перед использованием подождите, пока температура не вернется в норму", + "tr": "Kamera %component_index aşırı ısındı. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "%component_index号云台相机过热,请等待降温后再使用" + }, + "fpv_tip_0x1C100101": { + "de": "Fehler: Kamera %component_index. Kamera neu starten", + "en": "Camera %component_index error. Restart camera", + "es": "Error de la cámara %component_index. Reinicia la cámara", + "fr": "Erreur de %component_index de la caméra. Redémarrez la caméra", + "ja": "カメラ%component_indexエラー。カメラを再起動してください", + "ko": "카메라 %component_index 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка камеры %component_index. Перезагрузите камеру", + "tr": "Kamera %component_index hatası. Kamerayı yeniden başlatın", + "zh": "%component_index号云台相机异常,请重启相机" + }, + "fpv_tip_0x1C100102": { + "de": "Fehler: Kamera %component_index. Kamera neu starten", + "en": "Camera %component_index error. Restart camera", + "es": "Error de la cámara %component_index. Reinicia la cámara", + "fr": "Erreur de %component_index de la caméra. Redémarrez la caméra", + "ja": "カメラ%component_indexエラー。カメラを再起動してください", + "ko": "카메라 %component_index 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка камеры %component_index. Перезагрузите камеру", + "tr": "Kamera %component_index hatası. Kamerayı yeniden başlatın", + "zh": "%component_index号云台相机异常,请重启相机" + }, + "fpv_tip_0x1C100103": { + "de": "Hohe Temperatur des Kameraprozessors. Fluggerät ausschalten und vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature high. Power off aircraft and wait for temperature to return to normal before use", + "es": "Temperatura alta del procesador de la cámara. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra élevée. Éteignez l'appareil et attendez que sa température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高い。機体の電源を切り、通常の温度に戻ってからご使用ください", + "ko": "카메라 프로세서 온도 높음. 사용 전에 기체의 전원을 끄고 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Высокая температура процессора камеры. Перед использованием выключите питание дрона и дождитесь, пока температура опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı yüksek. Aracı kapatın ve kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度高,请关闭飞机,等待冷却后再使用" + }, + "fpv_tip_0x1C100103_in_the_sky": { + "de": "Hohe Temperatur des Kameraprozessors. Umgehend zum Startpunkt zurückkehren oder landen. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature high. Return to home or land promptly. Wait for temperature to return to normal before use", + "es": "Temperatura alta del procesador de la cámara. Regresa al punto de origen o aterriza rápidamente. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra élevée. Retournez au point de départ ou atterrissez rapidement. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高い。直ちに帰還するか、着陸してください。常温に戻るまで待ってからご使用ください", + "ko": "카메라 프로세서 온도 높음. 즉시 리턴 투 홈 또는 착륙 필요. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Высокая температура процессора камеры. Как можно скорее вернитесь на базу или приземлитесь. Перед использованием подождите, пока температура не опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı yüksek. Ana konuma geri dönün veya derhal iniş yapın. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度高,请尽快返航或降落,等待冷却后重启使用" + }, + "fpv_tip_0x1C100104": { + "de": "Temperatur des Kameraprozessors zu hoch. Fluggerät ausschalten und vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature too high. Power off aircraft and wait for temperature to return to normal before use", + "es": "Temperatura demasiado alta del procesador de la cámara. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra trop élevée. Éteignez l'appareil et attendez que sa température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高すぎる。機体の電源を切り、通常の温度に戻ってからご使用ください", + "ko": "카메라 프로세서 온도 너무 높음. 사용 전에 기체의 전원을 끄고 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Чрезмерно высокая температура процессора камеры. Перед использованием выключите питание дрона и дождитесь, пока температура опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı çok yüksek. Aracı kapatın ve kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请关闭飞机,等待冷却后再使用" + }, + "fpv_tip_0x1C100104_in_the_sky": { + "de": "Temperatur des Kameraprozessors zu hoch. Umgehend zum Startpunkt zurückkehren oder landen. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature too high. Return to home or land promptly. Wait for temperature to return to normal before use", + "es": "Temperatura demasiado alta del procesador de la cámara. Regresa al punto de origen o aterriza rápidamente. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra trop élevée. Retournez au point de départ ou atterrissez rapidement. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高すぎる。直ちに帰還するか、着陸してください。常温に戻るまで待ってからご使用ください", + "ko": "카메라 프로세서 온도 너무 높음. 즉시 리턴 투 홈 또는 착륙 필요. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Чрезмерно высокая температура процессора камеры. Как можно скорее вернитесь на базу или приземлитесь. Перед использованием подождите, пока температура не опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı çok yüksek. Ana konuma geri dönün veya derhal iniş yapın. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请尽快返航或降落,等待冷却后重启使用" + }, + "fpv_tip_0x1C100105": { + "de": "Fehler: Kamera %component_index. Kamera neu starten", + "en": "Camera %component_index error. Restart camera", + "es": "Error de la cámara %component_index. Reinicia la cámara", + "fr": "Erreur de %component_index de la caméra. Redémarrez la caméra", + "ja": "カメラ%component_indexエラー。カメラを再起動してください", + "ko": "카메라 %component_index 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка камеры %component_index. Перезагрузите камеру", + "tr": "Kamera %component_index hatası. Kamerayı yeniden başlatın", + "zh": "%component_index号云台相机异常,请重启相机" + }, + "fpv_tip_0x1C100201": { + "de": "Fehler: Prozessor für den Bildsensor der H20 Kamera", + "en": "H20 camera image transmission sensor processor error", + "es": "Error del procesador del sensor de imagen de la cámara H20", + "fr": "Erreur du processeur du capteur de transmission d\\'images de la caméra H20", + "ja": "H20 カメラ映像伝送センサープロセッサーエラー", + "ko": "H20 카메라 이미지 전송 센서 프로세서 오류", + "ru": "Ошибка процессора датчика передачи изображения камеры H20", + "tr": "H20 kamera görüntüsü iletim sensörü işlemcisi hatası", + "zh": "H20 相机图像传感器 芯片异常" + }, + "fpv_tip_0x1C100202": { + "de": "Fehler: Prozessor für den Bildsensor der H20 Kamera", + "en": "H20 camera image transmission sensor processor error", + "es": "Error del procesador del sensor de imagen de la cámara H20", + "fr": "Erreur du processeur du capteur de transmission d\\'images de la caméra H20", + "ja": "H20 カメラ映像伝送センサープロセッサーエラー", + "ko": "H20 카메라 이미지 전송 센서 프로세서 오류", + "ru": "Ошибка процессора датчика передачи изображения камеры H20", + "tr": "H20 kamera görüntüsü iletim sensörü işlemcisi hatası", + "zh": "H20 相机图像传感器 芯片异常" + }, + "fpv_tip_0x1C100203": { + "de": "Kamerachip überhitzt. Fluggerät ausschalten und vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera chip overheated. Power off aircraft and wait for temperature to return to normal before use", + "es": "Chip de la cámara sobrecalentado. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Surchauffe de la puce de la caméra. Éteignez l'appareil et attendez que sa température revienne à la normale avant utilisation", + "ja": "カメラチップ高温。機体の電源を切り、通常の温度に戻ってからご使用ください", + "ko": "카메라 칩 과열. 사용 전에 기체의 전원을 끄고 온도가 정상으로 돌아올 때까지 기다리세요", + "ru": "Чип камеры перегрелся. Выключите питание дрона и дождитесь возвращения температуры к нормальным значениям перед использованием", + "tr": "Kamera çipi aşırı ısındı. Aracı kapatın ve kullanmadan sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请关闭飞机,等待冷却后再使用" + }, + "fpv_tip_0x1C100203_in_the_sky": { + "de": "Kameraprozessor überhitzt. Umgehend zum Startpunkt zurückkehren oder landen. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor overheated. Return to home or land promptly. Wait for temperature to return to normal before use", + "es": "Procesador de la cámara sobrecalentado. Regresa al punto de origen o aterriza rápidamente. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Surchauffe du processeur de la caméra. Retournez au point de départ ou atterrissez rapidement. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラプロセッサー高温。直ちにホームに戻るか、着陸してください。常温に戻るまで待ってからご使用ください", + "ko": "카메라 프로세서 과열. 즉시 리턴 투 홈 진행 또는 착륙 필요. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요", + "ru": "Перегрев процессора камеры. Немедленно вернитесь в исходное положение и приземлитесь. Перед использованием подождите, пока температура не вернется в норму", + "tr": "Kamera işlemcisi aşırı ısındı. Hemen eve dön veya iniş yap. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请尽快返航或降落,等待冷却后重启使用" + }, + "fpv_tip_0x1C100204": { + "de": "Fehler: Prozessor für den Bildsensor der H20 Kamera", + "en": "H20 camera image transmission sensor processor error", + "es": "Error del procesador del sensor de imagen de la cámara H20", + "fr": "Erreur du processeur du capteur de transmission d\\'images de la caméra H20", + "ja": "H20 カメラ映像伝送センサープロセッサーエラー", + "ko": "H20 카메라 이미지 전송 센서 프로세서 오류", + "ru": "Ошибка процессора датчика передачи изображения камеры H20", + "tr": "H20 kamera görüntüsü iletim sensörü işlemcisi hatası", + "zh": "H20 相机图像传感器 芯片异常" + }, + "fpv_tip_0x1C100205": { + "de": "Kalibrierungsfehler des FPV-Objektivs. Objektiv neu kalibrieren und erneut versuchen", + "en": "FPV lens calibration error. Recalibrate lens and try again", + "es": "Error de calibración del objetivo FPV. Vuelve a calibrar el objetivo e inténtalo de nuevo", + "fr": "Erreur d’étalonnage de l’objectif FPV. Réétalonner l’objectif et réessayer", + "ja": "FPVレンズキャリブレーションエラー。レンズを再度キャリブレーションし、やり直してください", + "ko": "FPV 렌즈 캘리브레이션 오류. 렌즈를 재캘리브레이션한 후 다시 시도하세요", + "ru": "Ошибка калибровки объектива FPV. Выполните повторную калибровку объектива и повторите попытку", + "tr": "FPV lens kalibrasyonu hatası. Lensin kalibrasyonunu yeniden yapın ve tekrar deneyin", + "zh": "FPV镜头标定异常,请重新标定" + }, + "fpv_tip_0x1C100301": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C100302": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C100303": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C100304": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C100401": { + "de": "Ungültige Speicherkarte. Karte austauschen.", + "en": "Invalid memory card. Replace card", + "es": "Tarjeta de memoria no válida. Cambie la tarjeta", + "fr": "Carte mémoire non valide. Remplacez la carte", + "ja": "メモリーカードが無効です。 カードを交換してください", + "ko": "잘못된 메모리 카드입니다. 카드를 교체하세요", + "ru": "Недопустимая карта памяти. Замените карту", + "tr": "Geçersiz hafıza kartı. Kartı değiştirin", + "zh": "无效存储卡,请更换存储卡" + }, + "fpv_tip_0x1C100401_index_1": { + "de": "Ungültige eMMC. Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "Invalid eMMC. Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "eMMC non valide. Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "eMMCが無効です。カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "eMMC가 올바르지 않습니다. 카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Сбой eMMC. Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "无效EMMC,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C100402": { + "de": "Niedrige Speicherkartengeschwindigkeit. Durch schnellere Karte austauschen.", + "en": "Memory card speed low. Replace with faster card", + "es": "Velocidad baja de la tarjeta de memoria. Cambie la tarjeta por una más rápida", + "fr": "Vitesse de la carte mémoire lente. Remplacez-la par une carte plus rapide", + "ja": "メモリーカードが低速です。 より高速のカードと交換してください", + "ko": "메모리 카드 속도 느림. 더 빠른 카드로 교체하세요", + "ru": "Низкая скорость карты памяти. Замените карту на более быструю", + "tr": "Hafıza kartının hızı yavaş. Daha hızlı bir hafıza kartı ile değiştirin", + "zh": "存储卡为慢速卡,请更换" + }, + "fpv_tip_0x1C100402_index_1": { + "de": "eMMC-Geschwindigkeitsfehler. Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "eMMC speed error. Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "Erreur de vitesse de l'eMMC. Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "eMMCの速度エラーです。カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "eMMC 속도 오류입니다. 카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Ошибка скорости eMMC. Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "EMMC速度异常,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C100403": { + "de": "Speicherkartenfehler. Karte austauschen.", + "en": "Memory card error. Replace card", + "es": "Error de la tarjeta de memoria. Cambie la tarjeta", + "fr": "Erreur de carte mémoire. Remplacez la carte", + "ja": "メモリーカードにエラーが発生しました。 カードを交換してください", + "ko": "메모리 카드 오류. 카드를 교체하세요", + "ru": "Ошибка карты памяти. Замените карту", + "tr": "Hafıza kartı hatası. Kartı değiştirin", + "zh": "存储卡异常,请更换存储卡" + }, + "fpv_tip_0x1C100403_index_1": { + "de": "eMMC-Fehler. Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "eMMC error. Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "Erreur eMMC. Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "eMMCのエラーです。カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "eMMC 오류입니다. 카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Ошибка eMMC. Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "EMMC异常,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C100404": { + "de": "Keine Speicherkarte", + "en": "No memory card", + "es": "No hay tarjeta de memoria", + "fr": "Aucune carte mémoire", + "ja": "メモリーカードがありません", + "ko": "메모리 카드 없음", + "ru": "Нет карты памяти", + "tr": "Hafıza kartı yok", + "zh": "无存储卡" + }, + "fpv_tip_0x1C100404_index_1": { + "de": "eMMC-Identifikationsfehler. Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "eMMC identification error. Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "Erreur d'identification eMMC. Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "eMMCの認識エラーです。カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "eMMC 식별 오류입니다. 카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Ошибка идентификации eMMC. Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "EMMC识别异常,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C100405": { + "de": "Lese- und Schreibberechtigungen für Speicherkarte bestätigen", + "en": "Confirm memory card read and write permissions", + "es": "Confirme los permisos de lectura y escritura de la tarjeta de memoria", + "fr": "Confirmez les autorisations de lecture et d'écriture de la carte mémoire", + "ja": "メモリーカードの読み取り/書き込み権限を確認してください", + "ko": "메모리 카드 읽기 및 쓰기 권한을 확인하세요", + "ru": "Подтвердите наличие разрешений на чтение и запись карты памяти", + "tr": "Hafıza kartı okuma ve yazma izinlerini onaylayın", + "zh": "请确认存储卡读写属性" + }, + "fpv_tip_0x1C100406": { + "de": "Speicherkarte nicht formatiert. Karte vor Gebrauch formatieren.", + "en": "Memory card not formatted. Format card before use", + "es": "Tarjeta de memoria no formateada. Formatee la tarjeta antes del uso", + "fr": "Carte mémoire non formatée. Formatez la carte avant utilisation", + "ja": "メモリーカードがフォーマットされていません。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드가 포맷되지 않았습니다. 사용 전에 카드를 포맷하세요", + "ru": "Карта памяти не отформатирована. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı biçimlendirilmemiş. Kullanmadan önce kartı biçimlendirin", + "zh": "存储卡未格式化,请格式化后使用" + }, + "fpv_tip_0x1C100407": { + "de": "Speicherkarte wird formatiert...", + "en": "Formatting memory card...", + "es": "Formateando la tarjeta de memoria...", + "fr": "Formatage de la carte mémoire…", + "ja": "メモリーカードのフォーマット中...", + "ko": "메모리 카드 포맷 중...", + "ru": "Форматирование карты памяти...", + "tr": "Hafıza kartı biçimlendiriliyor...", + "zh": "存储卡正在格式化,请等待" + }, + "fpv_tip_0x1C100408": { + "de": "Dateisystem der Speicherkarte wird nicht unterstützt. Karte vor Gebrauch formatieren.", + "en": "Memory card file system not supported. Format card before use", + "es": "Sistema de archivos de la tarjeta de memoria no compatible. Formatee la tarjeta antes del uso", + "fr": "Système de fichiers de la carte mémoire non pris en charge. Formatez la carte avant utilisation", + "ja": "メモリーカードファイルシステムはサポートされていません。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드 파일 시스템이 지원되지 않습니다. 사용 전에 카드를 포맷하세요", + "ru": "Файловая система карты памяти не поддерживается. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı dosya sistemi desteklenmiyor. Kullanmadan önce kartı biçimlendirin", + "zh": "不支持该存储卡文件系统,请格式化后使用" + }, + "fpv_tip_0x1C100409": { + "de": "Speicherkarte wird aktualisiert...", + "en": "Refreshing memory card...", + "es": "Actualizando la tarjeta de memoria...", + "fr": "Actualisation de la carte mémoire…", + "ja": "メモリーカードの更新中...", + "ko": "메모리 카드 새로고침 중...", + "ru": "Обновление карты памяти...", + "tr": "Hafıza kartı yenileniyor...", + "zh": "存储卡正在刷新,请等待" + }, + "fpv_tip_0x1C10040A": { + "de": "Speicherkarte voll. Speicherplatz freigeben.", + "en": "Memory card full. Clear space", + "es": "Tarjeta de memoria llena. Libere espacio", + "fr": "Carte mémoire pleine. Libérez de l'espace", + "ja": "メモリーカードが満杯です。 領域をクリア", + "ko": "메모리 카드 공간 없음. 공간을 확보하세요", + "ru": "Карта памяти заполнена. Освободите место", + "tr": "Hafıza kartı dolu. Yer açın", + "zh": "存储卡已满,请清除内存" + }, + "fpv_tip_0x1C10040B": { + "de": "Max. Dateiindex überschritten. SD-Karte formatieren", + "en": "Max file index exceeded. Format SD card", + "es": "Se ha superado el índice máximo de archivos. Formatear tarjeta SD", + "fr": "Index de fichier max. dépassé. Formater la carte SD", + "ja": "ファイルインデックスの最大値を超えました。SDカードをフォーマット", + "ko": "최대 파일 색인을 초과함. SD 카드 포맷", + "ru": "Превышен максимальный индекс файла. Форматировать карту памяти SD", + "tr": "Maks. dosya dizini aşıldı. SD kartı biçimlendir", + "zh": "文件索引超出最大限制,请格式化SD卡" + }, + "fpv_tip_0x1C10040C": { + "de": "Speicherkarte wird initialisiert...", + "en": "Initializing memory card...", + "es": "Inicializando tarjeta de memoria...", + "fr": "Initialisation de la carte mémoire…", + "ja": "メモリーカードの初期化中...", + "ko": "메모리 카드 초기화 중...", + "ru": "Инициализация карты памяти...", + "tr": "Hafıza kartı başlatılıyor...", + "zh": "存储卡正在初始化,请等待" + }, + "fpv_tip_0x1C10040D": { + "de": "Speicherkartenfehler. Karte vor Gebrauch formatieren.", + "en": "Memory card error. Format card before use", + "es": "Error de la tarjeta de memoria. Formatee la tarjeta antes del uso", + "fr": "Erreur de carte mémoire. Formatez la carte avant utilisation", + "ja": "メモリーカードにエラーが発生しました。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드 오류. 사용 전에 카드를 포맷하세요", + "ru": "Ошибка карты памяти. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı hatası. Kullanmadan önce kartı biçimlendirin", + "zh": "存储卡异常,请格式化存储卡后使用" + }, + "fpv_tip_0x1C10040E": { + "de": "Speicherkarte wird repariert...", + "en": "Fixing memory card...", + "es": "Corrigiendo tarjeta de memoria...", + "fr": "Réparation de la carte mémoire…", + "ja": "メモリーカードの修正中...", + "ko": "메모리 카드 문제 해결 중...", + "ru": "Исправление карты памяти...", + "tr": "Hafıza kartı düzeltiliyor...", + "zh": "存储卡修复中,请等待" + }, + "fpv_tip_0x1C10040F": { + "de": "Niedrige Lese- und Schreibgeschwindigkeit für Speicherkarte. Warten, bis der Vorgang abgeschlossen wurde.", + "en": "Memory card read and write speed low. Wait until process completes", + "es": "Velocidad baja de lectura y escritura de la tarjeta de memoria. Espere hasta que se complete el proceso", + "fr": "Vitesse de lecture et d'écriture de la carte mémoire lente. Attendez que le processus soit terminé", + "ja": "メモリーカード読み取り/書き込みが低速です。 プロセスが完了するまでお待ちください", + "ko": "메모리 카드 읽기 및 쓰기 속도가 느립니다. 프로세스가 완료될 때까지 기다리세요", + "ru": "Низкая скорость чтения и записи карты памяти. Подождите, пока процесс завершится", + "tr": "Hafıza kartının okuma ve yazma hızı düşük. İşlem tamamlanana kadar bekleyin", + "zh": "存储卡读写缓慢,请等待" + }, + "fpv_tip_0x1C200001": { + "de": "Kamera %component_index überhitzt. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera %component_index overheated. Wait for temperature to return to normal before use", + "es": "Cámara %component_index sobrecalentada. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Surchauffe du %component_index de la caméra. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラ %component_index 高温。常温に戻るまで待ってからご使用ください", + "ko": "카메라 %component_index 과열. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요", + "ru": "Камера %component_index перегрелась. Перед использованием подождите, пока температура не вернется в норму", + "tr": "Kamera %component_index aşırı ısındı. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "%component_index号云台相机过热,请等待降温后再使用" + }, + "fpv_tip_0x1C200101": { + "de": "Fehler: Kamera %component_index. Kamera neu starten", + "en": "Camera %component_index error. Restart camera", + "es": "Error de la cámara %component_index. Reinicia la cámara", + "fr": "Erreur de %component_index de la caméra. Redémarrez la caméra", + "ja": "カメラ%component_indexエラー。カメラを再起動してください", + "ko": "카메라 %component_index 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка камеры %component_index. Перезагрузите камеру", + "tr": "Kamera %component_index hatası. Kamerayı yeniden başlatın", + "zh": "%component_index号云台相机异常,请重启相机" + }, + "fpv_tip_0x1C200102": { + "de": "Fehler: Kamera %component_index. Kamera neu starten", + "en": "Camera %component_index error. Restart camera", + "es": "Error de la cámara %component_index. Reinicia la cámara", + "fr": "Erreur de %component_index de la caméra. Redémarrez la caméra", + "ja": "カメラ%component_indexエラー。カメラを再起動してください", + "ko": "카메라 %component_index 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка камеры %component_index. Перезагрузите камеру", + "tr": "Kamera %component_index hatası. Kamerayı yeniden başlatın", + "zh": "%component_index号云台相机异常,请重启相机" + }, + "fpv_tip_0x1C200103": { + "de": "Temperatur des Kameraprozessors zu hoch. Fluggerät ausschalten und vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature too high. Power off aircraft and wait for temperature to return to normal before use", + "es": "Temperatura demasiado alta del procesador de la cámara. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra trop élevée. Éteignez l'appareil et attendez que sa température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高すぎる。機体の電源を切り、通常の温度に戻ってからご使用ください", + "ko": "카메라 프로세서 온도 너무 높음. 사용 전에 기체의 전원을 끄고 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Чрезмерно высокая температура процессора камеры. Перед использованием выключите питание дрона и дождитесь, пока температура опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı çok yüksek. Aracı kapatın ve kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请关闭飞机,等待冷却后再使用" + }, + "fpv_tip_0x1C200103_in_the_sky": { + "de": "Hohe Temperatur des Kameraprozessors. Umgehend zum Startpunkt zurückkehren oder landen. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature high. Return to home or land promptly. Wait for temperature to return to normal before use", + "es": "Temperatura alta del procesador de la cámara. Regresa al punto de origen o aterriza rápidamente. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra élevée. Retournez au point de départ ou atterrissez rapidement. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高い。直ちに帰還するか、着陸してください。常温に戻るまで待ってからご使用ください", + "ko": "카메라 프로세서 온도 높음. 즉시 리턴 투 홈 또는 착륙 필요. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Высокая температура процессора камеры. Как можно скорее вернитесь на базу или приземлитесь. Перед использованием подождите, пока температура не опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı yüksek. Ana konuma geri dönün veya derhal iniş yapın. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度高,请尽快返航或降落,等待冷却后重启使用" + }, + "fpv_tip_0x1C200104": { + "de": "Temperatur des Kameraprozessors zu hoch. Fluggerät ausschalten und vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature too high. Power off aircraft and wait for temperature to return to normal before use", + "es": "Temperatura demasiado alta del procesador de la cámara. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra trop élevée. Éteignez l'appareil et attendez que sa température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高すぎる。機体の電源を切り、通常の温度に戻ってからご使用ください", + "ko": "카메라 프로세서 온도 너무 높음. 사용 전에 기체의 전원을 끄고 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Чрезмерно высокая температура процессора камеры. Перед использованием выключите питание дрона и дождитесь, пока температура опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı çok yüksek. Aracı kapatın ve kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请关闭飞机,等待冷却后再使用" + }, + "fpv_tip_0x1C200104_in_the_sky": { + "de": "Temperatur des Kameraprozessors zu hoch. Umgehend zum Startpunkt zurückkehren oder landen. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature too high. Return to home or land promptly. Wait for temperature to return to normal before use", + "es": "Temperatura demasiado alta del procesador de la cámara. Regresa al punto de origen o aterriza rápidamente. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra trop élevée. Retournez au point de départ ou atterrissez rapidement. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高すぎる。直ちに帰還するか、着陸してください。常温に戻るまで待ってからご使用ください", + "ko": "카메라 프로세서 온도 너무 높음. 즉시 리턴 투 홈 또는 착륙 필요. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Чрезмерно высокая температура процессора камеры. Как можно скорее вернитесь на базу или приземлитесь. Перед использованием подождите, пока температура не опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı çok yüksek. Ana konuma geri dönün veya derhal iniş yapın. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请尽快返航或降落,等待冷却后重启使用" + }, + "fpv_tip_0x1C200105": { + "de": "Fehler: Kamera %component_index. Kamera neu starten", + "en": "Camera %component_index error. Restart camera", + "es": "Error de la cámara %component_index. Reinicia la cámara", + "fr": "Erreur de %component_index de la caméra. Redémarrez la caméra", + "ja": "カメラ%component_indexエラー。カメラを再起動してください", + "ko": "카메라 %component_index 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка камеры %component_index. Перезагрузите камеру", + "tr": "Kamera %component_index hatası. Kamerayı yeniden başlatın", + "zh": "%component_index号云台相机异常,请重启相机" + }, + "fpv_tip_0x1C200201": { + "de": "Fehler: Kamera %component_index. Kamera neu starten", + "en": "Camera %component_index error. Restart camera", + "es": "Error de la cámara %component_index. Reinicia la cámara", + "fr": "Erreur de %component_index de la caméra. Redémarrez la caméra", + "ja": "カメラ%component_indexエラー。カメラを再起動してください", + "ko": "카메라 %component_index 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка камеры %component_index. Перезагрузите камеру", + "tr": "Kamera %component_index hatası. Kamerayı yeniden başlatın", + "zh": "%component_index号云台相机异常,请重启相机" + }, + "fpv_tip_0x1C200202": { + "de": "Fehler: Kamera %component_index. Kamera neu starten", + "en": "Camera %component_index error. Restart camera", + "es": "Error de la cámara %component_index. Reinicia la cámara", + "fr": "Erreur de %component_index de la caméra. Redémarrez la caméra", + "ja": "カメラ%component_indexエラー。カメラを再起動してください", + "ko": "카메라 %component_index 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка камеры %component_index. Перезагрузите камеру", + "tr": "Kamera %component_index hatası. Kamerayı yeniden başlatın", + "zh": "%component_index号云台相机异常,请重启相机" + }, + "fpv_tip_0x1C200203": { + "de": "Kamerachip überhitzt. Fluggerät ausschalten und vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera chip overheated. Power off aircraft and wait for temperature to return to normal before use", + "es": "Chip de la cámara sobrecalentado. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Surchauffe de la puce de la caméra. Éteignez l'appareil et attendez que sa température revienne à la normale avant utilisation", + "ja": "カメラチップ高温。機体の電源を切り、通常の温度に戻ってからご使用ください", + "ko": "카메라 칩 과열. 사용 전에 기체의 전원을 끄고 온도가 정상으로 돌아올 때까지 기다리세요", + "ru": "Чип камеры перегрелся. Выключите питание дрона и дождитесь возвращения температуры к нормальным значениям перед использованием", + "tr": "Kamera çipi aşırı ısındı. Aracı kapatın ve kullanmadan sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请关闭飞机,等待冷却后再使用" + }, + "fpv_tip_0x1C200203_in_the_sky": { + "de": "Kameraprozessor überhitzt. Umgehend zum Startpunkt zurückkehren oder landen. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor overheated. Return to home or land promptly. Wait for temperature to return to normal before use", + "es": "Procesador de la cámara sobrecalentado. Regresa al punto de origen o aterriza rápidamente. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Surchauffe du processeur de la caméra. Retournez au point de départ ou atterrissez rapidement. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラプロセッサー高温。直ちにホームに戻るか、着陸してください。常温に戻るまで待ってからご使用ください", + "ko": "카메라 프로세서 과열. 즉시 리턴 투 홈 진행 또는 착륙 필요. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요", + "ru": "Перегрев процессора камеры. Немедленно вернитесь в исходное положение и приземлитесь. Перед использованием подождите, пока температура не вернется в норму", + "tr": "Kamera işlemcisi aşırı ısındı. Hemen eve dön veya iniş yap. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请尽快返航或降落,等待冷却后重启使用" + }, + "fpv_tip_0x1C200204": { + "de": "Fehler: Prozessor für den Bildsensor der H20 Kamera", + "en": "H20 camera image transmission sensor processor error", + "es": "Error del procesador del sensor de imagen de la cámara H20", + "fr": "Erreur du processeur du capteur de transmission d\\'images de la caméra H20", + "ja": "H20 カメラ映像伝送センサープロセッサーエラー", + "ko": "H20 카메라 이미지 전송 센서 프로세서 오류", + "ru": "Ошибка процессора датчика передачи изображения камеры H20", + "tr": "H20 kamera görüntüsü iletim sensörü işlemcisi hatası", + "zh": "H20 相机图像传感器 芯片异常" + }, + "fpv_tip_0x1C200301": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C200302": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C200303": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C200304": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C200401": { + "de": "Ungültige Speicherkarte. Karte austauschen.", + "en": "Invalid memory card. Replace card", + "es": "Tarjeta de memoria no válida. Cambie la tarjeta", + "fr": "Carte mémoire non valide. Remplacez la carte", + "ja": "メモリーカードが無効です。 カードを交換してください", + "ko": "잘못된 메모리 카드입니다. 카드를 교체하세요", + "ru": "Недопустимая карта памяти. Замените карту", + "tr": "Geçersiz hafıza kartı. Kartı değiştirin", + "zh": "无效存储卡,请更换存储卡" + }, + "fpv_tip_0x1C200401_index_1": { + "de": "Ungültige eMMC. Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "Invalid eMMC. Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "eMMC non valide. Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "eMMCが無効です。カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "eMMC가 올바르지 않습니다. 카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Сбой eMMC. Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "无效EMMC,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C200402": { + "de": "Niedrige Speicherkartengeschwindigkeit. Durch schnellere Karte austauschen.", + "en": "Memory card speed low. Replace with faster card", + "es": "Velocidad baja de la tarjeta de memoria. Cambie la tarjeta por una más rápida", + "fr": "Vitesse de la carte mémoire lente. Remplacez-la par une carte plus rapide", + "ja": "メモリーカードが低速です。 より高速のカードと交換してください", + "ko": "메모리 카드 속도 느림. 더 빠른 카드로 교체하세요", + "ru": "Низкая скорость карты памяти. Замените карту на более быструю", + "tr": "Hafıza kartının hızı yavaş. Daha hızlı bir hafıza kartı ile değiştirin", + "zh": "存储卡为慢速卡,请更换" + }, + "fpv_tip_0x1C200402_index_1": { + "de": "Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "EMMC速度异常,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C200403": { + "de": "Speicherkartenfehler. Karte austauschen.", + "en": "Memory card error. Replace card", + "es": "Error de la tarjeta de memoria. Cambie la tarjeta", + "fr": "Erreur de carte mémoire. Remplacez la carte", + "ja": "メモリーカードにエラーが発生しました。 カードを交換してください", + "ko": "메모리 카드 오류. 카드를 교체하세요", + "ru": "Ошибка карты памяти. Замените карту", + "tr": "Hafıza kartı hatası. Kartı değiştirin", + "zh": "存储卡异常,请更换存储卡" + }, + "fpv_tip_0x1C200403_index_1": { + "de": "eMMC-Fehler. Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "eMMC error. Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "Erreur eMMC. Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "eMMCのエラーです。カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "eMMC 오류입니다. 카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Ошибка eMMC. Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "EMMC异常,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C200404": { + "de": "Keine Speicherkarte", + "en": "No memory card", + "es": "No hay tarjeta de memoria", + "fr": "Aucune carte mémoire", + "ja": "メモリーカードがありません", + "ko": "메모리 카드 없음", + "ru": "Нет карты памяти", + "tr": "Hafıza kartı yok", + "zh": "无存储卡" + }, + "fpv_tip_0x1C200404_index_1": { + "de": "eMMC-Identifikationsfehler. Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "eMMC identification error. Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "Erreur d'identification eMMC. Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "eMMCの認識エラーです。カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "eMMC 식별 오류입니다. 카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Ошибка идентификации eMMC. Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "EMMC识别异常,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C200405": { + "de": "Lese- und Schreibberechtigungen für Speicherkarte bestätigen", + "en": "Confirm memory card read and write permissions", + "es": "Confirme los permisos de lectura y escritura de la tarjeta de memoria", + "fr": "Confirmez les autorisations de lecture et d'écriture de la carte mémoire", + "ja": "メモリーカードの読み取り/書き込み権限を確認してください", + "ko": "메모리 카드 읽기 및 쓰기 권한을 확인하세요", + "ru": "Подтвердите наличие разрешений на чтение и запись карты памяти", + "tr": "Hafıza kartı okuma ve yazma izinlerini onaylayın", + "zh": "请确认存储卡读写属性" + }, + "fpv_tip_0x1C200406": { + "de": "Speicherkarte nicht formatiert. Karte vor Gebrauch formatieren.", + "en": "Memory card not formatted. Format card before use", + "es": "Tarjeta de memoria no formateada. Formatee la tarjeta antes del uso", + "fr": "Carte mémoire non formatée. Formatez la carte avant utilisation", + "ja": "メモリーカードがフォーマットされていません。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드가 포맷되지 않았습니다. 사용 전에 카드를 포맷하세요", + "ru": "Карта памяти не отформатирована. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı biçimlendirilmemiş. Kullanmadan önce kartı biçimlendirin", + "zh": "存储卡未格式化,请格式化后使用" + }, + "fpv_tip_0x1C200407": { + "de": "Speicherkarte wird formatiert...", + "en": "Formatting memory card...", + "es": "Formateando la tarjeta de memoria...", + "fr": "Formatage de la carte mémoire…", + "ja": "メモリーカードのフォーマット中...", + "ko": "메모리 카드 포맷 중...", + "ru": "Форматирование карты памяти...", + "tr": "Hafıza kartı biçimlendiriliyor...", + "zh": "存储卡正在格式化,请等待" + }, + "fpv_tip_0x1C200408": { + "de": "Dateisystem der Speicherkarte wird nicht unterstützt. Karte vor Gebrauch formatieren.", + "en": "Memory card file system not supported. Format card before use", + "es": "Sistema de archivos de la tarjeta de memoria no compatible. Formatee la tarjeta antes del uso", + "fr": "Système de fichiers de la carte mémoire non pris en charge. Formatez la carte avant utilisation", + "ja": "メモリーカードファイルシステムはサポートされていません。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드 파일 시스템이 지원되지 않습니다. 사용 전에 카드를 포맷하세요", + "ru": "Файловая система карты памяти не поддерживается. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı dosya sistemi desteklenmiyor. Kullanmadan önce kartı biçimlendirin", + "zh": "不支持该存储卡文件系统,请格式化后使用" + }, + "fpv_tip_0x1C200409": { + "de": "Speicherkarte wird aktualisiert...", + "en": "Refreshing memory card...", + "es": "Actualizando la tarjeta de memoria...", + "fr": "Actualisation de la carte mémoire…", + "ja": "メモリーカードの更新中...", + "ko": "메모리 카드 새로고침 중...", + "ru": "Обновление карты памяти...", + "tr": "Hafıza kartı yenileniyor...", + "zh": "存储卡正在刷新,请等待" + }, + "fpv_tip_0x1C20040A": { + "de": "Speicherkarte voll. Speicherplatz freigeben.", + "en": "Memory card full. Clear space", + "es": "Tarjeta de memoria llena. Libere espacio", + "fr": "Carte mémoire pleine. Libérez de l'espace", + "ja": "メモリーカードが満杯です。 領域をクリア", + "ko": "메모리 카드 공간 없음. 공간을 확보하세요", + "ru": "Карта памяти заполнена. Освободите место", + "tr": "Hafıza kartı dolu. Yer açın", + "zh": "存储卡已满,请清除内存" + }, + "fpv_tip_0x1C20040B": { + "de": "Max. Dateiindex überschritten. SD-Karte formatieren", + "en": "Max file index exceeded. Format SD card", + "es": "Se ha superado el índice máximo de archivos. Formatear tarjeta SD", + "fr": "Index de fichier max. dépassé. Formater la carte SD", + "ja": "ファイルインデックスの最大値を超えました。SDカードをフォーマット", + "ko": "최대 파일 색인을 초과함. SD 카드 포맷", + "ru": "Превышен максимальный индекс файла. Форматировать карту памяти SD", + "tr": "Maks. dosya dizini aşıldı. SD kartı biçimlendir", + "zh": "文件索引超出最大限制,请格式化SD卡" + }, + "fpv_tip_0x1C20040C": { + "de": "Speicherkarte wird initialisiert...", + "en": "Initializing memory card...", + "es": "Inicializando tarjeta de memoria...", + "fr": "Initialisation de la carte mémoire…", + "ja": "メモリーカードの初期化中...", + "ko": "메모리 카드 초기화 중...", + "ru": "Инициализация карты памяти...", + "tr": "Hafıza kartı başlatılıyor...", + "zh": "存储卡正在初始化,请等待" + }, + "fpv_tip_0x1C20040D": { + "de": "Speicherkartenfehler. Karte vor Gebrauch formatieren.", + "en": "Memory card error. Format card before use", + "es": "Error de la tarjeta de memoria. Formatee la tarjeta antes del uso", + "fr": "Erreur de carte mémoire. Formatez la carte avant utilisation", + "ja": "メモリーカードにエラーが発生しました。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드 오류. 사용 전에 카드를 포맷하세요", + "ru": "Ошибка карты памяти. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı hatası. Kullanmadan önce kartı biçimlendirin", + "zh": "存储卡异常,请格式化存储卡后使用" + }, + "fpv_tip_0x1C20040E": { + "de": "Speicherkarte wird repariert...", + "en": "Fixing memory card...", + "es": "Corrigiendo tarjeta de memoria...", + "fr": "Réparation de la carte mémoire…", + "ja": "メモリーカードの修正中...", + "ko": "메모리 카드 문제 해결 중...", + "ru": "Исправление карты памяти...", + "tr": "Hafıza kartı düzeltiliyor...", + "zh": "存储卡修复中,请等待" + }, + "fpv_tip_0x1C20040F": { + "de": "Niedrige Lese- und Schreibgeschwindigkeit für Speicherkarte. Warten, bis der Vorgang abgeschlossen wurde.", + "en": "Memory card read and write speed low. Wait until process completes", + "es": "Velocidad baja de lectura y escritura de la tarjeta de memoria. Espere hasta que se complete el proceso", + "fr": "Vitesse de lecture et d'écriture de la carte mémoire lente. Attendez que le processus soit terminé", + "ja": "メモリーカード読み取り/書き込みが低速です。 プロセスが完了するまでお待ちください", + "ko": "메모리 카드 읽기 및 쓰기 속도가 느립니다. 프로세스가 완료될 때까지 기다리세요", + "ru": "Низкая скорость чтения и записи карты памяти. Подождите, пока процесс завершится", + "tr": "Hafıza kartının okuma ve yazma hızı düşük. İşlem tamamlanana kadar bekleyin", + "zh": "存储卡读写缓慢,请等待" + }, + "fpv_tip_0x1C200410": { + "de": "Überprüfung vor Verwendung der Speicherkarte erforderlich. Passwort zur Verifizierung eingeben.", + "en": "Verification required before using memory card. Enter password to verify", + "es": "Se requiere verificación antes de usar la tarjeta de memoria. Introduce la contraseña para verificar", + "fr": "Vérification requise avant d'utiliser la carte mémoire. Entrez le mot de passe pour vérifier", + "ja": "メモリーカードの使用前に検証が必要です。 確認用パスワードを入力", + "ko": "메모리 카드를 사용하기 전에 인증이 필요합니다. 인증을 위해 비밀번호를 입력하세요", + "ru": "Требуется проверка перед использованием карты памяти. Введите пароль для проверки", + "tr": "Hafıza kartını kullanmadan önce doğrulama gerekli. Doğrulamak için parolayı girin", + "zh": "存储卡加密待验证,请输入密码进行验证" + }, + "fpv_tip_0x1C300001": { + "de": "Kamera %component_index überhitzt. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera %component_index overheated. Wait for temperature to return to normal before use", + "es": "Cámara %component_index sobrecalentada. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Surchauffe du %component_index de la caméra. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラ %component_index 高温。常温に戻るまで待ってからご使用ください", + "ko": "카메라 %component_index 과열. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요", + "ru": "Камера %component_index перегрелась. Перед использованием подождите, пока температура не вернется в норму", + "tr": "Kamera %component_index aşırı ısındı. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "%component_index号云台相机过热,请等待降温后再使用" + }, + "fpv_tip_0x1C300101": { + "de": "Fehler: Kamera %component_index. Kamera neu starten", + "en": "Camera %component_index error. Restart camera", + "es": "Error de la cámara %component_index. Reinicia la cámara", + "fr": "Erreur de %component_index de la caméra. Redémarrez la caméra", + "ja": "カメラ%component_indexエラー。カメラを再起動してください", + "ko": "카메라 %component_index 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка камеры %component_index. Перезагрузите камеру", + "tr": "Kamera %component_index hatası. Kamerayı yeniden başlatın", + "zh": "%component_index号云台相机异常,请重启相机" + }, + "fpv_tip_0x1C300102": { + "de": "Fehler: Kamera %component_index. Kamera neu starten", + "en": "Camera %component_index error. Restart camera", + "es": "Error de la cámara %component_index. Reinicia la cámara", + "fr": "Erreur de %component_index de la caméra. Redémarrez la caméra", + "ja": "カメラ%component_indexエラー。カメラを再起動してください", + "ko": "카메라 %component_index 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка камеры %component_index. Перезагрузите камеру", + "tr": "Kamera %component_index hatası. Kamerayı yeniden başlatın", + "zh": "%component_index号云台相机异常,请重启相机" + }, + "fpv_tip_0x1C300103": { + "de": "Hohe Temperatur des Kameraprozessors. Fluggerät ausschalten und vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature high. Power off aircraft and wait for temperature to return to normal before use", + "es": "Temperatura alta del procesador de la cámara. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra élevée. Éteignez l'appareil et attendez que sa température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高い。機体の電源を切り、通常の温度に戻ってからご使用ください", + "ko": "카메라 프로세서 온도 높음. 사용 전에 기체의 전원을 끄고 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Высокая температура процессора камеры. Перед использованием выключите питание дрона и дождитесь, пока температура опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı yüksek. Aracı kapatın ve kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度高,请关闭飞机,等待冷却后再使用" + }, + "fpv_tip_0x1C300103_in_the_sky": { + "de": "Hohe Temperatur des Kameraprozessors. Umgehend zum Startpunkt zurückkehren oder landen. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature high. Return to home or land promptly. Wait for temperature to return to normal before use", + "es": "Temperatura alta del procesador de la cámara. Regresa al punto de origen o aterriza rápidamente. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra élevée. Retournez au point de départ ou atterrissez rapidement. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高い。直ちに帰還するか、着陸してください。常温に戻るまで待ってからご使用ください", + "ko": "카메라 프로세서 온도 높음. 즉시 리턴 투 홈 또는 착륙 필요. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Высокая температура процессора камеры. Как можно скорее вернитесь на базу или приземлитесь. Перед использованием подождите, пока температура не опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı yüksek. Ana konuma geri dönün veya derhal iniş yapın. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度高,请尽快返航或降落,等待冷却后重启使用" + }, + "fpv_tip_0x1C300104": { + "de": "Temperatur des Kameraprozessors zu hoch. Fluggerät ausschalten und vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature too high. Power off aircraft and wait for temperature to return to normal before use", + "es": "Temperatura demasiado alta del procesador de la cámara. Apaga la aeronave y espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra trop élevée. Éteignez l'appareil et attendez que sa température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高すぎる。機体の電源を切り、通常の温度に戻ってからご使用ください", + "ko": "카메라 프로세서 온도 너무 높음. 사용 전에 기체의 전원을 끄고 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Чрезмерно высокая температура процессора камеры. Перед использованием выключите питание дрона и дождитесь, пока температура опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı çok yüksek. Aracı kapatın ve kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请关闭飞机,等待冷却后再使用" + }, + "fpv_tip_0x1C300104_in_the_sky": { + "de": "Temperatur des Kameraprozessors zu hoch. Umgehend zum Startpunkt zurückkehren oder landen. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera processor temperature too high. Return to home or land promptly. Wait for temperature to return to normal before use", + "es": "Temperatura demasiado alta del procesador de la cámara. Regresa al punto de origen o aterriza rápidamente. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Température du processeur de la caméra trop élevée. Retournez au point de départ ou atterrissez rapidement. Attendez que la température revienne à la normale avant utilisation", + "ja": "カメラプロセッサの温度が高すぎる。直ちに帰還するか、着陸してください。常温に戻るまで待ってからご使用ください", + "ko": "카메라 프로세서 온도 너무 높음. 즉시 리턴 투 홈 또는 착륙 필요. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요.", + "ru": "Чрезмерно высокая температура процессора камеры. Как можно скорее вернитесь на базу или приземлитесь. Перед использованием подождите, пока температура не опустится до нормальной", + "tr": "Kamera işlemci sıcaklığı çok yüksek. Ana konuma geri dönün veya derhal iniş yapın. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "相机芯片温度过高,请尽快返航或降落,等待冷却后重启使用" + }, + "fpv_tip_0x1C300105": { + "de": "Fehler: Kamera %component_index. Kamera neu starten", + "en": "Camera %component_index error. Restart camera", + "es": "Error de la cámara %component_index. Reinicia la cámara", + "fr": "Erreur de %component_index de la caméra. Redémarrez la caméra", + "ja": "カメラ%component_indexエラー。カメラを再起動してください", + "ko": "카메라 %component_index 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка камеры %component_index. Перезагрузите камеру", + "tr": "Kamera %component_index hatası. Kamerayı yeniden başlatın", + "zh": "%component_index号云台相机异常,请重启相机" + }, + "fpv_tip_0x1C300301": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C300302": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C300303": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C300304": { + "de": "Fehler: H20 Kameraobjektiv. Kamera neu starten", + "en": "H20 camera lens error. Restart camera", + "es": "Error del objetivo de la cámara H20. Reinicia la cámara", + "fr": "Erreur de l'objectif de la caméra H20. Redémarrez la caméra", + "ja": "H20カメラレンズエラー。カメラを再起動してください", + "ko": "H20 카메라 렌즈 오류. 카메라를 다시 시작하세요", + "ru": "Ошибка объектива камеры H20. Перезагрузите камеру", + "tr": "H20 kamera lensi hatası. Kamerayı yeniden başlatın", + "zh": "H20 镜头异常,请断电重启" + }, + "fpv_tip_0x1C300401": { + "de": "Ungültige Speicherkarte. Karte austauschen.", + "en": "Invalid memory card. Replace card", + "es": "Tarjeta de memoria no válida. Cambie la tarjeta", + "fr": "Carte mémoire non valide. Remplacez la carte", + "ja": "メモリーカードが無効です。 カードを交換してください", + "ko": "잘못된 메모리 카드입니다. 카드를 교체하세요", + "ru": "Недопустимая карта памяти. Замените карту", + "tr": "Geçersiz hafıza kartı. Kartı değiştirin", + "zh": "无效存储卡,请更换存储卡" + }, + "fpv_tip_0x1C300401_index_1": { + "de": "Ungültige eMMC. Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "Invalid eMMC. Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "eMMC non valide. Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "eMMCが無効です。カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "eMMC가 올바르지 않습니다. 카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Сбой eMMC. Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "无效EMMC,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C300402": { + "de": "Niedrige Speicherkartengeschwindigkeit. Durch schnellere Karte austauschen.", + "en": "Memory card speed low. Replace with faster card", + "es": "Velocidad baja de la tarjeta de memoria. Cambie la tarjeta por una más rápida", + "fr": "Vitesse de la carte mémoire lente. Remplacez-la par une carte plus rapide", + "ja": "メモリーカードが低速です。 より高速のカードと交換してください", + "ko": "메모리 카드 속도 느림. 더 빠른 카드로 교체하세요", + "ru": "Низкая скорость карты памяти. Замените карту на более быструю", + "tr": "Hafıza kartının hızı yavaş. Daha hızlı bir hafıza kartı ile değiştirin", + "zh": "存储卡为慢速卡,请更换" + }, + "fpv_tip_0x1C300402_index_1": { + "de": "eMMC-Geschwindigkeitsfehler. Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "eMMC speed error. Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "Erreur de vitesse de l'eMMC. Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "eMMCの速度エラーです。カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "eMMC 속도 오류입니다. 카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Ошибка скорости eMMC. Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "EMMC速度异常,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C300403": { + "de": "Speicherkartenfehler. Karte austauschen.", + "en": "Memory card error. Replace card", + "es": "Error de la tarjeta de memoria. Cambie la tarjeta", + "fr": "Erreur de carte mémoire. Remplacez la carte", + "ja": "メモリーカードにエラーが発生しました。 カードを交換してください", + "ko": "메모리 카드 오류. 카드를 교체하세요", + "ru": "Ошибка карты памяти. Замените карту", + "tr": "Hafıza kartı hatası. Kartı değiştirin", + "zh": "存储卡异常,请更换存储卡" + }, + "fpv_tip_0x1C300403_index_1": { + "de": "eMMC-Fehler. Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "eMMC error. Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "Erreur eMMC. Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "eMMCのエラーです。カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "eMMC 오류입니다. 카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Ошибка eMMC. Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "EMMC异常,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C300404": { + "de": "Keine Speicherkarte", + "en": "No memory card", + "es": "No hay tarjeta de memoria", + "fr": "Aucune carte mémoire", + "ja": "メモリーカードがありません", + "ko": "메모리 카드 없음", + "ru": "Нет карты памяти", + "tr": "Hafıza kartı yok", + "zh": "无存储卡" + }, + "fpv_tip_0x1C300404_index_1": { + "de": "eMMC-Identifikationsfehler. Kamera neu starten. Wenn das Problem weiterhin besteht, wenden Sie sich für Reparaturen an den DJI-Support", + "en": "eMMC identification error. Restart camera. If the issue persists, contact DJI Support for repairs", + "fr": "Erreur d'identification eMMC. Redémarrez la caméra. Si le problème persiste, contactez l'assistance DJI pour la réparation", + "ja": "eMMCの認識エラーです。カメラを再起動してください。問題が解決しない場合は、DJIサポートにお問い合わせになり、修理をご依頼ください", + "ko": "eMMC 식별 오류입니다. 카메라를 다시 시작하세요. 문제가 지속되면 DJI 지원 센터에 수리를 요청하세요.", + "ru": "Ошибка идентификации eMMC. Перезапустите камеру. Если проблема не устранена, свяжитесь со службой поддержки DJI для ремонта", + "zh": "EMMC识别异常,请重启相机,如问题还存在,请返厂维修" + }, + "fpv_tip_0x1C300405": { + "de": "Lese- und Schreibberechtigungen für Speicherkarte bestätigen", + "en": "Confirm memory card read and write permissions", + "es": "Confirme los permisos de lectura y escritura de la tarjeta de memoria", + "fr": "Confirmez les autorisations de lecture et d'écriture de la carte mémoire", + "ja": "メモリーカードの読み取り/書き込み権限を確認してください", + "ko": "메모리 카드 읽기 및 쓰기 권한을 확인하세요", + "ru": "Подтвердите наличие разрешений на чтение и запись карты памяти", + "tr": "Hafıza kartı okuma ve yazma izinlerini onaylayın", + "zh": "请确认存储卡读写属性" + }, + "fpv_tip_0x1C300406": { + "de": "Speicherkarte nicht formatiert. Karte vor Gebrauch formatieren.", + "en": "Memory card not formatted. Format card before use", + "es": "Tarjeta de memoria no formateada. Formatee la tarjeta antes del uso", + "fr": "Carte mémoire non formatée. Formatez la carte avant utilisation", + "ja": "メモリーカードがフォーマットされていません。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드가 포맷되지 않았습니다. 사용 전에 카드를 포맷하세요", + "ru": "Карта памяти не отформатирована. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı biçimlendirilmemiş. Kullanmadan önce kartı biçimlendirin", + "zh": "存储卡未格式化,请格式化后使用" + }, + "fpv_tip_0x1C300407": { + "de": "Speicherkarte wird formatiert...", + "en": "Formatting memory card...", + "es": "Formateando la tarjeta de memoria...", + "fr": "Formatage de la carte mémoire…", + "ja": "メモリーカードのフォーマット中...", + "ko": "메모리 카드 포맷 중...", + "ru": "Форматирование карты памяти...", + "tr": "Hafıza kartı biçimlendiriliyor...", + "zh": "存储卡正在格式化,请等待" + }, + "fpv_tip_0x1C300408": { + "de": "Dateisystem der Speicherkarte wird nicht unterstützt. Karte vor Gebrauch formatieren.", + "en": "Memory card file system not supported. Format card before use", + "es": "Sistema de archivos de la tarjeta de memoria no compatible. Formatee la tarjeta antes del uso", + "fr": "Système de fichiers de la carte mémoire non pris en charge. Formatez la carte avant utilisation", + "ja": "メモリーカードファイルシステムはサポートされていません。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드 파일 시스템이 지원되지 않습니다. 사용 전에 카드를 포맷하세요", + "ru": "Файловая система карты памяти не поддерживается. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı dosya sistemi desteklenmiyor. Kullanmadan önce kartı biçimlendirin", + "zh": "不支持该存储卡文件系统,请格式化后使用" + }, + "fpv_tip_0x1C300409": { + "de": "Speicherkarte wird aktualisiert...", + "en": "Refreshing memory card...", + "es": "Actualizando la tarjeta de memoria...", + "fr": "Actualisation de la carte mémoire…", + "ja": "メモリーカードの更新中...", + "ko": "메모리 카드 새로고침 중...", + "ru": "Обновление карты памяти...", + "tr": "Hafıza kartı yenileniyor...", + "zh": "存储卡正在刷新,请等待" + }, + "fpv_tip_0x1C30040A": { + "de": "Speicherkarte voll. Speicherplatz freigeben.", + "en": "Memory card full. Clear space", + "es": "Tarjeta de memoria llena. Libere espacio", + "fr": "Carte mémoire pleine. Libérez de l'espace", + "ja": "メモリーカードが満杯です。 領域をクリア", + "ko": "메모리 카드 공간 없음. 공간을 확보하세요", + "ru": "Карта памяти заполнена. Освободите место", + "tr": "Hafıza kartı dolu. Yer açın", + "zh": "存储卡已满,请清除内存" + }, + "fpv_tip_0x1C30040B": { + "de": "Max. Dateiindex überschritten. SD-Karte formatieren", + "en": "Max file index exceeded. Format SD card", + "es": "Se ha superado el índice máximo de archivos. Formatear tarjeta SD", + "fr": "Index de fichier max. dépassé. Formater la carte SD", + "ja": "ファイルインデックスの最大値を超えました。SDカードをフォーマット", + "ko": "최대 파일 색인을 초과함. SD 카드 포맷", + "ru": "Превышен максимальный индекс файла. Форматировать карту памяти SD", + "tr": "Maks. dosya dizini aşıldı. SD kartı biçimlendir", + "zh": "文件索引超出最大限制,请格式化SD卡" + }, + "fpv_tip_0x1C30040C": { + "de": "Speicherkarte wird initialisiert...", + "en": "Initializing memory card...", + "es": "Inicializando tarjeta de memoria...", + "fr": "Initialisation de la carte mémoire…", + "ja": "メモリーカードの初期化中...", + "ko": "메모리 카드 초기화 중...", + "ru": "Инициализация карты памяти...", + "tr": "Hafıza kartı başlatılıyor...", + "zh": "存储卡正在初始化,请等待" + }, + "fpv_tip_0x1C30040D": { + "de": "Speicherkartenfehler. Karte vor Gebrauch formatieren.", + "en": "Memory card error. Format card before use", + "es": "Error de la tarjeta de memoria. Formatee la tarjeta antes del uso", + "fr": "Erreur de carte mémoire. Formatez la carte avant utilisation", + "ja": "メモリーカードにエラーが発生しました。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드 오류. 사용 전에 카드를 포맷하세요", + "ru": "Ошибка карты памяти. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı hatası. Kullanmadan önce kartı biçimlendirin", + "zh": "存储卡异常,请格式化存储卡后使用" + }, + "fpv_tip_0x1C30040E": { + "de": "Speicherkarte wird repariert...", + "en": "Fixing memory card...", + "es": "Corrigiendo tarjeta de memoria...", + "fr": "Réparation de la carte mémoire…", + "ja": "メモリーカードの修正中...", + "ko": "메모리 카드 문제 해결 중...", + "ru": "Исправление карты памяти...", + "tr": "Hafıza kartı düzeltiliyor...", + "zh": "存储卡修复中,请等待" + }, + "fpv_tip_0x1C30040F": { + "de": "Niedrige Lese- und Schreibgeschwindigkeit für Speicherkarte. Warten, bis der Vorgang abgeschlossen wurde.", + "en": "Memory card read and write speed low. Wait until process completes", + "es": "Velocidad baja de lectura y escritura de la tarjeta de memoria. Espere hasta que se complete el proceso", + "fr": "Vitesse de lecture et d'écriture de la carte mémoire lente. Attendez que le processus soit terminé", + "ja": "メモリーカード読み取り/書き込みが低速です。 プロセスが完了するまでお待ちください", + "ko": "메모리 카드 읽기 및 쓰기 속도가 느립니다. 프로세스가 완료될 때까지 기다리세요", + "ru": "Низкая скорость чтения и записи карты памяти. Подождите, пока процесс завершится", + "tr": "Hafıza kartının okuma ve yazma hızı düşük. İşlem tamamlanana kadar bekleyin", + "zh": "存储卡读写缓慢,请等待" + }, + "fpv_tip_0x1C300601": { + "de": "Temperatur der aktuellen Umgebung zu niedrig. Temperaturmessung aktivieren, wenn die Temperatur im normalen Bereich liegt", + "en": "Temperature of current environment too low. Enable temperature measurement when temperature is within normal range", + "es": "La temperatura del entorno actual es demasiado baja. Activa la medición de temperatura cuando la temperatura esté en el rango normal", + "fr": "Température de l\\'environnement actuel trop faible. Activez la mesure de température quand la température de l\\'environnement se situe dans une plage normale", + "ja": "現在の環境温度が低すぎます。温度測定は通常の温度範囲内の時に有効にしてください", + "ko": "현재 환경 온도가 너무 낮습니다. 온도가 정상 범위 내에 있을 때 온도 측정을 활성화하세요", + "ru": "Слишком низкая температура текущей среды. Включайте измерение температуры в пределах нормального диапазона", + "tr": "Mevcut çevre sıcaklığı çok düşük. Sıcaklık normal aralığa geldiğinde sıcaklık ölçümünü etkinleştir", + "zh": "环境温度过低,请在正常的工作温度范围内测温" + }, + "fpv_tip_0x1C300602": { + "de": "Temperatur der aktuellen Umgebung ist zu hoch. Temperaturmessung nur aktivieren, wenn die Temperatur im normalen Bereich liegt", + "en": "Temperature of current evironment too high. Only enable temperature measurement when temperature is within normal range", + "es": "La temperatura del entorno actual es demasiado alta. Activa la medición de temperatura solo cuando la temperatura esté en el rango normal", + "fr": "Température de l\\'environnement actuel trop élevée. Activez la mesure de température quand la température de l\\'environnement se situe dans une plage normale", + "ja": "現在の環境温度が高すぎます。温度測定は通常の温度範囲内の時にのみ有効にしてください", + "ko": "현재 환경 온도가 너무 높습니다. 온도가 정상 범위 내에 있을 때에만 온도 측정을 활성화하세요", + "ru": "Слишком высокая температура текущей среды. Включайте измерение температуры только в пределах нормального диапазона", + "tr": "Mevcut çevre sıcaklığı çok yüksek. Sıcaklık ölçümünü yalnızca sıcaklık normal aralığa geldiğinde etkinleştir", + "zh": "环境温度过高,请在正常的工作温度范围内测温" + }, + "fpv_tip_0x1C300603": { + "de": "Moduswechsel an der Zenmuse H20T IR-Wärmebildkamera ...", + "en": "Zenmuse H20T infrared thermal camera switching modes...", + "es": "Cámara térmica infrarroja Zenmuse H20T cambiando modos...", + "fr": "Changement de mode de la caméra thermique infrarouge Zenmuse H20T ...", + "ja": "Zenmuse H20T赤外線サーマルカメラのモード切り替え中...", + "ko": "젠뮤즈 H20T 적외선 열화상 카메라 전환 모드 ...", + "ru": "Режимы переключения инфракрасной тепловизионной камеры Zenmuse H20T ...", + "tr": "Zenmuse H20T kızılötesi termal kamera geçiş modları…", + "zh": "H20T相机红外镜头正在切换工作模式,请等待" + }, + "fpv_tip_0x1C300604": { + "de": "Fehlende Kalibrierungsdaten: Zenmuse H20T IR-Wärmebildkamera", + "en": "Zenmuse H20T infrared thermal camera calibration data missing", + "es": "Faltan datos de calibración de la cámara térmica infrarroja Zenmuse H20T", + "fr": "Données d\\'étalonnage de la caméra thermique infrarouge Zenmuse H20T introuvables", + "ja": "Zenmuse H20T赤外線サーマルカメラのキャリブレーションデータがありません", + "ko": "젠뮤즈 H20T 적외선 열화상 카메라 캘리브레이션 데이터 없음", + "ru": "Отсутствуют данные о калибровке инфракрасной тепловизионной камеры Zenmuse H20T", + "tr": "Zenmuse H20T kızılötesi termal kamera kalibrasyon verileri eksik", + "zh": "H20T相机红外镜头标定数据缺失" + }, + "fpv_tip_0x1C300605": { + "de": "Initialisierungsfehler: Zenmuse H20T IR-Wärmebildkamera. Kamera neu starten", + "en": "Zenmuse H20T infrared thermal camera initialization error. Restart camera", + "es": "Error de inicio de la cámara térmica infrarroja Zenmuse H20T. Reinicia la cámara", + "fr": "Erreur d\\'initialisation de la caméra thermique infrarouge Zenmuse H20T. Redémarrez la caméra", + "ja": "Zenmuse H20T赤外線サーマルカメラの初期化エラー。カメラを再起動してください", + "ko": "젠뮤즈 H20T 적외선 열화상 카메라 초기화 오류. 카메라를 다시 시작하세요.", + "ru": "Ошибка инициализации инфракрасной тепловизионной камеры Zenmuse H20T. Перезапустите камеру", + "tr": "Zenmuse H20T kızılötesi termal kamera başlatma hatası. Kamerayı yeniden başlatın", + "zh": "H20T相机红外镜头初始化异常,请断电重启" + }, + "fpv_tip_0x1C300606": { + "de": "Temperaturmessung fehlgeschlagen. Parameter der Kamera anpassen und erneut versuchen", + "en": "Temperature measurement failed. Adjust camera parameters and try again", + "es": "Error de medición de temperatura. Ajusta los parámetros de la cámara y vuelve a intentarlo", + "fr": "Mesure de la température échouée. Réglez les paramètres de caméra et réessayez", + "ja": "温度測定に失敗しました。カメラのパラメーターを調整し、再試行してください", + "ko": "온도 측정에 실패했습니다. 카메라 매개변수를 조정하고 다시 시도하세요", + "ru": "Не удалось измерить температуру. Настройте параметры камеры и повторите попытку", + "tr": "Sıcaklık ölçümü başarısız. Kamera parametrelerini ayarlayın ve tekrar deneyin", + "zh": "测温失败,请调整相机参数后测温" + }, + "fpv_tip_0x1C300607": { + "de": "Messbereichsgrenze überschritten. In den Modus mit niedriger Verstärkung wechseln", + "en": "Exceeded measuring range limit. Switch to Low Gain mode", + "es": "Se ha excedido el límite del rango de medición. Cambia al modo de baja ganancia", + "fr": "Limite de plage de mesure dépassée. Passez en mode Gain faible", + "it": "", + "ja": "測定範囲の限界を超えました。低ゲインモードに切り替え", + "ko": "측정 범위 한도를 초과했습니다. 낮은 게인 모드로 전환", + "ru": "Превышен порог диапазона измерения. Переключить в режим низкого прироста", + "tr": "Ölçüm aralığı sınırı aşıldı. Düşük Kazanç moduna geç", + "zh": "测温超出量程,请切换为低增益模式" + }, + "fpv_tip_0x1C300701": { + "de": "Sonne erkannt. IR-Verschluss geschlossen", + "en": "Sun detected. Infrared shutter closed", + "es": "Sol detectado. Obturador de infrarrojos cerrado", + "fr": "Soleil détecté. Obturateur infrarouge fermé", + "ja": "太陽を検知。赤外線シャッター閉", + "ko": "해가 감지되었습니다. 적외선 셔터가 닫혔습니다", + "ru": "Обнаружено солнце. Инфракрасный затвор закрыт", + "tr": "Güneş algılandı. Kızılötesi perde kapandı", + "zh": "检测到太阳,红外快门关闭" + }, + "fpv_tip_0x1C300702": { + "de": "Sonne erkannt. Gimbal drehen, um direkte Sonneneinstrahlung zu vermeiden", + "en": "Sun detected. Rotate gimbal to avoid direct sunlight", + "es": "Sol detectado. Gire el estabilizador para evitar la luz solar directa", + "fr": "Soleil détecté. Tournez la nacelle pour éviter la lumière directe du soleil", + "ja": "太陽を検知。ジンバルを回転させて直射日光を避けてください", + "ko": "해가 감지되었습니다. 짐벌을 회전시켜 직사 광선을 막으세요", + "ru": "Обнаружено солнце. Поверните гиростабилизатор, чтобы избежать попадания прямых солнечных лучей", + "tr": "Güneş algılandı. Doğrudan güneş ışığından kaçınmak için gimbalı döndürün", + "zh": "检测到太阳,请转动云台,避免太阳直射" + }, + "fpv_tip_0x1D001001": { + "de": "Gimbal reagiert nicht nach dem Einschalten", + "en": "Gimbal unresponsive after power on", + "es": "El estabilizador no responde después del encendido", + "fr": "Pas de réponse de la nacelle après la mise sous tension", + "ja": "電源オンの後にジンバル反応なし", + "ko": "전원을 켠 후 짐벌이 응답하지 않음", + "ru": "Стабилизатор не отвечает после включения питания", + "tr": "Gimbal açıldıktan sonra yanıt vermiyor", + "zh": "云台上电后无力" + }, + "fpv_tip_0x1D001101": { + "de": "Gimbal kann automatische Überprüfung nicht abschließen", + "en": "Gimbal unable to complete auto check", + "es": "El estabilizador no puede completar la comprobación automática", + "fr": "Nacelle incapable de terminer la vérification automatique", + "ja": "ジンバルの自動確認を完了できません", + "ko": "짐벌 자동 점검 완료 불가", + "ru": "Не удалось выполнить автоматическую проверку стабилизатора", + "tr": "Gimbal otomatik kontrolü tamamlanamıyor", + "zh": "云台无法完成自检" + }, + "fpv_tip_0x1D010001": { + "de": "Gimbal blockiert", + "en": "Gimbal stuck", + "es": "Estabilizador atascado", + "fr": "Nacelle bloquée", + "ja": "ジンバルがスタック状態", + "ko": "짐벌 막힘", + "ru": "Стабилизатор заблокирован", + "tr": "Gimbal sıkıştı", + "zh": "云台被卡住" + }, + "fpv_tip_0x1D010002": { + "de": "Fehler: Gimbal-Selbsttest", + "en": "Gimbal auto-check failed", + "es": "Error de comprobación automática del estabilizador", + "fr": "Vérif. auto de la nacelle échouée", + "ja": "ジンバル自動確認失敗", + "ko": "짐벌 자체 점검 실패", + "ru": "Сбой автопроверки стабилизатора", + "tr": "Gimbal otomatik kontrol başarısız", + "zh": "云台自检失败" + }, + "fpv_tip_0x1D010003": { + "de": "Gimbal-Motor überlastet", + "en": "Gimbal motor overloaded", + "es": "Motor del estabilizador sobrecargado", + "fr": "Surcharge du moteur de la nacelle", + "ja": "ジンバルモーター過負荷状態", + "ko": "짐벌 모터 과부하", + "ru": "Мотор стабилизатора перегружен", + "tr": "Gimbal motoru aşırı yüklü", + "zh": "云台电机过载" + }, + "fpv_tip_0x1D010C01": { + "de": "FPV-Gimbal blockiert", + "en": "FPV gimbal stuck", + "es": "Estabilizador FPV atascado", + "fr": "Nacelle FPV bloquée", + "ja": "FPVジンバルが動かなくなっています", + "ko": "FPV 짐벌 막힘", + "ru": "Заедание стабилизатора курсовой камеры", + "tr": "FPV gimbal sıkıştı", + "zh": "FPV云台被卡住" + }, + "fpv_tip_0x1D010C02": { + "de": "Selbsttest FPV-Gimbal fehlgeschlagen", + "en": "FPV gimbal auto-check failed", + "es": "Error de comprobación automática del estabilizador FPV", + "fr": "Échec de la vérification auto de la nacelle FPV", + "ja": "FPVジンバルの自動確認が失敗しました", + "ko": "FPV 짐벌 자체 점검 실패", + "ru": "Сбой автопроверки стабилизатора курсовой камеры", + "tr": "FPV gimbal otomatik kontrolü başarısız", + "zh": "FPV云台自检失败" + }, + "fpv_tip_0x1D010C03": { + "de": "Motor FPV-Gimbal überlastet", + "en": "FPV gimbal motor overloaded", + "es": "Motor del estabilizador FPV sobrecargado", + "fr": "Surcharge du moteur de nacelle FPV", + "ja": "FPVジンバルモーターが過負荷状態です", + "ko": "FPV 짐벌 모터 과부하", + "ru": "Перегрузка двигателя стабилизатора курсовой камеры", + "tr": "FPV gimbal motoru aşırı yüklü", + "zh": "FPV云台电机过载" + }, + "fpv_tip_0x1D020001": { + "de": "Kalibrierungsfehler: Gimbal", + "en": "Gimbal calibration error", + "es": "Error de calibración del estabilizador", + "fr": "Erreur d\\'étalonnage de la nacelle", + "ja": "ジンバル キャリブレーション エラー", + "ko": "짐벌 캘리브레이션 오류", + "ru": "Ошибка калибровки стабилизатора", + "tr": "Gimbal kalibrasyon hatası", + "zh": "云台标定错误" + }, + "fpv_tip_0x1D020002": { + "de": "Gimbal-Fehler: IMU. Fluggerät neu starten und erneut versuchen", + "en": "Gimbal IMU error. Restart aircraft and try again", + "es": "Error de IMU del estabilizador. Reinicia la aeronave y vuelve a intentarlo.", + "fr": "Erreur de l'IMU de nacelle. Redémarrez l'appareil et réessayez", + "ja": "ジンバルのIMUエラー。機体を再起動してやり直してください", + "ko": "짐벌 IMU 오류. 기체를 재시작한 후 다시 시도하세요.", + "ru": "Ошибка IMU гиростабилизатора. Перезапустите дрон и повторите попытку", + "tr": "Gimbal IMU hatası. Hava aracını yeniden başlatın ve tekrar deneyin", + "zh": "云台IMU数据异常,请尝试重启飞行器" + }, + "fpv_tip_0x1D020003": { + "de": "Parameterfehler: Gimbal-Kalibrierung. Automatische Gimbal-Kalibrierung versuchen", + "en": "Gimbal calibration parameter error. Try gimbal Auto Calibration", + "es": "Error de parámetros de calibración del estabilizador. Pruebe la calibración automática del estabilizador", + "fr": "Erreur de paramètre d'étalonnage de la nacelle. Essayez l'étalonnage automatique de la nacelle", + "ja": "ジンバルキャリブレーションパラメーターエラーです。ジンバル自動キャリブレーションを試行してください", + "ko": "짐벌 캘리브레이션 매개변수 오류. 짐벌 자동 캘리브레이션을 시도하세요", + "pt": "", + "ru": "Ошибка параметра калибровки гиростабилизатора. Попробуйте выполнить автоматическую калибровку гиростабилизатора", + "tr": "Gimbal kalibrasyon parametresi hatası. Gimbal Otomatik Kalibrasyonu deneyin", + "zh": "云台校准参数异常,请尝试云台自动校准" + }, + "fpv_tip_0x1D020C01": { + "de": "Kalibrierungsfehler FPV-Gimbal", + "en": "FPV gimbal calibration error", + "es": "Error de calibración del estabilizador FPV", + "fr": "Erreur d'étalonnage de la nacelle FPV", + "ja": "FPVジンバルキャリブレーションエラー", + "ko": "FPV 짐벌 캘리브레이션 오류", + "ru": "Ошибка калибровки стабилизатора курсовой камеры", + "tr": "FPV gimbal kalibrasyon hatası", + "zh": "FPV云台标定错误" + }, + "fpv_tip_0x1D030001": { + "de": "Gimbal kann Fluggerätedaten nicht abrufen", + "en": "Gimbal unable to retrieve aircraft data", + "es": "El estabilizador no puede recuperar los datos de la aeronave", + "fr": "La nacelle ne peut pas récupérer les donnés de l\\'appareil", + "ja": "ジンバルが機体データを取得できません", + "ko": "짐벌 기체 데이터 가져올 수 없음", + "ru": "Стабилизатор получает данные с дрона", + "tr": "Gimbal araç verilerini alamıyor", + "zh": "云台无法获取飞行器信息" + }, + "fpv_tip_0x1D030C01": { + "de": "FPV-Gimbal kann keine Fluggerätedaten abrufen", + "en": "FPV gimbal unable to obtain aircraft data", + "es": "El estabilizador FPV no puede obtener los datos de la aeronave", + "fr": "Nacelle FPV incapable d'obtenir les données de l'appareil", + "ja": "FPVジンバルで機体データを取得できません", + "ko": "FPV 짐벌이 기체 데이터 가져올 수 없습니다", + "ru": "Стабилизатору курсовой камеры не удается получить информацию о дроне", + "tr": "FPV gimbal, hava aracı verilerini alamıyor", + "zh": "FPV云台无法获取飞行器信息" + }, + "fpv_tip_0x1D040001": { + "de": "Starke Vibrationen am Gimbal", + "en": "Excessive gimbal vibration", + "es": "Vibración del estabilizador excesiva", + "fr": "Vibrations excessives de la nacelle", + "ja": "ジンバルの過剰な振動", + "ko": "과도한 짐벌 진동", + "ru": "Чрезмерная вибрация стабилизатора", + "tr": "Gimbal aşırı titriyor", + "zh": "云台异常振动" + }, + "fpv_tip_0x1D040002": { + "de": "Fehler: Gimbalsensor", + "en": "Gimbal sensor error", + "es": "Error del sensor del estabilizador", + "fr": "Erreur capteur de la nacelle", + "ja": "ジンバル センサー エラー", + "ko": "짐벌 센서 오류", + "ru": "Ошибка датчика стабилизатора", + "tr": "Gimbal sensörü hatası", + "zh": "云台传感器故障" + }, + "fpv_tip_0x1D040003": { + "de": "Fehlfunktion: Gimbal-ESC", + "en": "Gimbal ESC malfunctioned", + "es": "ESC del estabilizador no funciona correctamente", + "fr": "Anomalie sur l\\'ESC nacelle", + "ja": "ジンバルESC故障", + "ko": "짐벌 ESC 오작동", + "ru": "Неисправность ESC стабилизатора", + "tr": "Gimbal ESC arıza yaptı", + "zh": "云台电调故障" + }, + "fpv_tip_0x1D040004": { + "de": "Fehlfunktion: Gimbal-ESC", + "en": "Gimbal ESC malfunctioned", + "es": "ESC del estabilizador no funciona correctamente", + "fr": "Anomalie sur l\\'ESC nacelle", + "ja": "ジンバルESC故障", + "ko": "짐벌 ESC 오작동", + "ru": "Неполадки ESC стабилизатора", + "tr": "Gimbal ESC arıza yaptı", + "zh": "云台电调故障" + }, + "fpv_tip_0x1D040005": { + "de": "Fehlfunktion: Gimbal-ESC", + "en": "Gimbal ESC malfunctioned", + "es": "ESC del estabilizador no funciona correctamente", + "fr": "Anomalie sur l\\'ESC nacelle", + "ja": "ジンバルESC故障", + "ko": "짐벌 ESC 오작동", + "ru": "Неисправность ESC стабилизатора", + "tr": "Gimbal ESC arıza yaptı", + "zh": "云台电调故障" + }, + "fpv_tip_0x1D040C01": { + "de": "Abnormale Vibration FPV-Gimbal", + "en": "Abnormal FPV gimbal vibration", + "es": "Vibración anormal del estabilizador FPV", + "fr": "Vibration anormale de la nacelle FPV", + "ja": "FPVジンバルの振動に異常があります", + "ko": "비정상적인 FPV 짐벌 진동", + "ru": "Аномальная вибрация стабилизатора курсовой камеры", + "tr": "Anormal FPV gimbal titreşimi", + "zh": "FPV云台异常振动" + }, + "fpv_tip_0x1D040C02": { + "de": "Sensorfehler FPV-Gimbal", + "en": "FPV gimbal sensor error", + "es": "Error del sensor del estabilizador FPV", + "fr": "Erreur capteur de la nacelle FPV", + "ja": "FPVジンバルセンサーエラー", + "ko": "FPV 짐벌 센서 오류", + "ru": "Ошибка датчика стабилизатора курсовой камеры", + "tr": "FPV gimbal sensörü hatası", + "zh": "FPV云台传感器故障" + }, + "fpv_tip_0x1D040C03": { + "de": "ESC-Fehlfunktion FPV-Gimbal", + "en": "FPV gimbal ESC malfunction", + "es": "Error de funcionamiento de ESC del estabilizador FPV", + "fr": "Dysfonctionnement ESC de la nacelle FPV", + "ja": "FPVジンバルESCに異常", + "ko": "FPV 짐벌 ESC 오작동", + "ru": "Неисправность ESC стабилизатора курсовой камеры", + "tr": "FPV gimbal ESC arızası", + "zh": "FPV云台电调故障" + }, + "fpv_tip_0x1D040C04": { + "de": "ESC-Fehlfunktion FPV-Gimbal", + "en": "FPV gimbal ESC malfunction", + "es": "Error de funcionamiento de ESC del estabilizador FPV", + "fr": "FPV gimbal ESC malfunction", + "ja": "FPVジンバルESCに異常", + "ko": "FPV 짐벌 ESC 오작동", + "ru": "Неисправность ESC стабилизатора курсовой камеры", + "tr": "FPV gimbal ESC arızası", + "zh": "FPV云台电调故障" + }, + "fpv_tip_0x1D040C05": { + "de": "ESC-Fehlfunktion FPV-Gimbal", + "en": "FPV gimbal ESC malfunction", + "es": "Error de funcionamiento de ESC del estabilizador FPV", + "fr": "FPV gimbal ESC malfunction", + "ja": "FPVジンバルESCに異常", + "ko": "FPV 짐벌 ESC 오작동", + "ru": "Неисправность ESC стабилизатора курсовой камеры", + "tr": "FPV gimbal ESC arızası", + "zh": "FPV云台电调故障" + }, + "fpv_tip_0x1D050001": { + "ar": "", + "de": "Gimbal %component_index Rollachsen-Endpunkt erreicht", + "en": "Gimbal %component_index roll axis endpoint reached", + "es": "Se ha alcanzado el límite del eje de rotación del estabilizador %component_index", + "fr": "Limite axe de roulis de la nacelle %component_index atteinte", + "id": "", + "it": "", + "ja": "ジンバル%component_indexのロール軸のエンドポイントに達しました", + "ko": "짐벌 %component_index 롤 축 엔드포엔트 도달", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "Достигнут предел оси крена стабилизатора %component_index", + "th": "", + "tr": "Gimbal %component_index dönme ekseni bitiş noktasına ulaştı", + "ug": "", + "vi": "", + "zh": "云台%component_index横滚已达限位", + "zh-Hant": "" + }, + "fpv_tip_0x1D050002": { + "de": "Gimbal %component_index: Neigungsachsen-Endpunkt erreicht", + "en": "Gimbal %component_index pitch axis endpoint reached", + "es": "Se ha alcanzado el límite del eje de inclinación del estabilizador %component_index", + "fr": "Limite axe vertical de la nacelle %component_index atteinte", + "ja": "ジンバル%component_indexピッチ軸のエンドポイントに達しました", + "ko": "짐벌 %component_index 피치 축 엔드포인트 도달", + "ru": "Достигнут предел оси наклона стабилизатора %component_index", + "tr": "Gimbal %component_index yükselme ekseni bitiş noktasına ulaştı", + "zh": "云台%component_index俯仰已达限位" + }, + "fpv_tip_0x1D050003": { + "de": "Gimbal %component_index: Gierachsen-Endpunkt erreicht", + "en": "Gimbal %component_index pan axis endpoint reached", + "es": "Se ha alcanzado el límite del eje de paneo del estabilizador %component_index", + "fr": "Limite axe pano de la nacelle %component_index atteinte", + "ja": "ジンバル%component_indexパン軸のエンドポイントに達しました", + "ko": "짐벌 %component_index 요 축 엔드포인트 도달", + "ru": "Достигнут предел оси поворота стабилизатора %component_index", + "tr": "Gimbal %component_index yana dönüş ekseni bitiş noktasına ulaştı", + "zh": "云台%component_index偏航已达限位" + }, + "fpv_tip_0x1D050301": { + "de": "Max. Versuchsanzahl für Gimbal-Bedienung überschritten", + "en": "Gimbal operation retry attempts limit exceeded", + "es": "Se ha superado el límite de reintentos de operación del estabilizador", + "fr": "Limite de nouvelles tentatives dépassée pour l\\'opération de nacelle", + "it": "", + "ja": "ジンバル操作の再試行上限に達しました", + "ko": "짐벌 작업 재시도 횟수 한도 초과", + "pt": "", + "ru": "Количество повторных попыток использования стабилизатора превысило предел", + "tr": "Gimbal işlemi yeniden deneme sınırı aşıldı", + "zh": "云台重试次数过多" + }, + "fpv_tip_0x1D050302": { + "de": "Fehler: Kamerabelichtung", + "en": "Camera exposure error", + "es": "Error de exposición de la cámara", + "fr": "Erreur d\\'exposition de la caméra", + "it": "", + "ja": "カメラ露出エラー", + "ko": "카메라 노출 오류", + "pt": "", + "ru": "Ошибка выдержки камеры", + "tr": "Kamera pozlama hatası", + "zh": "相机曝光超时" + }, + "fpv_tip_0x1D05030F": { + "de": "Gimbal-Rotationsanzahl nähert sich max. Limit", + "en": "Gimbal rotation count approaching max limit", + "es": "Recuento de revoluciones del estabilizador cercano al límite máximo", + "fr": "Nombre de rotations de la nacelle proche de la limite maximale", + "it": "", + "ja": "ジンバルの回転数が最大値に近づいています", + "ko": "짐벌 회전 수가 최대 한도에 근접함", + "pt": "", + "ru": "Количество оборотов стабилизатора приближается к максимальному пределу", + "tr": "Gimbal dönüş sayısı maksimum sınıra yaklaşıyor", + "zh": "云台三轴转动次数接近使用寿命" + }, + "fpv_tip_0x1D050A01": { + "de": "Gimbal-Spannung zu niedrig", + "en": "Gimbal voltage too low", + "es": "Voltaje del estabilizador demasiado bajo", + "fr": "Tension de la nacelle trop basse", + "it": "", + "ja": "ジンバル低電圧", + "ko": "짐벌 전압 너무 낮음", + "pt": "", + "ru": "Слишком низкое напряжение стабилизатора", + "tr": "Gimbal gerilimi çok düşük", + "zh": "云台电压过低" + }, + "fpv_tip_0x1D050A02": { + "de": "Fehler: Zeitsynchronisierung des Gimbals", + "en": "Gimbal time synchronization error", + "es": "Error de sincronización de la hora del estabilizador", + "fr": "Erreur de synchronisation de l\\'heure de la nacelle", + "it": "", + "ja": "ジンバルの時間同期エラー", + "ko": "짐벌 시간 동기화 오류", + "pt": "", + "ru": "Ошибка синхронизации времени стабилизатора", + "tr": "Gimbal saati senkronizasyon hatası", + "zh": "云台时间同步功能异常" + }, + "fpv_tip_0x1D050C01": { + "de": "FPV-Gimbal-Limit erreicht", + "en": "FPV gimbal limit reached", + "es": "Límite de estabilizador FPV alcanzado", + "fr": "Limite nacelle FPV atteinte", + "ja": "FPVジンバルリミットに達しました", + "ko": "FPV 짐벌 한계점 도달", + "ru": "Достигнут предел стабилизатора курсовой камеры", + "tr": "FPV gimbal sınırına ulaşıldı", + "zh": "FPV云台已达限位" + }, + "fpv_tip_0x1D050C02": { + "de": "Neigungsgrenze FPV-Gimbal erreicht", + "en": "FPV gimbal tilt limit reached", + "es": "Límite de inclinación del estabilizador FPV alcanzado", + "fr": "Limite d'inclinaison de la nacelle FPV atteinte", + "ja": "チルトがFPVジンバルリミットに達しました", + "ko": "FPV 짐벌 틸트 한계점 도달", + "ru": "Достигнут предел наклона стабилизатора курсовой камеры", + "tr": "FPV gimbal eğilme sınırına ulaşıldı", + "zh": "FPV云台俯仰已达限位" + }, + "fpv_tip_0x1D050C03": { + "de": "Schwenkgrenze FPV-Gimbal erreicht", + "en": "FPV gimbal pan limit reached", + "es": "Límite de paneo del estabilizador FPV alcanzado", + "fr": "Limite panoramique de la nacelle FPV atteinte", + "ja": "パンがFPVジンバルリミットに達しました", + "ko": "FPV 짐벌 팬 한계점 도달", + "ru": "Достигнут предел панорамирования стабилизатора курсовой камеры", + "tr": "FPV gimbal pan sınırına ulaşıldı", + "zh": "FPV云台偏航已达限位" + }, + "fpv_tip_0x1D0C0002": { + "de": "Gimbal-Fehler: IMU", + "en": "Gimbal IMU Error", + "es": "Error de IMU del estabilizador", + "fr": "Erreur de l'IMU nacelle", + "ja": "ジンバルのIMUエラー", + "ko": "짐벌 IMU 오류", + "ru": "Ошибка IMU гиростабилизатора", + "tr": "Gimbal IMU hatası", + "zh": "云台IMU异常" + }, + "fpv_tip_0x1D0C0003": { + "de": "Fehler: Gimbal-Initialisierung", + "en": "Gimbal Initialization Error", + "es": "Error de inicio del estabilizador", + "fr": "Erreur d'initialisation nacelle", + "ja": "ジンバルの初期化エラー", + "ko": "짐벌 초기화 오류", + "ru": "Ошибка инициализации гиростабилизатора", + "tr": "Gimbal Başlatma Hatası", + "zh": "云台初始化异常" + }, + "fpv_tip_0x1D0C0004": { + "de": "Fehler: Gimbal-Initialisierung", + "en": "Gimbal Initialization Error", + "es": "Error de inicio del estabilizador", + "fr": "Erreur d'initialisation nacelle", + "ja": "ジンバルの初期化エラー", + "ko": "짐벌 초기화 오류", + "ru": "Ошибка инициализации гиростабилизатора", + "tr": "Gimbal Başlatma Hatası", + "zh": "云台初始化异常" + }, + "fpv_tip_0x1D0C0005": { + "de": "Gimbal-Spannungsfehler. Durch DJI-Akku ersetzen", + "en": "Gimbal voltage error. Replace with DJI battery", + "es": "Error de voltaje del estabilizador. Sustituir por una batería DJI", + "fr": "Erreur de tension de la nacelle. Remplacer la batterie par une batterie DJI", + "ja": "ジンバルの電圧エラー。DJIバッテリーに交換してください", + "ko": "짐벌 전압 오류. DJI 배터리로 교체하세요", + "ru": "Ошибка напряжения гиростабилизатора. Замените аккумуляторной батареей DJI", + "tr": "Gimbal voltaj hatası. DJI pille değiştirin", + "zh": "云台电源电压异常,请使用官方电池" + }, + "fpv_tip_0x1D0C000B": { + "de": "Gimbal Motor-Temperatur zu hoch", + "en": "Gimbal Motor Temperature Too High", + "es": "Temperatura del motor del estabilizador demasiado alta", + "fr": "Température moteur de nacelle trop élevée", + "ja": "ジンバルモーターの温度が高すぎます", + "ko": "짐벌 모터 온도 너무 높음", + "ru": "Слишком высокая температура двигателя гиростабилизатора", + "tr": "Gimbal Motor Sıcaklığı Çok Yüksek", + "zh": "云台电机温度过高" + }, + "fpv_tip_0x1D0C000E": { + "de": "Objektiv nicht ordnungsgemäß befestigt. Objektiv erneut anbringen und Hebel in die Verriegelungsstellung bringen", + "en": "Lens not firmly attached. Reattach lens and toggle lever to the locked position", + "es": "El objetivo no está bien sujeto. Vuelva a colocar el objetivo y la palanca acodada en la posición de bloqueo", + "fr": "L’objectif n’est pas correctement fixé. Rattachez l’objectif et basculez le levier en position verrouillée", + "ja": "レンズがしっかりと取り付けられていません。レンズを取り付け直し、レバーをロック位置に切り替えてください", + "ko": "렌즈가 단단히 부착되지 않았습니다. 렌즈를 다시 부착하고 레버를 잠금 위치로 전환하세요", + "ru": "Объектив не установлен должным образом. Снова установите объектив и переключите рычаг в заблокированное положение", + "tr": "Lens sıkıca takılı değil. Lensi yeniden takın ve kolu kilitli konuma getirin", + "zh": "镜头未安装紧固,请取下重装,并拧紧扳扣" + }, + "fpv_tip_0x1D0C000F": { + "de": "Gimbal nicht ausbalanciert. Darauf achten, dass Objektivschutz/ND-Filter und Gegenlichtblende ordnungsgemäß installiert sind.", + "en": "Gimbal not balanced. Make sure lens protector/ND filter and hood are properly installed", + "es": "Estabilizador no equilibrado. Asegúrese de que el protector del objetivo/filtro ND y el parasol estén montados correctamente", + "fr": "Nacelle non équilibrée. S'assurer que la protection d'objectif/le filtre ND et le pare-soleil sont correctement installés", + "ja": "ジンバルのバランスが取れていない。レンズプロテクター/NDフィルターとフードが正しく取り付けられているか確認してください", + "ko": "짐벌 균형 안 맞음. 렌즈 보호대/ND 필터 및 후드가 제대로 설치되었는지 확인합니다.", + "ru": "Гиростабилизатор не сбалансирован. Убедитесь, что защита объектива/фильтр ND и бленда установлены правильно", + "tr": "Gimbal dengeli değil. Lens koruyucusunun/ND filtresinin ve güneşliğin doğru şekilde takıldığından emin olun", + "zh": "云台未配平,请正确安装保护镜/ND镜和遮光罩" + }, + "fpv_tip_0x1D0C0C02": { + "de": "IMU-Fehler FPV-Gimbal", + "en": "FPV gimbal IMU error", + "es": "Error de IMU del estabilizador FPV", + "fr": "Erreur de l'IMU de la nacelle FPV", + "ja": "FPVジンバルIMUエラー", + "ko": "짐벌 짐벌 IMU 오류", + "ru": "Ошибка IMU стабилизатора курсовой камеры", + "tr": "FPV gimbal IMU hatası", + "zh": "FPV云台IMU异常" + }, + "fpv_tip_0x1D0C0C03": { + "de": "Initialisierungsfehler FPV-Gimbal", + "en": "FPV gimbal initialization error", + "es": "Error de inicialización del estabilizador FPV", + "fr": "Erreur d'initialisation de la nacelle FPV", + "ja": "FPVジンバル初期化エラー", + "ko": "FPV 짐벌 초기화 오류", + "ru": "Ошибка инициализации стабилизатора курсовой камеры", + "tr": "FPV gimbal başlatma hatası", + "zh": "FPV云台初始化异常" + }, + "fpv_tip_0x1D0C0C04": { + "de": "Initialisierungsfehler FPV-Gimbal", + "en": "FPV gimbal initialization error", + "es": "Error de inicialización del estabilizador FPV", + "fr": "FPV gimbal initialization error", + "ja": "FPVジンバル初期化エラー", + "ko": "FPV 짐벌 초기화 오류", + "ru": "Ошибка инициализации стабилизатора курсовой камеры", + "tr": "FPV gimbal başlatma hatası", + "zh": "FPV云台初始化异常" + }, + "fpv_tip_0x1D0C0C05": { + "de": "Spannungsfehler FPV-Gimbal. Durch DJI-Akku ersetzen", + "en": "FPV gimbal voltage error. Replace with DJI battery", + "es": "Error de voltaje del estabilizador FPV. Sustituir por una batería DJI", + "fr": "Erreur de tension de la nacelle FPV. Remplacer la batterie par une batterie DJI", + "ja": "FPVジンバル電圧エラーです。DJIバッテリーに交換してください", + "ko": "FPV 짐벌 전압 오류. DJI 배터리로 교체하세요", + "ru": "Ошибка напряжения стабилизатора курсовой камеры. Замените аккумуляторной батареей DJI", + "tr": "FPV gimbal voltaj hatası. DJI pille değiştirin", + "zh": "FPV云台电源电压异常,请使用官方电池" + }, + "fpv_tip_0x1D0C0C0B": { + "de": "Motor FPV-Gimbal überhitzt", + "en": "FPV gimbal motor overheated", + "es": "Motor del estabilizador FPV sobrecalentado", + "fr": "Surchauffe du moteur de nacelle FPV", + "ja": "FPVジンバルモーターがオーバーヒートしました", + "ko": "FPV 짐벌 모터 과부하", + "ru": "Перегрев двигателя стабилизатора курсовой камеры", + "tr": "FPV gimbal motoru aşırı ısındı", + "zh": "FPV云台电机温度过高" + }, + "fpv_tip_0x1D0E0001": { + "de": "Fehler: Gimbal-Initialisierung", + "en": "Gimbal Initialization Error", + "es": "Error de inicio del estabilizador", + "fr": "Erreur d'initialisation nacelle", + "ja": "ジンバルの初期化エラー", + "ko": "짐벌 초기화 오류", + "ru": "Ошибка инициализации гиростабилизатора", + "tr": "Gimbal Başlatma Hatası", + "zh": "云台初始化异常" + }, + "fpv_tip_0x1D0E0C01": { + "de": "Initialisierungsfehler FPV-Gimbal", + "en": "FPV gimbal initialization error", + "es": "Error de inicialización del estabilizador FPV", + "fr": "FPV gimbal initialization error", + "ja": "FPVジンバル初期化エラー", + "ko": "FPV 짐벌 초기화 오류", + "ru": "Ошибка инициализации стабилизатора курсовой камеры", + "tr": "FPV gimbal başlatma hatası", + "zh": "FPV云台初始化异常" + }, + "fpv_tip_0x1D100002": { + "de": "Gimbal reagiert nicht nach dem Einschalten", + "en": "Gimbal unresponsive after power on", + "es": "El estabilizador no responde después del encendido", + "fr": "Pas de réponse de la nacelle après la mise sous tension", + "ja": "電源オンの後にジンバル反応なし", + "ko": "전원을 켠 후 짐벌이 응답하지 않음", + "ru": "Стабилизатор не отвечает после включения питания", + "tr": "Gimbal açıldıktan sonra yanıt vermiyor", + "zh": "云台上电后无力" + }, + "fpv_tip_0x1D100006": { + "de": "Gimbal reagiert nicht nach dem Einschalten", + "en": "Gimbal unresponsive after power on", + "es": "El estabilizador no responde después del encendido", + "fr": "Pas de réponse de la nacelle après la mise sous tension", + "ja": "電源オンの後にジンバル反応なし", + "ko": "전원을 켠 후 짐벌이 응답하지 않음", + "ru": "Стабилизатор не отвечает после включения питания", + "tr": "Gimbal açıldıktan sonra yanıt vermiyor", + "zh": "云台上电后无力" + }, + "fpv_tip_0x1D110002": { + "de": "Gimbal kann automatische Überprüfung nicht abschließen", + "en": "Gimbal unable to complete auto check", + "es": "El estabilizador no puede completar la comprobación automática", + "fr": "Nacelle incapable de terminer la vérification automatique", + "ja": "ジンバルの自動確認を完了できません", + "ko": "짐벌 자동 점검 완료 불가", + "ru": "Не удалось выполнить автоматическую проверку стабилизатора", + "tr": "Gimbal otomatik kontrolü tamamlanamıyor", + "zh": "云台无法完成自检" + }, + "fpv_tip_0x1D110005": { + "de": "Gimbal kann automatische Überprüfung nicht abschließen", + "en": "Gimbal unable to complete auto check", + "es": "El estabilizador no puede completar la comprobación automática", + "fr": "Nacelle incapable de terminer la vérification automatique", + "ja": "ジンバルの自動確認を完了できません", + "ko": "짐벌 자동 점검 완료 불가", + "ru": "Не удалось выполнить автоматическую проверку стабилизатора", + "tr": "Gimbal otomatik kontrolü tamamlanamıyor", + "zh": "云台无法完成自检" + }, + "fpv_tip_0x1D120001": { + "de": "Fehler bei automatischer Gimbal-Überprüfung erkannt", + "en": "Error detected during gimbal auto check", + "es": "Error detectado durante la comprobación automática del estabilizador", + "fr": "Erreur détectée lors de la vérification automatique de la nacelle", + "ja": "ジンバルの自動確認中にエラー検出", + "ko": "짐벌 자동 점검 중 오류 감지", + "ru": "Во время автоматической проверки стабилизатора обнаружена ошибка", + "tr": "Gimbal otomatik kontrolü sırasında hata tespit edildi", + "zh": "云台自检后异常" + }, + "fpv_tip_0x1D120002": { + "de": "Fehler bei automatischer Gimbal-Überprüfung erkannt", + "en": "Error detected during gimbal auto check", + "es": "Error detectado durante la comprobación automática del estabilizador", + "fr": "Erreur détectée lors de la vérification automatique de la nacelle", + "ja": "ジンバルの自動確認中にエラー検出", + "ko": "짐벌 자동 점검 중 오류 감지", + "ru": "Во время автоматической проверки стабилизатора обнаружена ошибка", + "tr": "Gimbal otomatik kontrolü sırasında hata tespit edildi", + "zh": "云台自检后异常" + }, + "fpv_tip_0x1D120004": { + "de": "Fehler bei automatischer Gimbal-Überprüfung erkannt", + "en": "Error detected during gimbal auto check", + "es": "Error detectado durante la comprobación automática del estabilizador", + "fr": "Erreur détectée lors de la vérification automatique de la nacelle", + "ja": "ジンバルの自動確認中にエラー検出", + "ko": "짐벌 자동 점검 중 오류 감지", + "ru": "Во время автоматической проверки стабилизатора обнаружена ошибка", + "tr": "Gimbal otomatik kontrolü sırasında hata tespit edildi", + "zh": "云台自检后异常" + }, + "fpv_tip_0x1D120006": { + "de": "Fehler bei automatischer Gimbal-Überprüfung erkannt", + "en": "Error detected during gimbal auto check", + "es": "Error detectado durante la comprobación automática del estabilizador", + "fr": "Erreur détectée lors de la vérification automatique de la nacelle", + "ja": "ジンバルの自動確認中にエラー検出", + "ko": "짐벌 자동 점검 중 오류 감지", + "ru": "Во время автоматической проверки стабилизатора обнаружена ошибка", + "tr": "Gimbal otomatik kontrolü sırasında hata tespit edildi", + "zh": "云台自检后异常" + }, + "fpv_tip_0x1D130003": { + "de": "Übermäßige Vibrationen am Gimbal", + "en": "Excessive gimbal vibration", + "es": "Vibración del estabilizador excesiva", + "fr": "Vibration excessive de la nacelle", + "ja": "ジンバルの過剰な振動", + "ko": "과도한 짐벌 진동", + "ru": "Чрезмерная вибрация стабилизатора", + "tr": "Gimbal aşırı titriyor", + "zh": "云台异常振动" + }, + "fpv_tip_0x1D130005": { + "de": "Übermäßige Vibrationen am Gimbal", + "en": "Excessive gimbal vibration", + "es": "Vibración del estabilizador excesiva", + "fr": "Vibration excessive de la nacelle", + "ja": "ジンバルの過剰な振動", + "ko": "과도한 짐벌 진동", + "ru": "Чрезмерная вибрация стабилизатора", + "tr": "Gimbal aşırı titriyor", + "zh": "云台异常振动" + }, + "fpv_tip_0x1D13000A": { + "de": "Übermäßige Vibrationen am Gimbal", + "en": "Excessive gimbal vibration", + "es": "Vibración del estabilizador excesiva", + "fr": "Vibration excessive de la nacelle", + "ja": "ジンバルの過剰な振動", + "ko": "과도한 짐벌 진동", + "ru": "Чрезмерная вибрация стабилизатора", + "tr": "Gimbal aşırı titriyor", + "zh": "云台异常振动" + }, + "fpv_tip_0x1D140001": { + "de": "Gimbal-Motor überlastet", + "en": "Gimbal motor overloaded", + "es": "Motor del estabilizador sobrecargado", + "fr": "Surcharge du moteur de nacelle", + "ja": "ジンバルモーター過負荷状態", + "ko": "짐벌 모터 과부하", + "ru": "Двигатель стабилизатора перегружен", + "tr": "Gimbal motoru aşırı yüklü", + "zh": "云台电机过载" + }, + "fpv_tip_0x1D150002": { + "de": "Abdriften von Gimbal", + "en": "Gimbal drifting", + "es": "Desplazamiento del estabilizador", + "fr": "Dérive de la nacelle", + "ja": "ジンバルドリフト発生", + "ko": "짐벌 드리프트", + "ru": "Стабилизатор смещается", + "tr": "Gimbal kayıyor", + "zh": "云台自动漂移" + }, + "fpv_tip_0x1D150003": { + "de": "Abdriften von Gimbal", + "en": "Gimbal drifting", + "es": "Desplazamiento del estabilizador", + "fr": "Dérive de la nacelle", + "ja": "ジンバルドリフト発生", + "ko": "짐벌 드리프트", + "ru": "Стабилизатор смещается", + "tr": "Gimbal kayıyor", + "zh": "云台自动漂移" + }, + "fpv_tip_0x1D150004": { + "de": "Abdriften von Gimbal", + "en": "Gimbal drifting", + "es": "Desplazamiento del estabilizador", + "fr": "Dérive de la nacelle", + "ja": "ジンバルドリフト発生", + "ko": "짐벌 드리프트", + "ru": "Стабилизатор смещается", + "tr": "Gimbal kayıyor", + "zh": "云台自动漂移" + }, + "fpv_tip_0x1D150005": { + "de": "Abdriften von Gimbal", + "en": "Gimbal drifting", + "es": "Desplazamiento del estabilizador", + "fr": "Dérive de la nacelle", + "ja": "ジンバルドリフト発生", + "ko": "짐벌 드리프트", + "ru": "Стабилизатор смещается", + "tr": "Gimbal kayıyor", + "zh": "云台自动漂移" + }, + "fpv_tip_0x1D160004": { + "de": "Kamera geneigt", + "en": "Camera tilted", + "es": "Cámara inclinada", + "fr": "Caméra inclinée", + "ja": "カメラが傾いています", + "ko": "카메라 기울어짐", + "ru": "Камера наклонена", + "tr": "Kamera eğik", + "zh": "相机视频歪斜" + }, + "fpv_tip_0x1D170001": { + "de": "Gimbal-Fehler", + "en": "Gimbal error", + "es": "Error del estabilizador", + "fr": "Erreur de nacelle", + "ja": "ジンバルエラー", + "ko": "짐벌 오류", + "ru": "Ошибка стабилизатора", + "tr": "Gimbal hatası", + "zh": "云台功能异常" + }, + "fpv_tip_0x1D180001": { + "de": "Datenfehler bei Gimbal-Kalibrierung", + "en": "Gimbal calibration data error", + "es": "Error de datos de calibración del estabilizador", + "fr": "Erreur de données d\\'étalonnage de la nacelle", + "ja": "ジンバル キャリブレーション データ エラー", + "ko": "짐벌 캘리브레이션 데이터 오류", + "ru": "Ошибка данных калибровки стабилизатора", + "tr": "Gimbal kalibrasyon verisi hatası", + "zh": "云台校准数据异常" + }, + "fpv_tip_0x1D190002": { + "de": "Gimbal-Aktualisierung fehlgeschlagen", + "en": "Gimbal update failed", + "es": "Error de actualización del estabilizador", + "fr": "Échec de la mise à jour de la nacelle", + "ja": "ジンバルの更新に失敗しました", + "ko": "짐벌 업데이트 실패", + "ru": "Не удалось обновить стабилизатор", + "tr": "Gimbal güncellemesi başarısız", + "zh": "云台升级失败" + }, + "fpv_tip_0x1E00000": { + "en": "", + "zh": "喊话器与机身发生共振,供电已断开,请等待自行恢复" + }, + "fpv_tip_0x1E000001": { + "de": "Startfehler: Nutzlast %component_index", + "en": "Payload %component_index startup error", + "es": "Error de inicio del instrumento %component_index", + "fr": "Erreur démarrage charge utile %component_index", + "ja": "ペイロード%component_index開始エラー", + "ko": "페이로드 %component_index 시작 오류", + "ru": "Ошибка запуска оборудования %component_index", + "tr": "Yük %component_index başlatma hatası", + "zh": "%component_index号负载启动异常" + }, + "fpv_tip_0x1E000002": { + "de": "Kommunikationsfehler: Nutzlast %component_index", + "en": "Payload %component_index communication error", + "es": "Error de comunicación del instrumento %component_index", + "fr": "Erreur communication charge utile %component_index", + "ja": "ペイロード%component_index通信エラー", + "ko": "페이로드 %component_index 통신 오류", + "ru": "Ошибка связи оборудования %component_index", + "tr": "Yük %component_index iletişim hatası", + "zh": "%component_index号负载通讯异常" + }, + "fpv_tip_0x1E000003": { + "de": "Nutzlast %component_index überhitzt", + "en": "Payload %component_index overheated", + "es": "Instrumento %component_index sobrecalentado", + "fr": "Surchauffe charge utile %component_index", + "ja": "ペイロード%component_index高温", + "ko": "페이로드 %component_index 과열", + "ru": "Перегрев оборудования %component_index", + "tr": "Yük %component_index aşırı ısındı", + "zh": "%component_index号负载温度过高" + }, + "fpv_tip_0x1E000004": { + "de": "Hardwarefehler: Nutzlast %component_index", + "en": "Payload %component_index hardware error", + "es": "Error de hardware del instrumento %component_index", + "fr": "Erreur matérielle charge utile %component_index", + "ja": "ペイロード%component_indexハードウェアエラー", + "ko": "페이로드 %component_index 하드웨어 오류", + "ru": "Ошибка аппаратуры оборудования %component_index", + "tr": "Yük %component_index donanım hatası", + "zh": "%component_index号负载硬件异常" + }, + "fpv_tip_0x1E000006": { + "de": "Lautsprecher schwingt mit dem Fluggerät mit. Stromversorgung unterbrochen. Auf Wiederherstellung der Stromversorgung warten", + "en": "Speaker resonates with the aircraft. Power supply disconnected. Wait for power supply to recover", + "es": "El altavoz resuena con la aeronave. Fuente de alimentación desconectada. Espere a que se recupere la fuente de alimentación", + "fr": "Le haut-parleur résonne avec l’appareil. Alimentation déconnectée. Attendez que l’alimentation se rétablisse", + "ja": "スピーカーが機体と共鳴しています。電源接続が切断されました。電源が回復するまで待機してください", + "ko": "스피커가 기체와 공명합니다. 전력 공급 장치가 분리되었습니다. 전력 공급 장치가 복구될 때까지 기다리세요", + "ru": "Динамик резонирует с дроном. Питание отключено. Дождитесь восстановления питания", + "tr": "Hoparlör hava aracıyla rezonansa giriyor. Güç kaynağı bağlantısı kesildi. Güç kaynağının düzeltilmesini bekleyin", + "zh": "喊话器与机身发生共振,供电已断开,请等待自行恢复" + }, + "fpv_tip_0x1E010001": { + "de": "Lautsprecher überhitzt. Übermittlungslautstärke reduzieren oder warten, bis Lautsprecher abgekühlt ist", + "en": "Speaker overheats. Lower broadcast volume or wait until speaker cools down", + "es": "El altavoz se sobrecalienta. Reduce el volumen o espera a que el altavoz se enfríe.", + "fr": "Surchauffe du haut-parleur. Diminuez le volume de diffusion ou attendez que le haut-parleur refroidisse", + "ja": "スピーカーが過熱状態。放送音声の音量を下げるか、スピーカーが冷えるまでお待ちください", + "ko": "스피커 과열. 방송 볼륨을 낮추거나 스피커가 식을 때까지 기다리세요.", + "ru": "Динамик перегревается. Уменьшите громкость вещания или подождите, пока динамик остынет", + "tr": "Hoparlör aşırı ısındı. Yayının ses seviyesini düşürün veya hoparlör soğuyana kadar bekleyin", + "zh": "喊话器温度过高,请尝试降低音量或冷却后再使用" + }, + "fpv_tip_0x1E010002": { + "ar": "", + "de": "Hardwarefehler: Lautsprecher. Fluggerät neu starten", + "en": "Speaker hardware error. Contact DJI Support", + "es": "Error de hardware del altavoz. Reinicia la aeronave.", + "fr": "Erreur matérielle du haut-parleur. Redémarrez l'appareil", + "it": "", + "ja": "スピーカーのハードウェアエラー。機体を再起動してください", + "ko": "스피커 하드웨어 오류. 기체를 재시작하세요.", + "pt": "", + "ru": "Аппаратная ошибка динамика. Перезапустите дрон", + "tr": "Hoparlör donanım hatası. Hava aracını yeniden başlatın", + "zh": "喊话器硬件异常,请联系售后服务" + }, + "fpv_tip_0x1E010003": { + "de": "Lautsprecher überlastet. Fluggerät neu starten", + "en": "Speaker overloaded. Restart aircraft", + "es": "Altavoz sobrecargado. Reinicia la aeronave.", + "fr": "Haut-parleur surchargé. Redémarrez l'appareil", + "ja": "スピーカーが過負荷状態。機体を再起動してください", + "ko": "스피커 과부하. 기체를 재시작하세요.", + "ru": "Динамик перегружен. Перезапустите дрон", + "tr": "Hoparlör aşırı yüklendi. Hava aracını yeniden başlatın", + "zh": "喊话器过载,请重启飞行器" + }, + "fpv_tip_0x1F010000": { + "de": "4G service: unable to obtain license. Contact DJI Support", + "en": "4G service: unable to obtain license. Contact DJI Support", + "es": "4G service: unable to obtain license. Contact DJI Support", + "fr": "4G service: unable to obtain license. Contact DJI Support", + "ja": "4G service: unable to obtain license. Contact DJI Support", + "ko": "4G service: unable to obtain license. Contact DJI Support", + "ru": "4G service: unable to obtain license. Contact DJI Support", + "tr": "4G service: unable to obtain license. Contact DJI Support", + "zh": "4G服务:License无法获取,请联系DJI售后服务" + }, + "fpv_tip_0x1F010001": { + "de": "4G service: license expired. Import valid license", + "en": "4G service: license expired. Import valid license", + "es": "4G service: license expired. Import valid license", + "fr": "4G service: license expired. Import valid license", + "ja": "4G service: license expired. Import valid license", + "ko": "4G service: license expired. Import valid license", + "ru": "4G service: license expired. Import valid license", + "tr": "4G service: license expired. Import valid license", + "zh": "4G服务:License过期,请导入有效证书" + }, + "fpv_tip_0x1F010002": { + "de": "4G service: license verification failed. Contact DJI Support", + "en": "4G service: license verification failed. Contact DJI Support", + "es": "4G service: license verification failed. Contact DJI Support", + "fr": "4G service: license verification failed. Contact DJI Support", + "ja": "4G service: license verification failed. Contact DJI Support", + "ko": "4G service: license verification failed. Contact DJI Support", + "ru": "4G service: license verification failed. Contact DJI Support", + "tr": "4G service: license verification failed. Contact DJI Support", + "zh": "4G服务:License校验失败,请联系DJI售后服务" + }, + "fpv_tip_0x1F010003": { + "de": "4G service: device SN unauthorized. Authorize device SN", + "en": "4G service: device SN unauthorized. Authorize device SN", + "es": "4G service: device SN unauthorized. Authorize device SN", + "fr": "4G service: device SN unauthorized. Authorize device SN", + "ja": "4G service: device SN unauthorized. Authorize device SN", + "ko": "4G service: device SN unauthorized. Authorize device SN", + "ru": "4G service: device SN unauthorized. Authorize device SN", + "tr": "4G service: device SN unauthorized. Authorize device SN", + "zh": "4G服务:设备SN未授权,请授权设备SN" + }, + "fpv_tip_0x1F010004": { + "de": "4G service: device SN unauthorized. Purchase upgrade package", + "en": "4G service: device SN unauthorized. Purchase upgrade package", + "es": "4G service: device SN unauthorized. Purchase upgrade package", + "fr": "4G service: device SN unauthorized. Purchase upgrade package", + "ja": "4G service: device SN unauthorized. Purchase upgrade package", + "ko": "4G service: device SN unauthorized. Purchase upgrade package", + "ru": "4G service: device SN unauthorized. Purchase upgrade package", + "tr": "4G service: device SN unauthorized. Purchase upgrade package", + "zh": "4G服务:设备型号未授权,请购买扩容套餐" + }, + "fpv_tip_0x1F010005": { + "de": "4G service: the number of connected devices exceeds authorized number. Purchase upgrade package", + "en": "4G service: the number of connected devices exceeds authorized number. Purchase upgrade package", + "es": "4G service: the number of connected devices exceeds authorized number. Purchase upgrade package", + "fr": "4G service: the number of connected devices exceeds authorized number. Purchase upgrade package", + "ja": "4G service: the number of connected devices exceeds authorized number. Purchase upgrade package", + "ko": "4G service: the number of connected devices exceeds authorized number. Purchase upgrade package", + "ru": "4G service: the number of connected devices exceeds authorized number. Purchase upgrade package", + "tr": "4G service: the number of connected devices exceeds authorized number. Purchase upgrade package", + "zh": "4G服务:设备连接数量超过授权,请购买扩容套餐" + }, + "fpv_tip_0x1F010006": { + "de": "4G service: device firmware version too early. Upgrade firmware", + "en": "4G service: device firmware version too early. Upgrade firmware", + "es": "4G service: device firmware version too early. Upgrade firmware", + "fr": "4G service: device firmware version too early. Upgrade firmware", + "ja": "4G service: device firmware version too early. Upgrade firmware", + "ko": "4G service: device firmware version too early. Upgrade firmware", + "ru": "4G service: device firmware version too early. Upgrade firmware", + "tr": "4G service: device firmware version too early. Upgrade firmware", + "zh": "4G服务:设备固件版本过低,请升级固件" + }, + "fpv_tip_0x1F010007": { + "de": "4G service: server version too early. Upgrade server", + "en": "4G service: server version too early. Upgrade server", + "es": "4G service: server version too early. Upgrade server", + "fr": "4G service: server version too early. Upgrade server", + "ja": "4G service: server version too early. Upgrade server", + "ko": "4G service: server version too early. Upgrade server", + "ru": "4G service: server version too early. Upgrade server", + "tr": "4G service: server version too early. Upgrade server", + "zh": "4G服务:服务器版本过低,请升级服务器" + }, + "fpv_tip_0x1F010008": { + "de": "4G service: requested parameter error. Contact DJI Support", + "en": "4G service: requested parameter error. Contact DJI Support", + "es": "4G service: requested parameter error. Contact DJI Support", + "fr": "4G service: requested parameter error. Contact DJI Support", + "ja": "4G service: requested parameter error. Contact DJI Support", + "ko": "4G service: requested parameter error. Contact DJI Support", + "ru": "4G service: requested parameter error. Contact DJI Support", + "tr": "4G service: requested parameter error. Contact DJI Support", + "zh": "4G服务:请求参数错误,请联系DJI售后服务" + }, + "fpv_tip_0x1F010009": { + "de": "4G service: server internal error. Contact DJI Support", + "en": "4G service: server internal error. Contact DJI Support", + "es": "4G service: server internal error. Contact DJI Support", + "fr": "4G service: server internal error. Contact DJI Support", + "ja": "4G service: server internal error. Contact DJI Support", + "ko": "4G service: server internal error. Contact DJI Support", + "ru": "4G service: server internal error. Contact DJI Support", + "tr": "4G service: server internal error. Contact DJI Support", + "zh": "4G服务:服务器内部错误,请联系DJI售后服务" + }, + "fpv_tip_0x1F01000A": { + "de": "4G service: unable to obtain license. Contact DJI Support", + "en": "4G service: unable to obtain license. Contact DJI Support", + "es": "4G service: unable to obtain license. Contact DJI Support", + "fr": "4G service: unable to obtain license. Contact DJI Support", + "ja": "4G service: unable to obtain license. Contact DJI Support", + "ko": "4G service: unable to obtain license. Contact DJI Support", + "ru": "4G service: unable to obtain license. Contact DJI Support", + "tr": "4G service: unable to obtain license. Contact DJI Support", + "zh": "4G服务:证书无法读取,请联系DJI售后服务" + }, + "fpv_tip_0x1F01000B": { + "de": "4G service: license expired. Import valid license", + "en": "4G service: license expired. Import valid license", + "es": "4G service: license expired. Import valid license", + "fr": "4G service: license expired. Import valid license", + "ja": "4G service: license expired. Import valid license", + "ko": "4G service: license expired. Import valid license", + "ru": "4G service: license expired. Import valid license", + "tr": "4G service: license expired. Import valid license", + "zh": "4G服务:证书过期,请导入有效证书" + }, + "fpv_tip_0x1F01000C": { + "de": "4G service: license verification failed. Contact DJI Support", + "en": "4G service: license verification failed. Contact DJI Support", + "es": "4G service: license verification failed. Contact DJI Support", + "fr": "4G service: license verification failed. Contact DJI Support", + "ja": "4G service: license verification failed. Contact DJI Support", + "ko": "4G service: license verification failed. Contact DJI Support", + "ru": "4G service: license verification failed. Contact DJI Support", + "tr": "4G service: license verification failed. Contact DJI Support", + "zh": "4G服务:证书校验失败,请联系DJI售后服务" + }, + "fpv_tip_0x1F010063": { + "de": "4G service: system unknown error. Contact DJI Support", + "en": "4G service: system unknown error. Contact DJI Support", + "es": "4G service: system unknown error. Contact DJI Support", + "fr": "4G service: system unknown error. Contact DJI Support", + "ja": "4G service: system unknown error. Contact DJI Support", + "ko": "4G service: system unknown error. Contact DJI Support", + "ru": "4G service: system unknown error. Contact DJI Support", + "tr": "4G service: system unknown error. Contact DJI Support", + "zh": "4G服务:系统未知错误,请联系DJI售后服务" + }, + "fpv_tip_0x1F0B0001": { + "de": "Fluggerät: LTE-Übertragung nicht möglich. Datenverbindung instabil oder mit SIM-Karte nicht möglich", + "en": "Aircraft unable to use LTE Transmission. Network connection unstable or SIM card unable to connect to network", + "es": "La aeronave no puede utilizar la transmisión LTE. Conexión de red inestable o la tarjeta SIM no se puede conectar a la red", + "fr": "L\\'appareil ne peut utiliser la transmission LTE. Connexion au réseau instable ou carte SIM incapable de se connecter au réseau", + "ja": "機体がLTE伝送を使用できません。ネットワーク接続不安定、またはSIMカードがネットワークに接続できません", + "ko": "기체가 LTE 전송을 사용할 수 없습니다. 네트워크 연결이 불안정하거나 SIM 카드를 네트워크에 연결할 수 없습니다", + "ru": "Дрону не удается использовать передачу по LTE. Подключение к сети нестабильно, или невозможно подключить SIM-карту к сети", + "tr": "Araç LTE İletimini kullanamıyor. Ağ bağlantısı istikrarlı değil ya da SIM kart ağa bağlanamıyor", + "zh": "飞机无法使用LTE链路,网络波动或SIM卡无法访问网络" + }, + "fpv_tip_0x1F0B0002": { + "de": "Kein Netz auf DJI Mobilfunk-Dongle der Fernsteuerung", + "en": "No network on DJI Cellular Dongle of remote controller", + "es": "No hay red en el adaptador de red móvil de DJI del control remoto", + "fr": "Pas de réseau sur le dongle cellulaire DJI de la radiocommande", + "ja": "送信機のDJIセルラードングルでネットワークを利用できません", + "ko": "조종기 DJI 셀룰러 동글이 네트워크에 연결되어 있지 않습니다", + "ru": "Нет сети на DJI Cellular Dongle пульта дистанционного управления", + "tr": "Uzaktan kumandanın DJI Hücresel Dongle'ında ağ yok", + "zh": "遥控器DJI Cellular模块无法访问网络" + }, + "fpv_tip_0x1F0B0003": { + "de": "LTE-Server und LTE-Übertragung nicht verfügbar", + "en": "LTE Server and LTE Transmission unavailable", + "es": "Servidor LTE y transmisión LTE no disponibles", + "fr": "Serveur LTE et transmission LTE indisponibles", + "ja": "LTEサーバやLTE伝送が利用できません。", + "ko": "LTE 서버 및 LTE 전송을 사용할 수 없습니다", + "ru": "Сервер LTE и передача по LTE недоступны", + "tr": "LTE Sunucusu ve LTE İletimi kullanılamıyor", + "zh": "LTE服务器不可用,LTE链路不可用" + }, + "fpv_tip_0x1F0B0004": { + "de": "LTE-Server und LTE-Übertragung nicht verfügbar", + "en": "LTE Server and LTE Transmission unavailable", + "es": "Servidor LTE y transmisión LTE no disponibles", + "fr": "Serveur LTE et transmission LTE indisponibles", + "ja": "LTEサーバーやLTE伝送が利用できません", + "ko": "LTE 서버 및 LTE 전송 사용 불가", + "ru": "Сервер LTE и передача по LTE недоступны", + "tr": "LTE Sunucusu ve LTE İletimi kullanılamıyor", + "zh": "LTE服务器不可用,LTE链路不可用" + }, + "fpv_tip_0x1F0B0005": { + "de": "LTE-Übertragung nicht verfügbar. Überprüfen, ob Fernsteuerung und Fluggerät richtig gekoppelt sind", + "en": "LTE Transmission unavailable. Check and ensure remote controller and aircraft are linked properly", + "es": "Transmisión LTE no disponible. Comprueba el control remoto y la aeronave y asegúrate de que estén vinculados correctamente", + "fr": "Transmission LTE indisponible. Assurez-vous que la radiocommande et l\\'appareil sont bien connectés", + "ja": "LTE伝送は使用できません。。送信機と機体が適切にリンクされていることを確認してください", + "ko": "LTE 전송을 사용할 수 없습니다. LTE 전송 사용 불가", + "ru": "Передача по LTE недоступна. Проверьте и убедитесь, что пульт ДУ и дрон сопряжены должным образом", + "tr": "LTE İletimi kullanılamıyor. Uzaktan kumandanın ve aracın doğru şekilde bağlanıp bağlanmadığını kontrol edin", + "zh": "LTE链路不可用,请确认遥控器和飞机已成功对频" + }, + "fpv_tip_0x1F0B0006": { + "de": "LTE-Übertragung nicht verfügbar. Fernsteuerung neu starten", + "en": "LTE Transmission unavailable. Restart remote controller", + "es": "Transmisión LTE no disponible. Reinicia el control remoto", + "fr": "Transmission LTE indisponible. Redémarrez la radiocommande", + "ja": "LTE伝送は使用できません。送信機を再起動してください", + "ko": "LTE 전송을 사용할 수 없습니다. 조종기를 다시 시작하세요", + "ru": "Передача по LTE недоступна. Перезапустите пульт ДУ", + "tr": "LTE İletimi kullanılamıyor. Uzaktan kumandayı yeniden başlatın", + "zh": "LTE链路不可用,请重启遥控器" + }, + "fpv_tip_0x1F0B0007": { + "de": "LTE-Übertragung nicht verfügbar. 4G-Dongle-Netzwerkkonnektivität des Fluggeräts überprüfen", + "en": "LTE Transmission unavailable. Check aircraft 4G Dongle network connectivity", + "es": "Transmisión LTE no disponible. Comprueba la conectividad de red de la llave 4G de la aeronave", + "fr": "Transmission LTE indisponible. Vérifiez la connexion au réseau de la clé 4G de l\\'appareil", + "ja": "LTE伝送が利用不可。機体の4Gドングルネットワークの接続を確認してください", + "ko": "LTE 전송을 사용할 수 없습니다. 기체 4G 동글 네트워크 연결을 확인하세요", + "ru": "Передача по LTE недоступна. Проверьте подключение 4G-адаптера дрона к сети", + "tr": "LTE İletimi kullanılamıyor. Aracın 4G Modem ağ bağlantısını kontrol edin", + "zh": "LTE链路不可用,请检查飞机4G dongle的网络能力" + }, + "fpv_tip_0x1F0B0008": { + "de": "LTE-Übertragung nicht verfügbar. Fluggerät und Fernsteuerung neu starten", + "en": "LTE Transmission unavailable. Restart aircraft and remote controller", + "es": "Transmisión LTE no disponible. Reinicia la aeronave y el control remoto", + "fr": "Transmission LTE indisponible. Redémarrez l\\'appareil et la radiocommande", + "ja": "LTE伝送が利用不可。機体と送信機を再起動してください", + "ko": "LTE 전송을 사용할 수 없습니다. 기체와 조종기를 다시 시작하세요", + "ru": "Передача по LTE недоступна. Перезапустите дрон и пульт ДУ", + "tr": "LTE İletimi kullanılamıyor. Aracı ve uzaktan kumandayı yeniden başlatın", + "zh": "LTE链路不可用,请重启飞机和遥控器" + }, + "fpv_tip_0x1F0B0009": { + "de": "LTE-Übertragung nicht verfügbar. Fernsteuerung neu starten", + "en": "LTE Transmission unavailable. Restart remote controller", + "es": "Transmisión LTE no disponible. Reinicia el control remoto", + "fr": "Transmission LTE indisponible. Redémarrez la radiocommande", + "ja": "LTE通信は利用できません。送信機を再起動してください", + "ko": "LTE 전송 사용 불가. 조종기 다시 시작", + "ru": "Передача по LTE недоступна. Перезагрузите пульт ДУ", + "tr": "LTE İletimi kullanılamıyor. Uzaktan kumandayı yeniden başlatın", + "zh": "LTE链路不可用,请重启遥控器" + }, + "fpv_tip_0x1F0B0016": { + "de": "LTE-Übertragung nicht verfügbar. Netzwerkkonnektivität der Fernsteuerung überprüfen", + "en": "LTE Transmission unavailable. Check remote controller network connectivity", + "es": "Transmisión LTE no disponible. Comprueba la conectividad de red del control remoto", + "fr": "Transmission LTE non disponible. Vérifier la connectivité réseau de la radiocommande", + "ja": "LTE通信は利用できません。リモートコントローラーのネットワーク接続を確認してください", + "ko": "LTE 전송을 사용할 수 없습니다. 조종기 네트워크 연결을 확인하세요.", + "ru": "Передача по LTE недоступна. Проверьте подключение пульта ДУ к сети", + "tr": "LTE İletimi kullanılamıyor. Uzaktan kumanda ağ bağlanabilirliğini kontrol edin", + "zh": "LTE链路不可用,请检查遥控器的网络能力" + }, + "fpv_tip_0x1F0B0017": { + "de": "LTE-Übertragung nicht verfügbar. Netzwerkkonnektivität der Fernsteuerung überprüfen", + "en": "LTE Transmission unavailable. Check remote controller network connectivity", + "es": "Transmisión LTE no disponible. Comprueba la conectividad de red del control remoto", + "fr": "Transmission LTE non disponible. Vérifiez la connectivité réseau de la radiocommande", + "ja": "LTE通信は利用できません。リモートコントローラーのネットワーク接続を確認してください", + "ko": "LTE 전송을 사용할 수 없습니다. 조종기 네트워크 연결을 확인하세요.", + "ru": "Передача по LTE недоступна. Проверьте подключение пульта ДУ к сети", + "tr": "LTE İletimi kullanılamıyor. Uzaktan kumanda ağ bağlanabilirliğini kontrol edin", + "zh": "LTE链路不可用,请检查遥控器的网络能力" + }, + "fpv_tip_0x1F0B0018": { + "de": "LTE-Übertragung nicht verfügbar. Fluggerät und Fernsteuerung neu starten", + "en": "LTE Transmission unavailable. Restart aircraft and remote controller", + "es": "Transmisión LTE no disponible. Reinicia la aeronave y el control remoto", + "fr": "Transmission LTE indisponible. Redémarrez l\\'appareil et la radiocommande", + "ja": "LTE伝送が利用不可。機体と送信機を再起動してください", + "ko": "LTE 전송을 사용할 수 없습니다. 기체와 조종기를 다시 시작하세요", + "ru": "Передача по LTE недоступна. Перезапустите дрон и пульт ДУ", + "tr": "LTE İletimi kullanılamıyor. Aracı ve uzaktan kumandayı yeniden başlatın", + "zh": "LTE链路不可用,请重启飞机和遥控器" + }, + "fpv_tip_0x1F0B001A": { + "de": "LTE-Übertragung nicht verfügbar. 4G-Dongle-Netzwerkkonnektivität des Fluggeräts überprüfen", + "en": "LTE Transmission unavailable. Check aircraft 4G Dongle network connectivity", + "es": "Transmisión LTE no disponible. Comprueba la conectividad de red de la llave 4G de la aeronave", + "fr": "Transmission LTE indisponible. Vérifiez la connexion au réseau de la clé 4G de l'appareil", + "ja": "LTE通信は利用できません。機体の4Gドングルネットワークの接続を確認してください", + "ko": "LTE 전송 사용 불가. 기체 4G 동글 네트워크 연결을 확인하세요", + "ru": "Передача по LTE недоступна. Проверьте подключение 4G-адаптера дрона к сети", + "tr": "LTE İletimi kullanılamıyor. Aracın 4G Modem ağ bağlantısını kontrol edin", + "zh": "LTE链路不可用,请检查飞机4G dongle的网络能力" + }, + "fpv_tip_0x1F0B001B": { + "de": "LTE-Übertragung nicht verfügbar. Fluggerät und Fernsteuerung neu starten", + "en": "LTE Transmission unavailable. Restart aircraft and remote controller", + "es": "Transmisión LTE no disponible. Reinicia la aeronave y el control remoto", + "fr": "Transmission LTE indisponible. Redémarrez l'appareil et la radiocommande", + "ja": "LTE通信は利用できません。機体と送信機を再起動してください", + "ko": "LTE 전송 사용 불가. 기체와 조종기를 다시 시작하세요", + "ru": "Передача по LTE недоступна. Перезагрузите дрон и пульт ДУ", + "tr": "LTE İletimi kullanılamıyor. Aracı ve uzaktan kumandayı yeniden başlatın", + "zh": "LTE链路不可用,请重启飞机和遥控器" + }, + "fpv_tip_0x1F0B001C": { + "de": "LTE-Übertragungsfehler. Authentifizierungsdateien für Fluggerät fehlen. Lokalen Händler oder DJI Support kontaktieren", + "en": "LTE Transmission error. Aircraft authentication files missing. Contact your local dealer or DJI Support", + "es": "", + "fr": "Erreur transmission LTE. Fichiers d'authentification de l'appareil manquants. Contactez immédiatement votre revendeur local ou l'assistance technique DJI", + "it": "", + "ja": "LTE伝送エラー。機体認証ファイルがありません。最寄りの代理店またはDJIサポートにお問い合わせください", + "ko": "LTE 전송 오류. 기체 인증 파일이 없습니다. 현지 대리점 또는 DJI 고객지원팀에 연락하세요", + "pt": "", + "ru": "Ошибка передачи по LTE. Отсутствуют файлы аутентификации дрона. Обратитесь к местному дилеру или в службу поддержки DJI", + "tr": "", + "zh": "LTE链路异常,飞行器缺少认证文件,请联系大疆售后服务" + }, + "fpv_tip_0x1F0B001c": { + "de": "LTE-Übertragungsfehler. Authentifizierungsdateien für Fluggerät fehlen. Lokalen Händler oder DJI Support kontaktieren", + "en": "LTE Transmission error. Aircraft authentication files missing. Contact your local dealer or DJI Support", + "es": "", + "fr": "Erreur transmission LTE. Fichiers d'authentification de l'appareil manquants. Contactez immédiatement votre revendeur local ou l'assistance technique DJI", + "ja": "LTE伝送エラー。機体認証ファイルがありません。最寄りの代理店またはDJIサポートにお問い合わせください", + "ko": "LTE 전송 오류. 기체 인증 파일이 없습니다. 현지 대리점 또는 DJI 고객지원팀에 연락하세요", + "ru": "Ошибка передачи по LTE. Отсутствуют файлы аутентификации дрона. Обратитесь к местному дилеру или в службу поддержки DJI", + "tr": "", + "zh": "LTE链路异常,飞行器缺少认证文件,请联系大疆售后服务" + }, + "fpv_tip_0x1F0B001d": { + "de": "LTE-Übertragungsfehler. Authentifizierungsdateien für Fernsteuerung fehlen. Lokalen Händler oder DJI Support kontaktieren", + "en": "LTE Transmission error. Remote controller authentication files missing. Contact your local dealer or DJI Support", + "es": "", + "fr": "Erreur transmission LTE. Fichiers d'authentification de la radiocommande manquants. Contactez votre revendeur local ou l'assistance technique DJI", + "ja": "LTE伝送エラー。送信機認証ファイルがありません。最寄りの代理店またはDJIサポートにお問い合わせください", + "ko": "LTE 전송 오류. 조종기 인증 파일이 없습니다. 현지 대리점 또는 DJI 고객지원팀에 연락하세요", + "ru": "Ошибка передачи по LTE. Отсутствуют файлы аутентификации пульта ДУ. Обратитесь к местному дилеру или в службу поддержки DJI", + "tr": "", + "zh": "LTE链路异常,遥控器缺少认证文件,请联系大疆售后服务" + }, + "fpv_tip_0x1F0B0020": { + "de": "Aktualisierung des DJI Mobilfunkmodul-Dongles des Fluggeräts erforderlich", + "en": "Update DJI Cellular Dongle of aircraft required", + "es": "Es necesario actualizar el adaptador de red móvil de DJI de la aeronave.", + "fr": "Mise à jour requise du dongle cellulaire DJI de l'appareil", + "ja": "機体のDJIセルラードングルの更新が必要です", + "ko": "기체의 DJI 셀룰러 동글 업데이트 필요", + "ru": "Обновите DJI Cellular Dongle дрона", + "tr": "Hava aracının DJI Hücresel Dongle'ının güncellenmesi gerekiyor", + "zh": "飞行器 DJI Cellular 模块需要升级" + }, + "fpv_tip_0x1F0B0021": { + "de": "Aktualisierung des DJI Mobilfunkmodul-Dongles der Fernsteuerung erforderlich", + "en": "Update DJI Cellular Dongle of remote controller required", + "es": "Es necesario actualizar el adaptador de red móvil de DJI del control remoto.", + "fr": "Mise à jour requise du dongle cellulaire DJI de la radiocommande", + "ja": "送信機のDJIセルラードングルの更新が必要です", + "ko": "조종기의 DJI 셀룰러 동글 업데이트 필요", + "ru": "Обновите DJI Cellular Dongle пульта дистанционного управления", + "tr": "Uzaktan kumandanın DJI Hücresel Dongle'ının güncellenmesi gerekiyor", + "zh": "遥控器 DJI Cellular 模块需升级" + }, + "fpv_tip_0x1F0B0022": { + "ar": "", + "de": "", + "en": "Airplane mode enabled or Wi-Fi and mobile data disabled on mobile device. Unable to connect", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "手机进入飞行模式或者关闭wifi及移动网络,无法发起移动网络通信", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B0023": { + "de": "Schwaches LTE-Signal. Mit Vorsicht fliegen", + "en": "LTE signal weak. Fly with caution", + "es": "Señal de LTE débil. Vuela con cuidado.", + "fr": "Signal LTE faible. Pilotez avec précaution", + "ja": "LTE信号 弱。慎重に飛行してください", + "ko": "LTE 신호 약함. 비행 시 주의 필요", + "ru": "Слабый сигнал LTE. Будьте внимательны при полете", + "tr": "LTE sinyali zayıf. Dikkatlice uçun.", + "zh": "LTE 信号弱,请谨慎飞行" + }, + "fpv_tip_0x1F0B0024": { + "de": "Schwaches LTE-Signal. Mit Vorsicht fliegen", + "en": "LTE signal weak. Fly with caution", + "es": "Señal de LTE débil. Vuela con cuidado.", + "fr": "Signal LTE faible. Pilotez avec précaution", + "ja": "LTE信号 弱。慎重に飛行してください", + "ko": "LTE 신호 약함. 비행 시 주의 필요", + "ru": "Слабый сигнал LTE. Будьте внимательны при полете", + "tr": "LTE sinyali zayıf. Dikkatlice uçun.", + "zh": "LTE 信号弱,请谨慎飞行" + }, + "fpv_tip_0x1F0B0025": { + "de": "Schwaches LTE-Signal. Mit Vorsicht fliegen", + "en": "LTE signal weak. Fly with caution", + "es": "Señal de LTE débil. Vuela con cuidado.", + "fr": "Signal LTE faible. Pilotez avec précaution", + "ja": "LTE信号 弱。慎重に飛行してください", + "ko": "LTE 신호 약함. 비행 시 주의 필요", + "ru": "Слабый сигнал LTE. Будьте внимательны при полете", + "tr": "LTE sinyali zayıf. Dikkatlice uçun.", + "zh": "LTE 信号弱,请谨慎飞行" + }, + "fpv_tip_0x1F0B0026": { + "ar": "", + "de": "", + "en": "Insufficient data allowance on SIM card. Fly with caution", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "SIM卡流量不足,请谨慎飞行", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B0027": { + "de": "Aktualisierung der LTE-Zertifizierung des Fluggeräts erforderlich. An Händler vor Ort oder an DJI Support wenden", + "en": "Aircraft LTE certification update required. Contact your local dealer or DJI Support", + "es": "Es necesario actualizar la certificación LTE de la aeronave. Ponte en contacto con el distribuidor local o el servicio de asistencia técnica de DJI.", + "fr": "Mise à jour de la certification LTE de l'appareil nécessaire. Contactez votre revendeur local ou le service client DJI", + "ja": "機体のLTE認定の更新が必要です。最寄りの代理店またはDJIサポートにお問い合わせください", + "ko": "기체 LTE 인증 업데이트 필요. 지역 딜러 또는 DJI 고객지원에 문의하세요.", + "ru": "Требуется обновление сертификации LTE для дрона. Обратитесь к местному представителю или в службу поддержки DJI", + "tr": "Hava aracı LTE sertifika güncellemesi gerekiyor. Bölgenizdeki satıcıyla veya DJI Destek ile iletişime geçin", + "zh": "飞行器 LTE 证书需更新,请联系售后或代理商" + }, + "fpv_tip_0x1F0B0028": { + "de": "Aktualisierung der LTE-Zertifizierung der Fernsteuerung erforderlich. An Händler vor Ort oder an DJI Support wenden", + "en": "Remote controller LTE certification update required. Contact your local dealer or DJI Support", + "es": "Es necesario actualizar la certificación LTE del control remoto. Ponte en contacto con el distribuidor local o el servicio de asistencia técnica de DJI.", + "fr": "Mise à jour de la certification LTE de la radiocommande. Contactez votre revendeur local ou le service client DJI", + "ja": "送信機のLTE認定の更新が必要です。最寄りの代理店またはDJIサポートにお問い合わせください", + "ko": "조종기 LTE 인증 업데이트 필요. 지역 딜러 또는 DJI 고객지원에 문의하세요.", + "ru": "Требуется обновление сертификации LTE для пульта дистанционного управления. Обратитесь к местному представителю или в службу поддержки DJI", + "tr": "Uzaktan kumanda LTE sertifika güncellemesi gerekiyor. Bölgenizdeki satıcıyla veya DJI Destek ile iletişime geçin", + "zh": "遥控器 LTE 证书需更新,请联系售后或代理商" + }, + "fpv_tip_0x1F0B0029": { + "ar": "", + "de": "", + "en": "License expired. Unable to establish communication", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "证书过期,将无法正常建立通信链路", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B002A": { + "de": "Inkompatible Firmware-Versionen. Zum Startbildschirm wechseln, um die Firmware zu aktualisieren", + "en": "Incompatible firmware versions. Return to home screen to update firmware", + "es": "Versiones del firmware incompatibles. Vuelve a la pantalla de inicio para actualizar el firmware.", + "fr": "Versions de firmware incompatibles. Revenez sur l'écran d'accueil pour mettre à jour le firmware", + "ja": "互換性のないファームウェア。ホーム画面に戻ってファームウェアを更新してください", + "ko": "호환되지 않는 펌웨어 버전. 리턴 투 홈 화면으로 돌아가 펌웨어를 업데이트하세요.", + "ru": "Несовместимые версии прошивки. Вернитесь на главный экран, чтобы обновить прошивку", + "tr": "Uyumsuz ürün yazılımı sürümleri. Ürün yazılımını güncellemek için ana ekrana dönün", + "zh": "固件版本不匹配,请返回首页进行升级" + }, + "fpv_tip_0x1F0B002B": { + "de": "Inkompatible Firmware-Versionen. Zum Startbildschirm wechseln, um die Firmware zu aktualisieren", + "en": "Incompatible firmware versions. Return to home screen to update firmware", + "es": "Versiones del firmware incompatibles. Vuelve a la pantalla de inicio para actualizar el firmware.", + "fr": "Versions de firmware incompatibles. Revenez sur l'écran d'accueil pour mettre à jour le firmware", + "ja": "互換性のないファームウェア。ホーム画面に戻ってファームウェアを更新してください", + "ko": "호환되지 않는 펌웨어 버전. 리턴 투 홈 화면으로 돌아가 펌웨어를 업데이트하세요.", + "ru": "Несовместимые версии прошивки. Вернитесь на главный экран, чтобы обновить прошивку", + "tr": "Uyumsuz ürün yazılımı sürümleri. Ürün yazılımını güncellemek için ana ekrana dönün", + "zh": "固件版本不匹配,请返回首页进行升级" + }, + "fpv_tip_0x1F0B002C": { + "ar": "", + "de": "", + "en": "Incompatible firmware versions. Go to home screen to update firmware", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "固件版本不匹配,请在首页进行升级", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B002D": { + "ar": "", + "de": "", + "en": "App update required", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "App版本需要升级", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B002E": { + "de": "Schwache Netzwerkverbindung auf Fernsteuerung. Mit Vorsicht fliegen", + "en": "Weak network connection on remote controller. Fly with caution", + "es": "Conexión de red débil en el control remoto. Vuele con cuidado", + "fr": "Connexion réseau faible sur la radiocommande. Pilotez avec précaution", + "ja": "送信機のネットワーク接続 弱。慎重に飛行してください", + "ko": "조종기의 네트워크 연결이 약합니다. 비행 시 주의 필요", + "ru": "Слабое сетевое подключение на пульте дистанционного управления. Соблюдайте осторожность при полете", + "tr": "Uzaktan kumandada zayıf ağ bağlantısı. Dikkatlice uçurun", + "zh": "遥控器网络信号弱,请谨慎飞行" + }, + "fpv_tip_0x1F0B0030": { + "de": "Verbindung zum LTE-Server fehlgeschlagen. Später erneut versuchen", + "en": "Failed to connect to LTE server. Try again later", + "es": "No se pudo conectar al servidor LTE. Vuelve a intentarlo más tarde.", + "fr": "Échec de la connexion au serveur LTE. Veuillez réessayer ultérieurement", + "ja": "LTEサーバーへの接続に失敗。後でやり直してください", + "ko": "LTE 서버 연결 실패. 나중에 다시 시도하세요.", + "ru": "Не удалось подключиться к серверу LTE. Повторите попытку позже", + "tr": "LTE sunucusuna bağlanılamadı. Daha sonra tekrar deneyin", + "zh": "LTE服务器暂时无法连接,请稍后再试" + }, + "fpv_tip_0x1F0B0031": { + "ar": "", + "de": "", + "en": "Weak network signal on mobile device. Device may be unable to establish communication or connection may be unstable", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "手机可网络信号弱,链路可能无法建立或者容易断开连接", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B0032": { + "ar": "", + "de": "", + "en": "Service expired. Unable to use Enhanced Transmission. Firmware update required", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "用户服务到期,不允许进入融合模式。固件版本需要升级", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B0035": { + "ar": "", + "de": "", + "en": "Dongle firmware update required", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "dongle固件版本需要升级", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B0036": { + "de": "Verbesserte Übertragung in aktueller Region nicht verfügbar", + "en": "Enhanced Transmission unavailable in current region", + "es": "La transmisión mejorada no está disponible en la región actual.", + "fr": "Transmission améliorée non disponible dans la région actuelle", + "ja": "現在の地域では、強化伝送を利用できません", + "ko": "현재 지역에서는 향상된 전송 사용 불가", + "ru": "Расширенная передача недоступна в текущем регионе", + "tr": "Gelişmiş Aktarım geçerli bölgede mevcut değil", + "zh": "当前地区无法使用增强图传功能" + }, + "fpv_tip_0x1F0B0037": { + "de": "Kein Internetzugang auf DJI Mobilfunkmodul-Dongle des Fluggeräts. Standort oder Netzwerk wechseln", + "en": "No internet access on DJI Cellular Dongle of aircraft. Move or change network", + "es": "No hay acceso a Internet en el adaptador de red móvil de DJI de la aeronave. Muévete o cambia de red.", + "fr": "Aucun accès Internet sur le dongle cellulaire DJI de l'appareil. Déplacez-vous ou changez de réseau", + "ja": "機体のDJIセルラードングルがインターネットにアクセス不可。アクセス可能な場所に移動するか、ネットワークを変更してください", + "ko": "기체의 DJI 셀룰러 동글에서 인터넷에 액세스할 수 없음. 이동하거나 네트워크를 변경하세요.", + "ru": "Нет доступа в Интернет на DJI Cellular Dongle дрона. Переместите его или измените сеть", + "tr": "Hava aracının DJI Hücresel Dongle'ında internet erişimi yok. Hareket edin veya ağı değiştirin", + "zh": "飞行器 DJI Cellular 模块无法访问网络,请更换至网络更好的地点或稍后重试" + }, + "fpv_tip_0x1F0B0038": { + "de": "Kein Netz auf DJI Mobilfunk-Dongle der Fernsteuerung", + "en": "No network on DJI Cellular Dongle of remote controller", + "es": "No hay red en el adaptador de red móvil de DJI del control remoto", + "fr": "Pas de réseau sur le dongle cellulaire DJI de la radiocommande", + "ja": "送信機のDJIセルラードングルでネットワークを利用できません", + "ko": "조종기 DJI 셀룰러 동글이 네트워크에 연결되어 있지 않습니다", + "ru": "Нет сети на DJI Cellular Dongle пульта дистанционного управления", + "tr": "Uzaktan kumandanın DJI Hücresel Dongle'ında ağ yok", + "zh": "遥控器 DJI Cellular 模块无法访问网络" + }, + "fpv_tip_0x1F0B0039": { + "ar": "", + "de": "", + "en": "Unable to establish network connection. Move to a different place or switch to a different SIM card from another service provider", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "目前网络无法正常建立,可以尝试更换地点,或者换其他运营商的卡。", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B003A": { + "de": "Kein Internetzugang auf DJI Mobilfunkmodul-Dongle des Fluggeräts. Netzanbieter wechseln", + "en": "No internet access on DJI Cellular Dongle of aircraft. Change network provider", + "es": "No hay acceso a Internet en el adaptador de red móvil de DJI de la aeronave. Cambia de proveedor de red.", + "fr": "Aucun accès Internet sur le dongle cellulaire DJI de l'appareil. Changez de fournisseur de réseau", + "ja": "機体のDJIセルラードングルがインターネットにアクセス不可。ネットワークプロバイダーを変更してください", + "ko": "기체의 DJI 셀룰러 동글에서 인터넷에 액세스할 수 없음. 네트워크 공급자를 변경하세요.", + "ru": "Нет доступа в Интернет на DJI Cellular Dongle дрона. Выберите другого оператора связи", + "tr": "Hava aracının DJI Hücresel Dongle'ında internet erişimi yok. Ağ sağlayıcısını değiştirin", + "zh": "飞行器 DJI Cellular 模块无法访问网络,请尝试使用其他运营商网络" + }, + "fpv_tip_0x1F0B003B": { + "de": "Kein Netz auf DJI Mobilfunk-Dongle der Fernsteuerung", + "en": "No network on DJI Cellular Dongle of remote controller", + "es": "No hay red en el adaptador de red móvil de DJI del control remoto", + "fr": "Pas de réseau sur le dongle cellulaire DJI de la radiocommande", + "ja": "送信機のDJIセルラードングルでネットワークを利用できません", + "ko": "조종기 DJI 셀룰러 동글이 네트워크에 연결되어 있지 않습니다", + "ru": "Нет сети на DJI Cellular Dongle пульта дистанционного управления", + "tr": "Uzaktan kumandanın DJI Hücresel Dongle'ında ağ yok", + "zh": "遥控器 DJI Cellular 模块无法访问网络" + }, + "fpv_tip_0x1F0B003C": { + "ar": "", + "de": "", + "en": "Unable to establish network connection. Move to a different place or switch to a different SIM card from another service provider", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "目前网络无法正常建立,可以尝试更换地点,或者换其他运营商的卡。", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B003D": { + "de": "Keine Netzwerkverbindung", + "en": "No network connection", + "es": "No hay conexión de red", + "fr": "Aucune connexion réseau", + "ja": "ネットワーク接続がありません", + "ko": "네트워크 연결 없음", + "ru": "Нет подключения к сети", + "tr": "Ağ bağlantısı yok", + "zh": "无法访问网络" + }, + "fpv_tip_0x1F0B003E": { + "de": "Kein Netz für SIM-Karte des DJI Mobilfunkmodul-Dongles der Fernsteuerung. SIM-Karte prüfen oder ersetzen", + "en": "No network on SIM card of DJI Cellular Dongle of remote controller. Check or replace SIM card", + "es": "No hay red en la tarjeta SIM del adaptador de red móvil de DJI del control remoto. Compruebe o sustituya la tarjeta SIM", + "fr": "Pas de réseau sur la carte SIM du dongle cellulaire de radiocommande DJI. Vérifiez ou remplacez la carte SIM", + "ja": "送信機のDJIセルラードングルのSIMカードでネットワークを利用できません。SIMカードを確認または交換してください", + "ko": "조종기 DJI 셀룰러 동글의 SIM 카드에 네트워크가 없습니다. SIM 카드를 확인하거나 교체하세요", + "ru": "Нет сети на SIM-карте DJI Cellular Dongle пульта дистанционного управления. Проверьте или замените SIM-карту", + "tr": "Uzaktan kumandanın DJI Hücresel Dongle öğesi SIM kartında ağ bağlantısı yok. SIM kartı kontrol edin veya değiştirin", + "zh": "遥控器 DJI Cellular SIM卡暂时无法获取网络服务,建议检查或更换SIM卡" + }, + "fpv_tip_0x1F0B0040": { + "de": "Kein Netz auf der Fernsteuerung", + "en": "No network on remote controller", + "es": "No hay red en el control remoto", + "fr": "Pas de réseau sur la radiocommande", + "ja": "送信機でネットワークを利用できません", + "ko": "조종기가 네트워크에 연결되어 있지 않습니다", + "ru": "Отсутствие сети на пульте дистанционного управления", + "tr": "Uzaktan kumandada ağ yok", + "zh": "遥控器无法访问网络" + }, + "fpv_tip_0x1F0B0040_in_the_sky": { + "de": "Kein Internet auf der Fernsteuerung. Status des DJI Mobilfunk-Dongles oder der Wi-Fi-Verbindung prüfen", + "en": "No internet on remote controller. Check DJI Cellular Dongle or Wi-Fi connection status", + "es": "No hay internet en el control remoto. Compruebe el estado de la conexión Wi-Fi o del adaptador de red móvil de DJI", + "fr": "Pas d’Internet sur la radiocommande. Vérifiez le dongle cellulaire DJI ou l'état de la connexion Wi-Fi", + "ja": "送信機にインターネット接続なし。DJIセルラードングルまたはWi-Fi接続ステータスを確認してください", + "ko": "조종기가 인터넷에 연결되어 있지 않습니다. DJI 셀룰러 동글 또는 Wi-Fi 연결 상태를 확인하세요", + "ru": "Отсутствие сети Интернет на пульте. Проверьте DJI Cellular Dongle или статус подключения Wi-Fi", + "tr": "Uzaktan kumandada internet yok. DJI Hücresel Dongle veya Wi-Fi bağlantı durumunu kontrol edin", + "zh": "遥控器无法访问网络,请检查DJI Cellular模块或Wi-Fi连接状态" + }, + "fpv_tip_0x1F0B0045": { + "de": "Erhöhte Latenzzeit der Verbindung. Mit Vorsicht fliegen", + "en": "Enhanced link latency high. Fly with caution", + "es": "Alta latencia de enlace mejorada. Vuele con cuidado.", + "fr": "Latence de liaison améliorée élevée. Pilotez avec précaution", + "ja": "強化リンクが高遅延。慎重に飛行してください", + "ko": "향상된 링크 지연율이 높습니다. 비행 시 주의 필요", + "ru": "Большая вероятность канальной задержки управления расширенной связью. Соблюдайте осторожность при полете", + "tr": "Gelişmiş bağlantı gecikmesi yüksek. Dikkatlice uçurun", + "zh": "增强链路操控延时较大,请谨慎飞行" + }, + "fpv_tip_0x1F0B0045_in_the_sky": { + "de": "Erhöhte Latenzzeit der Verbindung. Mit Vorsicht fliegen.", + "en": "Enhanced link latency high. Fly with caution", + "es": "Alta latencia de enlace mejorada. Vuele con cuidado", + "fr": "Latence de liaison améliorée élevée. Pilotez avec précaution", + "ja": "強化リンクが高遅延。慎重に飛行してください", + "ko": "향상된 링크 지연율이 높습니다. 비행 시 주의 필요", + "ru": "Большая вероятность канальной задержки управления расширенной связью. Соблюдайте осторожность при полете", + "tr": "Gelişmiş bağlantı gecikmesi yüksek. Dikkatlice uçurun", + "zh": "增强链路操控延时较大,请谨慎飞行" + }, + "fpv_tip_0x1F0B0046": { + "ar": "", + "de": "SIM-Karte nicht in 4G-Dongle des Fluggeräts eingesetzt und eSIM-Karte nicht aktiviert", + "en": "SIM card not inserted in 4G Dongle of aircraft and eSIM card not activated", + "es": "Tarjeta SIM no insertada en el adaptador 4G de la aeronave y tarjeta eSIM no activada", + "fr": "Carte SIM non insérée dans le dongle 4G de l'appareil et carte eSIM non activée", + "id": "", + "it": "", + "ja": "SIMカードが機体の4Gドングルに挿入されておらず、eSIMカードがアクティベートされていません", + "ko": "기체의 4G 동글에 SIM 카드가 삽입되지 않았고 eSIM 카드가 활성화되지 않았습니다", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "SIM-карта не вставлена в 4G-адаптер дрона и карта eSIM не активирована", + "th": "", + "tr": "Hava aracının 4G Dongle'ına SIM kart takılı değil ve eSIM kartı etkinleştirilmemiş", + "ug": "", + "vi": "", + "zh": "飞机的4G Dongle未插入SIM卡且eSIM未激活", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B0047": { + "ar": "", + "de": "SIM-Karte in 4G-Dongle des Fluggeräts eingesetzt. eSIM-Karte ausgewählt, aber nicht aktiviert", + "en": "SIM card inserted in 4G Dongle of aircraft. eSIM card selected but not activated", + "es": "Tarjeta SIM insertada en el adaptador 4G de la aeronave. Tarjeta eSIM seleccionada pero no activada", + "fr": "Carte SIM insérée dans le dongle 4G de l'appareil. Carte eSIM sélectionnée, mais non activée", + "id": "", + "it": "", + "ja": "SIMカードが機体の4Gドングルに挿入され、eSIMカードが選択されていますがアクティベートされていません", + "ko": "기체의 4G 동글에 SIM 카드가 삽입되어 있지만 선택한 eSIM 카드가 활성화되지 않았습니다", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "SIM-карта вставлена в 4G-адаптер дрона. Карта eSIM выбрана, но не активирована", + "th": "", + "tr": "Hava aracının 4G Dongle'ına SIM kart takıldı eSIM kartı seçildi ancak etkinleştirilmedi", + "ug": "", + "vi": "", + "zh": "飞机的4G Dongle已插入SIM卡,选择了eSIM且eSIM未激活", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B0048": { + "ar": "", + "de": "SIM-Karte nicht in 4G-Dongle der Fernsteuerung eingesetzt und eSIM-Karte nicht aktiviert", + "en": "SIM card not inserted in 4G Dongle of remote controller and eSIM card not activated", + "es": "Tarjeta SIM no insertada en el adaptador 4G del control remoto y tarjeta eSIM no activada", + "fr": "Carte SIM non insérée dans le dongle 4G de la radiocommande et carte eSIM non activée", + "id": "", + "it": "", + "ja": "SIMカードが送信機の4Gドングルに挿入されておらず、eSIMカードがアクティベートされていません", + "ko": "조종기의 4G 동글에 SIM 카드가 삽입되지 않았고 eSIM 카드가 활성화되지 않았습니다", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "SIM-карта не вставлена в 4G-адаптер пульта ДУ и карта eSIM не активирована", + "th": "", + "tr": "Uzaktan kumandanın 4G Dongle'ına SIM kart takılı değil ve eSIM kartı etkinleştirilmemiş", + "ug": "", + "vi": "", + "zh": "遥控器的4G Dongle未插入SIM卡且eSIM未激活", + "zh-Hant": "" + }, + "fpv_tip_0x1F0B0049": { + "ar": "", + "de": "SIM-Karte in 4G-Dongle der Fernsteuerung eingesetzt. eSIM-Karte ausgewählt, aber nicht aktiviert", + "en": "SIM card inserted in 4G Dongle of remote controller. eSIM card selected but not activated", + "es": "Tarjeta SIM insertada en el adaptador 4G del control remoto. Tarjeta eSIM seleccionada pero no activada", + "fr": "Carte SIM insérée dans le dongle 4G de la radiocommande. Carte eSIM sélectionnée, mais non activée", + "id": "", + "it": "", + "ja": "SIMカードが送信機の4Gドングルに挿入され、eSIMカードが選択されていますがアクティベートされていません", + "ko": "조종기의 4G 동글에 SIM 카드가 삽입되어 있지만 선택한 eSIM 카드가 활성화되지 않았습니다", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "SIM-карта вставлена в 4G-адаптер пульта ДУ. Карта eSIM выбрана, но не активирована", + "th": "", + "tr": "Uzaktan kumandanın 4G Dongle'ına SIM kart takıldı. eSIM kartı seçildi ancak etkinleştirilmedi", + "ug": "", + "vi": "", + "zh": "遥控器的4G Dongle已插入SIM卡,选择了eSIM且eSIM未激活", + "zh-Hant": "" + }, + "fpv_tip_0x1a020180": { + "de": "Infrarotsensoren überhitzt. Umgehend zum Startpunkt zurückkehren oder landen. Bitte aus Umgebung mit hoher Temperatur entfernen (%alarmid)", + "en": "Infrared sensors overheated. Return to home or land promptly. Move away from high-temperature environment", + "es": "Sensores de infrarrojos sobrecalentados. Regresa al punto de origen o aterriza rápidamente. Aléjate del entorno de alta temperatura", + "fr": "Surchauffe des capteurs infrarouges. Retournez au point de départ ou atterrissez immédiatement. Éloignez-vous des sources de hautes températures", + "ja": "赤外線センサーが高温。直ちにホームに帰還するか着陸してください。高温環境から離れてください", + "ko": "적외선 센서 과열. 홈으로 돌아가거나 신속히 착륙하세요. 고온 환경에서 벗어나세요", + "ru": "Инфракрасные датчики перегреты. Немедленно вернитесь в исходное положение и приземлитесь. Переместитесь от среды с высокой температурой", + "tr": "", + "zh": "视觉红外传感器温度过高,请尽快返航或降落,远离高温环境" + }, + "fpv_tip_0x1a420bc0": { + "de": "Abwärtsgerichtetes Umgebungslicht zu schwach. Abwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Downward ambient light too low. Obstacle avoidance unavailable. Fly with caution", + "es": "Luz ambiental inferior demasiado débil. Sistema anticolisión no disponible. Vuela con cuidado", + "fr": "Éclairage ambiant vers le bas trop faible. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "下方環境光が弱すぎます。障害物回避を利用できません。慎重に飛行してください", + "ko": "하향 주변 조명이 너무 어둡습니다. 하향 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком низкая яркость окружающего света внизу. Обход препятствий снизу недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "下视环境光过暗,下方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420bc1": { + "de": "Vorwärtsgerichtetes Umgebungslicht zu schwach. Vorwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Mit Vorsicht fliegen", + "en": "Forward ambient light too low. Obstacle avoidance unavailable. Fly with caution", + "es": "Luz ambiental frontal demasiado débil. Sistema anticolisión no disponible. Vuela con cuidado", + "fr": "Éclairage ambiant vers l\\'avant trop faible. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "前方環境光が弱すぎます。障害物回避を利用できません。慎重に飛行してください", + "ko": "전방 주변 조명이 너무 어둡습니다. 전방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком низкая яркость окружающего света впереди. Обход препятствий спереди недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "前视环境光过暗,前向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420bc2": { + "de": "Rückwärtiges Umgebungslicht zu schwach. Rückwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Backward ambient light too low. Backward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental trasera demasiado débil. Sistema anticolisión trasero no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop faible à l\\'arrière. Évitement des obstacles à l\\'arrière non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "後方の環境光が十分ではありません。後方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "후방 주변 조명이 너무 어둡습니다. 후방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком низкая яркость окружающего света сзади. Обход препятствий сзади недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "后视环境光过暗,后向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420bc3": { + "de": "Rechtsgerichtetes Umgebungslicht zu schwach. Rechtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Rightward ambient light too low. Rightward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental derecha demasiado débil. Sistema anticolisión derecho no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop faible sur la droite. Évitement des obstacles sur la droite non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "右方向の環境光が十分ではありません。右方向の障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "오른쪽 주변 조명이 너무 어둡습니다. 오른쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Слишком низкая яркость окружающего света справа. Обход препятствий справа недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "右视环境光过暗,右向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420bc4": { + "de": "Linksgerichtetes Umgebungslicht zu schwach. Linksgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Leftward ambient light too low. Leftward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental izquierda demasiado débil. Sistema anticolisión izquierdo no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop faible sur la gauche. Évitement des obstacles sur la gauche non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "左方向の環境光が十分ではありません。左方向の障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "왼쪽 주변 조명이 너무 어둡습니다. 왼쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Слишком низкая яркость окружающего света слева. Обход препятствий слева недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "左视环境光过暗,左向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420bc5": { + "de": "Aufwärtsgerichtetes Umgebungslicht zu schwach. Aufwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Upward ambient light too low. Upward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental superior demasiado débil. Sistema anticolisión superior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop faible au-dessus. Évitement des obstacles au-dessus non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "上方の環境光が十分ではありません。上方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "상방 주변 조명이 너무 어둡습니다. 상방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Слишком низкая яркость окружающего света сверху. Обход препятствий сверху недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "上视环境光过暗,上方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420bc6": { + "de": "Horizontales Umgebungslicht zu schwach. Horizontale Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Horizontal ambient light too low. Horizontal obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental horizontal demasiado débil. Sistema anticolisión horizontal no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante horizontale trop faible. Évitement des obstacles horizontaux non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "水平方向の環境光が十分ではありません。水平方向の障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "수평 주변 조명이 너무 어둡습니다. 수평 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Слишком низкая яркость окружающего света в горизонтальном направлении. Обход препятствий в горизонтальном направлении недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "水平方向环境光过暗,水平方向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c00": { + "de": "Abwärtsgerichtetes Umgebungslicht zu hell. Abwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Downward ambient light too bright. Downward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental inferior demasiado intensa. Sistema anticolisión inferior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop forte en dessous. Évitement des obstacles en dessous non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "下方の環境光が明るすぎます。下方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "하방 주변 조명이 너무 밝습니다. 하방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Слишком высокая яркость окружающего света внизу. Обход препятствий снизу недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "下视环境光过亮,下方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c01": { + "de": "Vorwärts-Umgebungslicht zu hell. Vorwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Forward ambient light too bright. Forward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental frontal demasiado intensa. Sistema anticolisión frontal no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop forte à l\\'avant. Évitement des obstacles à l\\'avant non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "前方の環境光が明るすぎます。前方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "전방 주변 조명이 너무 밝습니다. 전방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Слишком высокая яркость окружающего света впереди. Обход препятствий спереди недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "前视环境光过亮,前向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c02": { + "de": "Rückwärtiges Umgebungslicht zu hell. Rückwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Backward ambient light too bright. Backward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental trasera demasiado intensa. Sistema anticolisión trasero no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop forte à l\\'arrière. Évitement des obstacles à l\\'arrière non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "後方の環境光が明るすぎます。後方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "후방 주변 조명이 너무 밝습니다. 후방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Слишком высокая яркость окружающего света сзади. Обход препятствий сзади недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "后视环境光过亮,后向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c03": { + "de": "Rechtsgerichtetes Umgebungslicht zu hell. Rechtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Rightward ambient light too bright. Rightward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental derecha demasiado intensa. Sistema anticolisión derecho no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop forte sur la droite. Évitement des obstacles sur la droite non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "右方向の環境光が明るすぎます右方向の障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "오른쪽 주변 조명이 너무 밝습니다. 오른쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Слишком высокая яркость окружающего света справа. Обход препятствий справа недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "右视环境光过亮,右向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c04": { + "de": "Linksgerichtetes Umgebungslicht zu hell. Linksgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Leftward ambient light too bright. Leftward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental izquierda demasiado intensa. Sistema anticolisión izquierdo no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop forte sur la gauche. Évitement des obstacles sur la gauche non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "左方向の環境光が明るすぎます。左方向の障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "왼쪽 주변 조명이 너무 밝습니다. 왼쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Слишком высокая яркость окружающего света слева. Обход препятствий слева недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "左视环境光过亮,左向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c05": { + "de": "Aufwärtsgerichtetes Umgebungslicht zu hell. Aufwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Upward ambient light too bright. Upward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental superior demasiado intensa. Sistema anticolisión superior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante trop forte au-dessus. Évitement des obstacles au-dessus non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "上方の環境光が明るすぎます。上方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "상방 주변 조명이 너무 밝습니다. 상방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Слишком высокая яркость окружающего света сверху. Обход препятствий сверху недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "上视环境光过亮,上方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c06": { + "de": "Horizontales Umgebungslicht zu hell. Horizontale Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Horizontal ambient light too bright. Horizontal obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Luz ambiental horizontal demasiado intensa. Sistema anticolisión horizontal no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Lumière ambiante horizontale trop forte. Évitement des obstacles horizontaux non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "水平方向の環境光が明るすぎます。水平方向の障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "수평 주변 조명이 너무 밝습니다. 수평 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Слишком высокая яркость окружающего света в горизонтальном направлении. Обход препятствий в горизонтальном направлении недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "水平方向环境光过亮,水平方向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c40": { + "de": "Abwärtsgerichtete(r) Sensor(en) blockiert. Abwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Downward sensor(s) blocked. Downward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) inferior(es) bloqueado(s). Sistema anticolisión inferior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) inférieurs bloqué(s). Évitement des obstacles en dessous non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "下方センサーがブロックされています。下方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "하방 센서가 막혔습니다. 하방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Нижние датчик(и) заблокированы. Обход препятствий снизу недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "下视可能遮挡,下方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c41": { + "de": "Vorwärtsgerichtete(r) Sensor(en) blockiert. Vorwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Forward sensor(s) blocked. Forward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) frontal(es) bloqueado(s). Sistema anticolisión frontal no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) avant bloqué(s). Évitement des obstacles à l\\'avant non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "前方センサーがブロックされています。前方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "전방 센서가 막혔습니다. 전방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Передние датчик(и) заблокированы. Обход препятствий спереди недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "前视可能遮挡,前向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c42": { + "de": "Rückwärtsgerichtete(r) Sensor(en) blockiert. Rückwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Backward sensor(s) blocked. Backward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) trasero(s) bloqueado(s). Sistema anticolisión trasero no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) arrière bloqué(s). Évitement des obstacles à l\\'arrière non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "後方センサーがブロックされています。後方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "후방 센서가 막혔습니다. 후방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Задние датчик(и) заблокированы. Обход препятствий сзади недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "后视可能遮挡,后向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c43": { + "de": "Rechtsgerichtete(r) Sensor(en) blockiert. Rechtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Rightward sensor(s) blocked. Rightward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) derecho(s) bloqueado(s). Sistema anticolisión derecho no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) de droite bloqué(s). Évitement des obstacles sur la droite non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "右方向センサーがブロックされています。右方向の障害物回避を利用できません。赤外線センサーのみが利用できます。 注意して飛行してください", + "ko": "오른쪽 센서가 막혔습니다. 오른쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Правые датчик(и) заблокированы. Обход препятствий справа недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "右视可能遮挡,右向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c44": { + "de": "Linksgerichtete(r) Sensor(en) blockiert. Linksgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Leftward sensor(s) blocked. Leftward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) izquierdo(s) bloqueado(s). Sistema anticolisión izquierdo no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) de gauche bloqué(s). Évitement des obstacles sur la gauche non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "左方向センサーがブロックされています。左方向の障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "왼쪽 센서가 막혔습니다. 왼쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Левые датчик(и) заблокированы. Обход препятствий слева недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "左视可能遮挡,左向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c45": { + "de": "Aufwärtsgerichtete(r) Sensor(en) blockiert. Aufwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Upward sensor(s) blocked. Upward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) superior(es) bloqueado(s). Sistema anticolisión superior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) supérieurs bloqué(s). Évitement des obstacles au-dessus non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "上方センサーがブロックされています。上方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "상방 센서가 막혔습니다. 상방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Верхние датчик(и) заблокированы. Обход препятствий сверху недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "上视可能遮挡,上方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c80": { + "de": "Abwärtsgerichtete(r) Sensor(en) unscharf. Abwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Downward sensor(s) blurry. Downward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) inferior(es) borroso(s). Sistema anticolisión inferior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) inférieurs flou(s). Évitement des obstacles en dessous non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "下方センサーが不鮮明です。下方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "하방 센서가 흐릿합니다. 하방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Размытое изображение с нижних датчиков. Обход препятствий снизу недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "下视可能脏污,下方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c81": { + "de": "Vorwärtsgerichtete(r) Sensor(en) unscharf. Vorwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Forward sensor(s) blurry. Forward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) frontal(es) borroso(s). Sistema anticolisión frontal no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) avant flou(s). Évitement des obstacles à l\\'avant non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "前方センサーが不鮮明です。前方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "전방 센서가 흐릿합니다. 전방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Размытое изображение с передних датчиков. Обход препятствий спереди недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "前视可能脏污,前向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c82": { + "de": "Rückwärtsgerichtete(r) Sensor(en) verschwommen. Rückwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Backward sensor(s) blurry. Backward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) trasero(s) borroso(s). Sistema anticolisión trasero no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) arrière flou(s). Évitement des obstacles à l\\'arrière non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "後方センサーが不鮮明です。後方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "후방 센서가 흐릿합니다. 후방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의해서 비행하세요", + "ru": "Размытое изображение с задних датчиков. Обход препятствий сзади недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "后视可能脏污,后向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c83": { + "de": "Rechte(r) Sensor(en) unscharf. Rechtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Right sensor(s) blurry. Rightward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) derecho(s) borroso(s). Sistema anticolisión derecho no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) de droite flou(s). Évitement des obstacles sur la droite non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "右センサーが不鮮明です。右方向の障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "오른쪽 센서가 흐릿합니다. 오른쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Размытое изображение с правых датчиков. Обход препятствий справа недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "右视可能脏污,右向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c84": { + "de": "Linke(r) Sensor(en) unscharf. Linksgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Left sensor(s) blurry. Leftward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) izquierdo(s) borroso(s). Sistema anticolisión izquierdo no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) de gauche flou(s). Évitement des obstacles sur la gauche non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "左センサーが不鮮明です。左方向の障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "왼쪽 센서가 흐릿합니다. 왼쪽 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Размытое изображение с левых датчиков. Обход препятствий слева недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "左视可能脏污,左向视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420c85": { + "de": "Aufwärtsgerichtete(r) Sensor(en) unscharf. Aufwärtsgerichtete Hindernisvermeidung nicht verfügbar. Nur Infrarotsensoren verfügbar. Vorsichtig fliegen.", + "en": "Upward sensor(s) blurry. Upward obstacle avoidance unavailable. Only infrared sensors available. Fly with caution", + "es": "Sensor(es) superior(es) borroso(s). Sistema anticolisión superior no disponible. Solo están disponibles los sensores de infrarrojos. Vuela con cuidado", + "fr": "Capteur(s) supérieurs flou(s). Évitement des obstacles au-dessus non disponible. Seuls les capteurs infrarouges sont disponibles. Volez avec prudence", + "ja": "上方センサーが不鮮明です。上方障害物回避を利用できません。赤外線センサーのみが利用できます。注意して飛行してください", + "ko": "상방 센서가 흐릿합니다. 상방 장애물 회피를 사용할 수 없습니다. 적외선 센서만 사용할 수 있습니다. 주의하여 비행하세요.", + "ru": "Размытое изображение с верхних датчиков. Обход препятствий сверху недоступен. Доступны только инфракрасные датчики. Будьте внимательны при полете", + "tr": "", + "zh": "上视可能脏污,上方视觉避障失效,仅红外传感器工作,请谨慎飞行" + }, + "fpv_tip_0x1a420cc0": { + "de": "Fluglagenwinkel des Fluggeräts zu groß. Hindernisvermeidung nicht verfügbar. Mit Vorsicht fliegen", + "en": "Aircraft attitude angle too large. Obstacle avoidance unavailable. Fly with caution", + "es": "Ángulo de posición de la aeronave demasiado grande. Sistema anticolisión no disponible. Vuela con cuidado", + "fr": "Angle d\\'attitude de l\\'appareil trop important. Évitement d\\'obstacles indisponible. Volez avec précaution", + "ja": "機体姿勢角が大きすぎます。障害物回避を利用できません。慎重に飛行してください", + "ko": "기체 자세 각도가 너무 큽니다. 장애물 회피를 사용할 수 없습니다. 주의해서 비행하세요", + "ru": "Слишком большой угол тангажа дрона. Обход препятствий недоступен. Будьте внимательны при полете", + "tr": "", + "zh": "飞行器姿态角过大,避障失效,请谨慎飞行" + }, + "fpv_tip_0x1a420d00": { + "de": "Fluglagenwinkel des Fluggeräts zu groß. Landeschutz nicht verfügbar. Manuell landen", + "en": "Aircraft attitude angle too large. Landing protection unavailable. Land manually", + "es": "Ángulo de posición de la aeronave demasiado grande. Protección durante el aterrizaje no disponible. Aterriza manualmente", + "fr": "Angle d\\'attitude de l\\'appareil trop important. Protection à l\\'atterrissage indisponible. Atterrissez manuellement", + "ja": "機体姿勢角が大きすぎます。着陸保護を利用できません。手動で着陸してください", + "ko": "기체 자세 각도가 너무 큽니다. 착륙 보호 기능을 사용할 수 없습니다. 수동 착륙", + "ru": "Слишком большой угол тангажа дрона. Безопасное приземление недоступно. Приземлитесь вручную", + "tr": "", + "zh": "飞行器姿态角过大,降落保护失效,请手动降落" + }, + "fpv_tip_0x1a420d40": { + "de": "Fluggerät nähert sich Hindernis mit totem Winkel. Hinderniserkennung evtl. nicht möglich. Mit Vorsicht fliegen", + "en": "Aircraft approaching obstacle sensing blind spot and may be unable to detect obstacles. Fly with caution", + "es": "La aeronave se está acercando al punto ciego de detección de obstáculos y es posible que no pueda detectar obstáculos. Vuela con cuidado", + "fr": "L\\'appareil approche de l\\'angle mort de la détection d\\'obstacles et pourrait ne pas être en mesure de détecter les obstacles. Volez avec précaution", + "ja": "機体が障害物検知死角に接近中。障害物を検知できない可能性があります。慎重に飛行してください", + "ko": "기체가 장애물 감지 사각 지대에 접근하고 있으므로 장애물을 감지하지 못할 수도 있습니다. 주의해서 비행하세요", + "ru": "Дрон приближается к слепой зоне определения препятствий, и, возможно, не сможет обнаружить препятствия. Будьте внимательны при полете", + "tr": "", + "zh": "正飞向障碍物感知盲区,可能无法检测障碍物,请谨慎飞行" + }, + "fpv_tip_0x1a5103c0": { + "de": "Kalibrierungsfehler: Sichtsensor", + "en": "Downward vision sensor calibration error", + "es": "Error de calibración del sensor visual inferior", + "fr": "Erreur d\\'étalonnage du capteur optique inférieur", + "ja": "下方ビジョンセンサーのキャリブレーションエラー", + "ko": "비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки нижнего датчика обзора", + "tr": "", + "zh": "下视传感器标定异常" + }, + "fpv_tip_0x1a5103c1": { + "de": "Kalibrierungsfehler: Vorwärtsgerichtete Sichtsensoren", + "en": "Forward vision sensor calibration error", + "es": "Error de calibración del sensor visual frontal", + "fr": "Erreur d\\'étalonnage du capteur optique avant", + "ja": "前方ビジョンセンサーのキャリブレーションエラー", + "ko": "전방 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки переднего датчика обзора", + "tr": "", + "zh": "前视传感器标定异常" + }, + "fpv_tip_0x1a5103c2": { + "de": "Kalibrierungsfehler: Rückwärtsgerichtete Sichtsensoren", + "en": "Backward vision sensor calibration error", + "es": "Error de calibración del sensor visual trasero", + "fr": "Erreur d\\'étalonnage du capteur optique arrière", + "ja": "後方ビジョンセンサーのキャリブレーションエラー", + "ko": "후방 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки заднего датчика обзора", + "tr": "", + "zh": "后视传感器标定异常" + }, + "fpv_tip_0x1a5103c3": { + "de": "Kalibrierungsfehler: Aufwärtsgerichtete Sichtsensoren", + "en": "Upward vision sensor calibration error", + "es": "Error de calibración del sensor visual superior", + "fr": "Erreur d\\'étalonnage du capteur optique supérieur", + "ja": "上方ビジョンセンサーのキャリブレーションエラー", + "ko": "상향 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки верхнего датчика обзора", + "tr": "", + "zh": "上视传感器标定异常" + }, + "fpv_tip_0x1a5103c4": { + "de": "Kalibrierungsfehler: Linksgerichtete Sichtsensoren", + "en": "Left vision sensor calibration error", + "es": "Error de calibración del sensor visual izquierdo", + "fr": "Erreur d\\'étalonnage du capteur optique gauche", + "ja": "左ビジョンセンサーのキャリブレーションエラー", + "ko": "좌측 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки левого датчика обзора", + "tr": "", + "zh": "左视传感器标定异常" + }, + "fpv_tip_0x1a5103c5": { + "de": "Kalibrierungsfehler: Rechtsgerichtete Sichtsensoren", + "en": "Right vision sensor calibration error", + "es": "Error de calibración del sensor visual derecho", + "fr": "Erreur d\\'étalonnage du capteur optique droit", + "ja": "右ビジョンセンサーのキャリブレーションエラー", + "ko": "우측 비전 센서 캘리브레이션 오류", + "ru": "Ошибка калибровки правого датчика обзора", + "tr": "", + "zh": "右视传感器标定异常" + }, + "fpv_tip_0x1afd0040": { + "de": "Fehler: Sensorsystem. Kann nicht abheben. Fliegen untersagt", + "en": "Sensor system error. Unable to take off. Flight prohibited", + "es": "Error del sistema del sensor. No se puede despegar. Vuelo prohibido", + "fr": "Erreur système de capteurs. Décollage impossible. Vol interdit", + "it": "", + "ja": "センサーシステムエラー。離陸できません。飛行が禁止されています", + "ko": "센서 시스템 오류. 이륙 불가. 비행 금지", + "pt": "", + "ru": "Ошибка системы датчиков. Невозможно выполнить взлет. Полет запрещен", + "tr": "Sensör sistem hatası. Kalkış yapamıyor. Uçuş yasaklandı", + "zh": "无法起飞:感知传感器系统异常,禁止起飞" + }, + "fpv_tip_0x1afd0040_in_the_sky": { + "de": "Fehler: Sensorsystem. Sofort zurückkehren oder landen", + "en": "Sensor system error. Return to home or land promptly", + "es": "Error del sistema del sensor. Regresa al punto de origen o aterriza lo antes posible", + "fr": "Erreur système de capteurs. Revenez au point de départ et atterrissez immédiatement", + "it": "", + "ja": "センサーシステムエラー。直ちに帰還もしくは着陸してください", + "ko": "센서 시스템 오류. 즉시 RTH 또는 착륙 필요", + "pt": "", + "ru": "Ошибка системы датчиков. Вернитесь домой или приземлитесь немедленно", + "tr": "Sensör sistem hatası. Eve geri dönün veya düzgün iniş yapın", + "zh": "感知传感器系统异常,请尽快返航或降落" + }, + "fpv_tip_0x1afe0040": { + "de": "Sichtsensoren überlastet. In offenen Bereich fliegen", + "en": "Vision system overloaded. Fly to open area", + "es": "Sistema de visión sobrecargado. Vuela a un espacio abierto", + "fr": "Système optique surchargé. Volez dans une zone dégagée", + "ja": "ビジョンシステム過負荷状態。開けた場所に飛行してください", + "ko": "비전 시스템 과부하. 개방 영역으로 비행하세요", + "ru": "Система обзора перегружена. Подлетите к открытому участку", + "tr": "", + "zh": "视觉系统负载过高,请谨慎飞行至开阔环境" + }, + "fpv_tip_0x1b030019": { + "de": "Fluggerät fliegt nicht entlang der Route. Sichere Rückkehrfunktion beendet", + "en": "Aircraft not flying along route. Safe RTH exited", + "es": "Aeronave que no vuela por la ruta. Salió de RPO seguro", + "fr": "L'appareil ne suit pas l'itinéraire. RTH sécurisé quitté", + "ja": "機体はルートに沿って飛行していません。セーフRTHが終了しました", + "ko": "경로에 따라 비행하지 않는 기체. 안전한 RTH 종료됨", + "ru": "Дрон не летит по маршруту. Функция безопасного возврата домой отключена", + "tr": "Hava aracı rota üzerinde uçmuyor. Güvenli BND'den çıkıldı", + "zh": "飞行器已偏离航线,航线安全返航失效" + }, + "fpv_tip_0x1b080001": { + "en": "Remote ID broadcast error. Failed to obtain remote controller location", + "zh": "Remote ID 播报异常,无法获取遥控器位置" + }, + "fpv_tip_0x1b080002": { + "en": "Remote ID module error. Contact DJI Support", + "zh": "Remote ID 模块异常,请联系售后服务" + }, + "fpv_tip_0x1c000603": { + "de": "Evtl. Überbelichtung im Foto", + "en": "Risk of overexposure in photo", + "es": "Riesgo de sobreexposición en la foto", + "fr": "Risque de surexposition photo", + "ja": "写真の露出オーバーのリスク", + "ko": "사진 과다 노출 위험", + "ru": "Риск переэкспонирования на фото", + "tr": "Fotoğrafta aşırı pozlama riski", + "zh": "照片存在欠曝风险" + }, + "fpv_tip_0x1c000604": { + "de": "Evtl. Überbelichtung im Foto", + "en": "Risk of overexposure in photo", + "es": "Riesgo de sobreexposición en la foto", + "fr": "Risque de surexposition photo", + "ja": "写真の露出オーバーのリスク", + "ko": "사진 과다 노출 위험", + "ru": "Риск переэкспонирования на фото", + "tr": "Fotoğrafta aşırı pozlama riski", + "zh": "照片存在过曝风险" + }, + "fpv_tip_0x1c100405": { + "de": "Lese- und Schreibberechtigungen für Speicherkarte bestätigen", + "en": "Confirm memory card read and write permissions", + "es": "Confirme los permisos de lectura y escritura de la tarjeta de memoria", + "fr": "Confirmez les autorisations de lecture et d'écriture de la carte mémoire", + "ja": "メモリーカードの読み取り/書き込み権限を確認してください", + "ko": "메모리 카드 읽기 및 쓰기 권한을 확인하세요", + "ru": "Подтвердите наличие разрешений на чтение и запись карты памяти", + "tr": "Hafıza kartı okuma ve yazma izinlerini onaylayın", + "zh": "请确认存储卡读写属性" + }, + "fpv_tip_0x1c100405_index_1": { + "de": "eMMC-Lese- und Schreibeigenschaften bestätigen", + "en": "Confirm eMMC read and write properties", + "es": "", + "fr": "Confirmez les propriétés de lecture et d'écriture de l'eMMC", + "ja": "eMMCの読み取り/書き込みプロパティを確認", + "ko": "eMMC 읽기 및 쓰기 속성을 확인하세요.", + "ru": "Подтвердите наличие разрешений на чтений и запись eMMC-накопителя", + "tr": "", + "zh": "请确认EMMC读写属性" + }, + "fpv_tip_0x1c100406": { + "de": "Speicherkarte nicht formatiert. Karte vor Gebrauch formatieren.", + "en": "Memory card not formatted. Format card before use", + "es": "Tarjeta de memoria no formateada. Formatee la tarjeta antes del uso", + "fr": "Carte mémoire non formatée. Formatez la carte avant utilisation", + "ja": "メモリーカードがフォーマットされていません。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드가 포맷되지 않았습니다. 사용 전에 카드를 포맷하세요", + "ru": "Карта памяти не отформатирована. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı biçimlendirilmemiş. Kullanmadan önce kartı biçimlendirin", + "zh": "存储卡未格式化,请格式化后使用" + }, + "fpv_tip_0x1c100406_index_1": { + "de": "eMMC nicht formatiert. Vor Verwendung formatieren", + "en": "eMMC not formatted. Format before use", + "es": "", + "fr": "eMMC non formaté. Formatez avant utilisation", + "ja": "eMMCはフォーマットされていません。フォーマットしてから、使用してください", + "ko": "eMMC가 포맷되지 않았습니다. 사용 전에 포맷하세요.", + "ru": "eMMC-накопитель не отформатирован. Отформатируйте перед использованием", + "tr": "", + "zh": "EMMC未格式化,请格式化后使用" + }, + "fpv_tip_0x1c100407": { + "de": "Speicherkarte wird formatiert...", + "en": "Formatting memory card...", + "es": "Formateando la tarjeta de memoria...", + "fr": "Formatage de la carte mémoire…", + "ja": "メモリーカードのフォーマット中...", + "ko": "메모리 카드 포맷 중...", + "ru": "Форматирование карты памяти...", + "tr": "Hafıza kartı biçimlendiriliyor...", + "zh": "存储卡正在格式化,请等待" + }, + "fpv_tip_0x1c100407_index_1": { + "de": "eMMC-Formatierung. Bitte warten", + "en": "eMMC formatting. Please wait", + "es": "", + "fr": "Formatage de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCをフォーマットしています。お待ちください", + "ko": "eMMC를 포맷 중입니다. 기다려 주세요.", + "ru": "Форматирование eMMC. Подождите", + "tr": "", + "zh": "EMMC正在格式化,请等待" + }, + "fpv_tip_0x1c100408": { + "de": "Dateisystem der Speicherkarte wird nicht unterstützt. Karte vor Gebrauch formatieren.", + "en": "Memory card file system not supported. Format card before use", + "es": "Sistema de archivos de la tarjeta de memoria no compatible. Formatee la tarjeta antes del uso", + "fr": "Système de fichiers de la carte mémoire non pris en charge. Formatez la carte avant utilisation", + "ja": "メモリーカードファイルシステムはサポートされていません。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드 파일 시스템이 지원되지 않습니다. 사용 전에 카드를 포맷하세요", + "ru": "Файловая система карты памяти не поддерживается. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı dosya sistemi desteklenmiyor. Kullanmadan önce kartı biçimlendirin", + "zh": "不支持该存储卡文件系统,请格式化后使用" + }, + "fpv_tip_0x1c100409": { + "de": "Speicherkarte wird aktualisiert...", + "en": "Refreshing memory card...", + "es": "Actualizando la tarjeta de memoria...", + "fr": "Actualisation de la carte mémoire…", + "ja": "メモリーカードの更新中...", + "ko": "메모리 카드 새로고침 중...", + "ru": "Обновление карты памяти...", + "tr": "Hafıza kartı yenileniyor...", + "zh": "存储卡正在刷新,请等待" + }, + "fpv_tip_0x1c100409_index_1": { + "de": "eMMC-Aktualisierung. Bitte warten", + "en": "eMMC refreshing. Please wait", + "es": "", + "fr": "Actualisation de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCを更新しています。お待ちください", + "ko": "eMMC를 새로 고치는 중입니다. 기다려 주세요.", + "ru": "Обновление eMMC. Подождите", + "tr": "", + "zh": "EMMC正在刷新,请等待" + }, + "fpv_tip_0x1c10040B": { + "de": "Max. Dateiindex überschritten. SD-Karte formatieren", + "en": "Max file index exceeded. Format SD card", + "es": "Se ha superado el índice máximo de archivos. Formatear tarjeta SD", + "fr": "Index de fichier max. dépassé. Formater la carte SD", + "ja": "ファイルインデックスの最大値を超えました。SDカードをフォーマット", + "ko": "최대 파일 색인을 초과함. SD 카드 포맷", + "ru": "Превышен максимальный индекс файла. Форматировать карту памяти SD", + "tr": "Maks. dosya dizini aşıldı. SD kartı biçimlendir", + "zh": "文件索引超出最大限制,请格式化SD卡" + }, + "fpv_tip_0x1c10040a": { + "de": "Speicherkarte voll. Speicherplatz freigeben.", + "en": "Memory card full. Clear space", + "es": "Tarjeta de memoria llena. Libere espacio", + "fr": "Carte mémoire pleine. Libérez de l'espace", + "ja": "メモリーカードが満杯です。 領域をクリア", + "ko": "메모리 카드 공간 없음. 공간을 확보하세요", + "ru": "Карта памяти заполнена. Освободите место", + "tr": "Hafıza kartı dolu. Yer açın", + "zh": "存储卡已满,请清除内存" + }, + "fpv_tip_0x1c10040a_index_1": { + "de": "eMMC voll. Speicherplatz freigeben", + "en": "eMMC full. Clear space", + "es": "", + "fr": "Stockage eMMC saturé. Libérez de l'espace", + "ja": "eMMCに空き容量がありません。空き容量を増やしてください", + "ko": "eMMC가 가득 찼습니다. 공간을 정리하세요.", + "ru": "eMMC-накопитель заполнен. Освободите место", + "tr": "", + "zh": "EMMC已满,请清除内存" + }, + "fpv_tip_0x1c10040b": { + "de": "Max. Dateiindex überschritten. SD-Karte formatieren", + "en": "Max file index exceeded. Format SD card", + "es": "Se ha superado el índice máximo de archivos. Formatear tarjeta SD", + "fr": "Index de fichier max. dépassé. Formater la carte SD", + "ja": "ファイルインデックスの最大値を超えました。SDカードをフォーマット", + "ko": "최대 파일 색인을 초과함. SD 카드 포맷", + "ru": "Превышен максимальный индекс файла. Форматировать карту памяти SD", + "tr": "Maks. dosya dizini aşıldı. SD kartı biçimlendir", + "zh": "文件索引超出最大限制,请格式化SD卡" + }, + "fpv_tip_0x1c10040b_index_1": { + "de": "eMMC-Speicherüberlauf. eMMC formatieren und Kamera neu starten", + "en": "eMMC memory overflow. Format eMMC and restart camera", + "es": "", + "fr": "Débordement de la mémoire eMMC. Formatez l'eMMC et redémarrez la caméra", + "ja": "eMMCメモリのオーバーフローが発生しました。eMMCをフォーマットして、カメラを再起動してください", + "ko": "eMMC 메모리 오버플로입니다. eMMC를 포맷하고 카메라를 다시 시작하세요.", + "ru": "Переполнение памяти eMMC. Отформатируйте eMMC и перезапустите камеру", + "tr": "", + "zh": "EMMC内存溢出,请格式化EMMC并重启相机" + }, + "fpv_tip_0x1c10040c": { + "de": "Speicherkarte wird initialisiert...", + "en": "Initializing memory card...", + "es": "Inicializando tarjeta de memoria...", + "fr": "Initialisation de la carte mémoire…", + "ja": "メモリーカードの初期化中...", + "ko": "메모리 카드 초기화 중...", + "ru": "Инициализация карты памяти...", + "tr": "Hafıza kartı başlatılıyor...", + "zh": "存储卡正在初始化,请等待" + }, + "fpv_tip_0x1c10040c_index_1": { + "de": "eMMC-Initialisierung. Bitte warten", + "en": "eMMC initializing. Please wait", + "es": "", + "fr": "Initialisation de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCを初期化しています。お待ちください", + "ko": "eMMC를 초기화 중입니다. 기다려 주세요.", + "ru": "Инициализация eMMC. Подождите", + "tr": "", + "zh": "EMMC正在初始化,请等待" + }, + "fpv_tip_0x1c10040d": { + "de": "Speicherkartenfehler. Karte vor Gebrauch formatieren.", + "en": "Memory card error. Format card before use", + "es": "Error de la tarjeta de memoria. Formatee la tarjeta antes del uso", + "fr": "Erreur de carte mémoire. Formatez la carte avant utilisation", + "ja": "メモリーカードにエラーが発生しました。 カードをフォーマットしてから使用してください", + "ko": "메모리 카드 오류. 사용 전에 카드를 포맷하세요", + "ru": "Ошибка карты памяти. Отформатируйте карту перед использованием", + "tr": "Hafıza kartı hatası. Kullanmadan önce kartı biçimlendirin", + "zh": "存储卡异常,请格式化存储卡后使用" + }, + "fpv_tip_0x1c10040d_index_1": { + "de": "eMMC-Fehler. Vor Verwendung formatieren", + "en": "eMMC error. Format before use", + "es": "", + "fr": "Erreur eMMC. Formatez avant utilisation", + "ja": "eMMCのエラーです。フォーマットしてから、使用してください", + "ko": "eMMC 오류입니다. 사용 전에 포맷하세요.", + "ru": "Ошибка eMMC. Отформатируйте перед использованием", + "tr": "", + "zh": "EMMC异常,请格式化EMMC后使用" + }, + "fpv_tip_0x1c10040e": { + "de": "Speicherkarte wird repariert...", + "en": "Fixing memory card...", + "es": "Corrigiendo tarjeta de memoria...", + "fr": "Réparation de la carte mémoire…", + "ja": "メモリーカードの修正中...", + "ko": "메모리 카드 문제 해결 중...", + "ru": "Исправление карты памяти...", + "tr": "Hafıza kartı düzeltiliyor...", + "zh": "存储卡修复中,请等待" + }, + "fpv_tip_0x1c10040e_index_1": { + "de": "eMMC-Reparatur wird ausgeführt. Bitte warten", + "en": "eMMC repair in progress. Please wait", + "es": "", + "fr": "Réparation de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCを修復しています。お待ちください", + "ko": "eMMC 수리가 진행 중입니다. 기다려 주세요.", + "ru": "Идет восстановление eMMC. Подождите", + "tr": "", + "zh": "EMMC修复中,请等待" + }, + "fpv_tip_0x1c10040f": { + "de": "Niedrige Lese- und Schreibgeschwindigkeit für Speicherkarte. Warten, bis der Vorgang abgeschlossen wurde.", + "en": "Memory card read and write speed low. Wait until process completes", + "es": "Velocidad baja de lectura y escritura de la tarjeta de memoria. Espere hasta que se complete el proceso", + "fr": "Vitesse de lecture et d'écriture de la carte mémoire lente. Attendez que le processus soit terminé", + "ja": "メモリーカード読み取り/書き込みが低速です。 プロセスが完了するまでお待ちください", + "ko": "메모리 카드 읽기 및 쓰기 속도가 느립니다. 프로세스가 완료될 때까지 기다리세요", + "ru": "Низкая скорость чтения и записи карты памяти. Подождите, пока процесс завершится", + "tr": "Hafıza kartının okuma ve yazma hızı düşük. İşlem tamamlanana kadar bekleyin", + "zh": "存储卡读写缓慢,请等待" + }, + "fpv_tip_0x1c10040f_index_1": { + "de": "eMMC-Lesen und -Schreiben langsam. Bitte warten", + "en": "eMMC read and write speed low. Please wait", + "es": "", + "fr": "Vitesse de lecture et d'écriture de l'eMMC basse. Veuillez patienter", + "ja": "eMMCの読み取り/書き込み速度が低下しています。お待ちください", + "ko": "eMMC 읽기 및 쓰기 속도가 느립니다. 기다려 주세요.", + "ru": "Низкая скорость чтения и записи eMMC. Подождите", + "tr": "", + "zh": "EMMC读写缓慢,请等待" + }, + "fpv_tip_0x1c200405_index_1": { + "de": "eMMC-Lese- und Schreibeigenschaften bestätigen", + "en": "Confirm eMMC read and write properties", + "es": "", + "fr": "Confirmez les propriétés de lecture et d'écriture de l'eMMC", + "ja": "eMMCの読み取り/書き込みプロパティを確認", + "ko": "eMMC 읽기 및 쓰기 속성을 확인하세요.", + "ru": "Подтвердите наличие разрешений на чтений и запись eMMC-накопителя", + "tr": "", + "zh": "请确认EMMC读写属性" + }, + "fpv_tip_0x1c200406_index_1": { + "de": "eMMC nicht formatiert. Vor Verwendung formatieren", + "en": "eMMC not formatted. Format before use", + "es": "", + "fr": "eMMC non formaté. Formatez avant utilisation", + "ja": "eMMCはフォーマットされていません。フォーマットしてから、使用してください", + "ko": "eMMC가 포맷되지 않았습니다. 사용 전에 포맷하세요.", + "ru": "eMMC-накопитель не отформатирован. Отформатируйте перед использованием", + "tr": "", + "zh": "EMMC未格式化,请格式化后使用" + }, + "fpv_tip_0x1c200407_index_1": { + "de": "eMMC-Formatierung. Bitte warten", + "en": "eMMC formatting. Please wait", + "es": "", + "fr": "Formatage de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCをフォーマットしています。お待ちください", + "ko": "eMMC를 포맷 중입니다. 기다려 주세요.", + "ru": "Форматирование eMMC. Подождите", + "tr": "", + "zh": "EMMC正在格式化,请等待" + }, + "fpv_tip_0x1c200409_index_1": { + "de": "eMMC-Aktualisierung. Bitte warten", + "en": "eMMC refreshing. Please wait", + "es": "", + "fr": "Actualisation de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCを更新しています。お待ちください", + "ko": "eMMC를 새로 고치는 중입니다. 기다려 주세요.", + "ru": "Обновление eMMC. Подождите", + "tr": "", + "zh": "EMMC正在刷新,请等待" + }, + "fpv_tip_0x1c20040a_index_1": { + "de": "eMMC voll. Speicherplatz freigeben", + "en": "eMMC full. Clear space", + "es": "", + "fr": "Stockage eMMC saturé. Libérez de l'espace", + "ja": "eMMCに空き容量がありません。空き容量を増やしてください", + "ko": "eMMC가 가득 찼습니다. 공간을 정리하세요.", + "ru": "eMMC-накопитель заполнен. Освободите место", + "tr": "", + "zh": "EMMC已满,请清除内存" + }, + "fpv_tip_0x1c20040b": { + "de": "Max. Dateiindex überschritten. SD-Karte formatieren", + "en": "Max file index exceeded. Format SD card", + "es": "Se ha superado el índice máximo de archivos. Formatear tarjeta SD", + "fr": "Index de fichier max. dépassé. Formater la carte SD", + "ja": "ファイルインデックスの最大値を超えました。SDカードをフォーマット", + "ko": "최대 파일 색인을 초과함. SD 카드 포맷", + "ru": "Превышен максимальный индекс файла. Форматировать карту памяти SD", + "tr": "Maks. dosya dizini aşıldı. SD kartı biçimlendir", + "zh": "文件索引超出最大限制,请格式化SD卡" + }, + "fpv_tip_0x1c20040b_index_1": { + "de": "eMMC-Speicherüberlauf. eMMC formatieren und Kamera neu starten", + "en": "eMMC memory overflow. Format eMMC and restart camera", + "es": "", + "fr": "Débordement de la mémoire eMMC. Formatez l'eMMC et redémarrez la caméra", + "ja": "eMMCメモリのオーバーフローが発生しました。eMMCをフォーマットして、カメラを再起動してください", + "ko": "eMMC 메모리 오버플로입니다. eMMC를 포맷하고 카메라를 다시 시작하세요.", + "ru": "Переполнение памяти eMMC. Отформатируйте eMMC и перезапустите камеру", + "tr": "", + "zh": "EMMC内存溢出,请格式化EMMC并重启相机" + }, + "fpv_tip_0x1c20040c_index_1": { + "de": "eMMC-Initialisierung. Bitte warten", + "en": "eMMC initializing. Please wait", + "es": "", + "fr": "Initialisation de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCを初期化しています。お待ちください", + "ko": "eMMC를 초기화 중입니다. 기다려 주세요.", + "ru": "Инициализация eMMC. Подождите", + "tr": "", + "zh": "EMMC正在初始化,请等待" + }, + "fpv_tip_0x1c20040d_index_1": { + "de": "eMMC-Fehler. Vor Verwendung formatieren", + "en": "eMMC error. Format before use", + "es": "", + "fr": "Erreur eMMC. Formatez avant utilisation", + "ja": "eMMCのエラーです。フォーマットしてから、使用してください", + "ko": "eMMC 오류입니다. 사용 전에 포맷하세요.", + "ru": "Ошибка eMMC. Отформатируйте перед использованием", + "tr": "", + "zh": "EMMC异常,请格式化EMMC后使用" + }, + "fpv_tip_0x1c20040e_index_1": { + "de": "eMMC-Reparatur wird ausgeführt. Bitte warten", + "en": "eMMC repair in progress. Please wait", + "es": "", + "fr": "Réparation de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCを修復しています。お待ちください", + "ko": "eMMC 수리가 진행 중입니다. 기다려 주세요.", + "ru": "Идет восстановление eMMC. Подождите", + "tr": "", + "zh": "EMMC修复中,请等待" + }, + "fpv_tip_0x1c20040f_index_1": { + "de": "eMMC-Lesen und -Schreiben langsam. Bitte warten", + "en": "eMMC read and write speed low. Please wait", + "es": "", + "fr": "Vitesse de lecture et d'écriture de l'eMMC basse. Veuillez patienter", + "ja": "eMMCの読み取り/書き込み速度が低下しています。お待ちください", + "ko": "eMMC 읽기 및 쓰기 속도가 느립니다. 기다려 주세요.", + "ru": "Низкая скорость чтения и записи eMMC. Подождите", + "tr": "", + "zh": "EMMC读写缓慢,请等待" + }, + "fpv_tip_0x1c200410": { + "de": "Überprüfung vor Verwendung der Speicherkarte erforderlich. Passwort zur Verifizierung eingeben.", + "en": "Verification required before using memory card. Enter password to verify", + "es": "Se requiere verificación antes de usar la tarjeta de memoria. Introduce la contraseña para verificar", + "fr": "Vérification requise avant d'utiliser la carte mémoire. Entrez le mot de passe pour vérifier", + "ja": "メモリーカードの使用前に検証が必要です。 確認用パスワードを入力", + "ko": "메모리 카드를 사용하기 전에 인증이 필요합니다. 인증을 위해 비밀번호를 입력하세요", + "ru": "Требуется проверка перед использованием карты памяти. Введите пароль для проверки", + "tr": "Hafıza kartını kullanmadan önce doğrulama gerekli. Doğrulamak için parolayı girin", + "zh": "存储卡加密待验证,请输入密码验证后使用" + }, + "fpv_tip_0x1c300405_index_1": { + "de": "eMMC-Lese- und Schreibeigenschaften bestätigen", + "en": "Confirm eMMC read and write properties", + "es": "", + "fr": "Confirmez les propriétés de lecture et d'écriture de l'eMMC", + "ja": "eMMCの読み取り/書き込みプロパティを確認", + "ko": "eMMC 읽기 및 쓰기 속성을 확인하세요.", + "ru": "Подтвердите наличие разрешений на чтений и запись eMMC-накопителя", + "tr": "", + "zh": "请确认EMMC读写属性" + }, + "fpv_tip_0x1c300406_index_1": { + "de": "eMMC nicht formatiert. Vor Verwendung formatieren", + "en": "eMMC not formatted. Format before use", + "es": "", + "fr": "eMMC non formaté. Formatez avant utilisation", + "ja": "eMMCはフォーマットされていません。フォーマットしてから、使用してください", + "ko": "eMMC가 포맷되지 않았습니다. 사용 전에 포맷하세요.", + "ru": "eMMC-накопитель не отформатирован. Отформатируйте перед использованием", + "tr": "", + "zh": "EMMC未格式化,请格式化后使用" + }, + "fpv_tip_0x1c300407_index_1": { + "de": "eMMC-Formatierung. Bitte warten", + "en": "eMMC formatting. Please wait", + "es": "", + "fr": "Formatage de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCをフォーマットしています。お待ちください", + "ko": "eMMC를 포맷 중입니다. 기다려 주세요.", + "ru": "Форматирование eMMC. Подождите", + "tr": "", + "zh": "EMMC正在格式化,请等待" + }, + "fpv_tip_0x1c300409_index_1": { + "de": "eMMC-Aktualisierung. Bitte warten", + "en": "eMMC refreshing. Please wait", + "es": "", + "fr": "Actualisation de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCを更新しています。お待ちください", + "ko": "eMMC를 새로 고치는 중입니다. 기다려 주세요.", + "ru": "Обновление eMMC. Подождите", + "tr": "", + "zh": "EMMC正在刷新,请等待" + }, + "fpv_tip_0x1c30040a_index_1": { + "de": "eMMC voll. Speicherplatz freigeben", + "en": "eMMC full. Clear space", + "es": "", + "fr": "Stockage eMMC saturé. Libérez de l'espace", + "ja": "eMMCに空き容量がありません。空き容量を増やしてください", + "ko": "eMMC가 가득 찼습니다. 공간을 정리하세요.", + "ru": "eMMC-накопитель заполнен. Освободите место", + "tr": "", + "zh": "EMMC已满,请清除内存" + }, + "fpv_tip_0x1c30040b": { + "de": "Max. Dateiindex überschritten. SD-Karte formatieren", + "en": "Max file index exceeded. Format SD card", + "es": "Se ha superado el índice máximo de archivos. Formatear tarjeta SD", + "fr": "Index de fichier max. dépassé. Formater la carte SD", + "ja": "ファイルインデックスの最大値を超えました。SDカードをフォーマット", + "ko": "최대 파일 색인을 초과함. SD 카드 포맷", + "ru": "Превышен максимальный индекс файла. Форматировать карту памяти SD", + "tr": "Maks. dosya dizini aşıldı. SD kartı biçimlendir", + "zh": "文件索引超出最大限制,请格式化SD卡" + }, + "fpv_tip_0x1c30040b_index_1": { + "de": "eMMC-Speicherüberlauf. eMMC formatieren und Kamera neu starten", + "en": "eMMC memory overflow. Format eMMC and restart camera", + "es": "", + "fr": "Débordement de la mémoire eMMC. Formatez l'eMMC et redémarrez la caméra", + "ja": "eMMCメモリのオーバーフローが発生しました。eMMCをフォーマットして、カメラを再起動してください", + "ko": "eMMC 메모리 오버플로입니다. eMMC를 포맷하고 카메라를 다시 시작하세요.", + "ru": "Переполнение памяти eMMC. Отформатируйте eMMC и перезапустите камеру", + "tr": "", + "zh": "EMMC内存溢出,请格式化EMMC并重启相机" + }, + "fpv_tip_0x1c30040c_index_1": { + "de": "eMMC-Initialisierung. Bitte warten", + "en": "eMMC initializing. Please wait", + "es": "", + "fr": "Initialisation de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCを初期化しています。お待ちください", + "ko": "eMMC를 초기화 중입니다. 기다려 주세요.", + "ru": "Инициализация eMMC. Подождите", + "tr": "", + "zh": "EMMC正在初始化,请等待" + }, + "fpv_tip_0x1c30040d_index_1": { + "de": "eMMC-Fehler. Vor Verwendung formatieren", + "en": "eMMC error. Format before use", + "es": "", + "fr": "Erreur eMMC. Formatez avant utilisation", + "ja": "eMMCのエラーです。フォーマットしてから、使用してください", + "ko": "eMMC 오류입니다. 사용 전에 포맷하세요.", + "ru": "Ошибка eMMC. Отформатируйте перед использованием", + "tr": "", + "zh": "EMMC异常,请格式化EMMC后使用" + }, + "fpv_tip_0x1c30040e_index_1": { + "de": "eMMC-Reparatur wird ausgeführt. Bitte warten", + "en": "eMMC repair in progress. Please wait", + "es": "", + "fr": "Réparation de l'eMMC en cours. Veuillez patienter", + "ja": "eMMCを修復しています。お待ちください", + "ko": "eMMC 수리가 진행 중입니다. 기다려 주세요.", + "ru": "Идет восстановление eMMC. Подождите", + "tr": "", + "zh": "EMMC修复中,请等待" + }, + "fpv_tip_0x1c30040f_index_1": { + "de": "eMMC-Lesen und -Schreiben langsam. Bitte warten", + "en": "eMMC read and write speed low. Please wait", + "es": "", + "fr": "Vitesse de lecture et d'écriture de l'eMMC basse. Veuillez patienter", + "ja": "eMMCの読み取り/書き込み速度が低下しています。お待ちください", + "ko": "eMMC 읽기 및 쓰기 속도가 느립니다. 기다려 주세요.", + "ru": "Низкая скорость чтения и записи eMMC. Подождите", + "tr": "", + "zh": "EMMC读写缓慢,请等待" + }, + "fpv_tip_0x1f0b0017": { + "de": "LTE-Übertragung nicht verfügbar. Netzwerkkonnektivität der Fernsteuerung überprüfen", + "en": "LTE Transmission unavailable. Check remote controller network connectivity", + "es": "Transmisión LTE no disponible. Comprueba la conectividad de red del control remoto", + "fr": "Transmission LTE non disponible. Vérifiez la connectivité réseau de la radiocommande", + "ja": "LTE通信は利用できません。リモートコントローラーのネットワーク接続を確認してください", + "ko": "LTE 전송을 사용할 수 없습니다. 조종기 네트워크 연결을 확인하세요.", + "ru": "", + "tr": "", + "zh": "LTE链路不可用,请检查遥控器的网络能力" + }, + "fpv_tip_0x20010100": { + "de": "Fernsteuerung %2$s hat die Steuerung von Gimbal %1$s übernommen", + "en": "Remote controller %2$s obtained gimbal %1$s control", + "es": "El control remoto %2$s ha obtenido el control del estabilizador %1$s", + "fr": "La radiocommande %2$s a obtenu le contrôle de la nacelle %1$s", + "ja": "送信機%2$sがジンバル%1$sの制御を取得しました", + "ko": "RC %2$s 짐벌 %1$s 제어권 가져옴", + "ru": "Пульт %2$s получил управление стабилизатором %1$s", + "tr": "%2$s uzaktan kumandası, %1$s gimbalının kontrolünü aldı", + "zh": "云台%1$s的控制权已被%2$s控获取" + }, + "fpv_tip_0x20010200": { + "de": "Steuerung des aktuellen Gimbals übernommen", + "en": "Obtained control of current gimbal", + "es": "Se ha obtenido el control del estabilizador actual", + "fr": "Contrôle de la nacelle actuelle obtenu", + "ja": "現在のジンバルの制御を取得しました", + "ko": "현재 짐벌 제어권 가져옴", + "ru": "Получено управление данным стабилизатором", + "tr": "Mevcut gimbalın kontrolünü aldı", + "zh": "已成功获取该云台的控制权" + }, + "fpv_tip_0x20010301": { + "de": "Freier Modus", + "en": "Free-mode", + "es": "Modo Libre", + "fr": "Mode libre", + "ja": "フリーモード", + "ko": "프리 모드", + "ru": "Свободный", + "tr": "Serbest Mod", + "zh": "自由模式" + }, + "fpv_tip_0x20010302": { + "de": "Folgen", + "en": "Follow", + "es": "Seguir", + "fr": "Suivre", + "ja": "追跡", + "ko": "팔로우", + "ru": "Следование", + "tr": "İzle", + "zh": "跟随模式" + }, + "fpv_tip_0x20010304": { + "de": "Wechsel des Gimbal-Modus fehlgeschlagen. Bitte später erneut versuchen.", + "en": "Failed to change gimbal mode, please try again.", + "es": "No se pudo cambiar el modo de estabilizador. Vuelve a intentarlo.", + "fr": "Impossible de modifier le mode de nacelle, veuillez réessayer.", + "ja": "ジンバルモードの変更に失敗しました。もう一度やり直してください。", + "ko": "짐벌 모드 변경 실패. 다시 시도해주세요", + "ru": "Не удалось изменить режим стабилизатора. Повторите попытку", + "tr": "Gimbal modu değişimi başarısız, lütfen tekrar deneyin.", + "zh": "云台模式设置失败,请重试" + }, + "fpv_tip_0x20010400": { + "de": "Hinweis: Nur die erste Kamera im dualen Gimbal-Modus ist in der Lage Tap-Zoom zu verwenden.", + "en": "Tip: Only the first camera can tap-zoom in dual gimbal control mode.", + "es": "Consejo: En el modo de control de estabilizador doble, el zoom táctil solo está disponible en la primera cámara.", + "fr": "Seule la première caméra peut tap-zoom en mode de contrôle double nacelle.", + "ja": "ヒント:1 つ目のカメラのみで、デュアルジンバルコントロールモードでタップズームが可能です。", + "ko": "주의: 듀얼 짐벌 제어 모드에서 제1카메라에서만 TapZoom을 사용할 수 있습니다", + "ru": "Примечание: приближение нажатием на экран доступно только для 1-й камеры в режиме управления 2-мя стабилизаторами.", + "tr": "İpucu: Sadece ilk kamerada, çift gimbal kontrol modunda dokunarak yakınlaştırma özelliği kullanılabilir.", + "zh": "提示:开启双云台同时控制模式时,只能使用1号云台指点变焦功能" + }, + "fpv_tip_0x20010501": { + "de": "Gimbal zentrieren", + "en": "Gimbal Recenter", + "es": "Volver a centrar estabilizador", + "fr": "Recentrer", + "ja": "ジンバルの中心を再設定", + "ko": "짐벌 중앙 복귀", + "ru": "Центрировать камеру", + "tr": "Gimbalı Tekrar Ortala", + "zh": "云台回中" + }, + "fpv_tip_0x20010502": { + "de": "Gimbal-Schwenk zentrieren", + "en": "Recenter Gimbal Pan", + "es": "Volver a centrar paneo del estabilizador", + "fr": "Recentrer pano nacelle", + "ja": "ジンバル パンを再センタリング", + "ko": "짐벌 요 중앙 복귀", + "ru": "Центрировать камеру по оси поворота", + "tr": "Gimbalı Yana Dönüş Kafasını Tekrar Ortalayın", + "zh": "云台偏航回中" + }, + "fpv_tip_0x20010503": { + "de": "Gimbal-Nickwinkel nach oben", + "en": "Gimbal Pitch Up", + "es": "Inclinación hacia arriba del estabilizador", + "fr": "Augmenter inclin. nacelle", + "ja": "ジンバルピッチアップ", + "ko": "짐벌 피치 위로", + "ru": "Наклон стабилизатора вверх", + "tr": "Gimbal Yükselme Eksenini Yukarıya Kaldır", + "zh": "云台俯仰朝上" + }, + "fpv_tip_0x20010504": { + "de": "Gimbal-Nickwinkel abwärts", + "en": "Gimbal Pitch Down", + "es": "Inclinación hacia abajo del estabilizador", + "fr": "Baisser inclin. nacelle", + "ja": "ジンバルピッチ ダウン", + "ko": "짐벌 피치 다운", + "ru": "Опускание наклона подвеса", + "tr": "Gimbal Yükselme Eksenini Aşağıya İndir", + "zh": "云台俯仰朝下" + }, + "fpv_tip_0x20010505": { + "de": "Gimbal nach oben", + "en": "Gimbal Up", + "es": "Estabilizador hacia arriba", + "fr": "Nacelle relevée", + "ja": "ジンバルアップ", + "ko": "짐벌 위로", + "ru": "Поднятие стабилизатора", + "tr": "Gimbalı Yukarı Kaldır", + "zh": "云台朝上" + }, + "fpv_tip_0x20010506": { + "de": "Gimbal abwärts", + "en": "Gimbal down", + "es": "Estabilizador hacia abajo", + "fr": "Nacelle baissée", + "ja": "ジンバル下降", + "ko": "짐벌 다운", + "ru": "Опускание подвеса", + "tr": "Gimbalı aşağı indir", + "zh": "云台向下" + }, + "fpv_tip_0x20010507": { + "de": "Gimbal-Nickwinkel zentrieren", + "en": "Gimbal Pitch Recenter", + "es": "Volver a centrar inclinación del estabilizador", + "fr": "Recentrer l\\'inclinaison de la nacelle", + "ja": "ジンバルピッチ 再センタリング", + "ko": "짐벌 피치 중앙 복귀", + "ru": "Повторная центровка наклона подвеса", + "tr": "Gimbal Yükselme Eksenini Tekrar Ortala", + "zh": "云台俯仰回中" + }, + "fpv_tip_0x20010508": { + "de": "Gimbal-Rolle zentriert", + "en": "Gimbal roll centered", + "es": "Rotación del estabilizador centrada", + "fr": "Roulis de nacelle centré", + "ja": "ジンバルロールがセンタリング済み", + "ko": "짐벌 롤 중앙에 위치", + "ru": "Рамка крена гиростабилизатора выровнена по центру", + "tr": "Gimbal yatışı merkezli", + "zh": "云台横滚回中" + }, + "fpv_tip_0x20010600": { + "de": "Gimbal-Stabilisierung aktiviert", + "en": "Vision stabilization on.", + "es": "Estabilización visual activada.", + "fr": "Stabilisation optique en marche.", + "ja": "ビジョン安定化がオンです。", + "ko": "짐벌 안정화 시스템 켜짐", + "ru": "Стабилизация камеры включена", + "tr": "Görüş stabilizasyonu açık.", + "zh": "云台增稳开启" + }, + "fpv_tip_0x20010601": { + "de": "Gimbal-Stabilisierung deaktiviert", + "en": "Vision stabilization off.", + "es": "Estabilización visual desactivada.", + "fr": "Stabilisation optique arrêtée", + "ja": "ビジョン安定化がオフです。", + "ko": "짐벌 안정화 시스템 꺼짐", + "ru": "Стабилизация камеры выключена", + "tr": "Görüş stabilizasyonu kapalı.", + "zh": "云台增稳关闭" + }, + "fpv_tip_0x20010700": { + "de": "Kontrolle verloren: %1$s. Multi-Gimbal-Verbindung deaktiviert.", + "en": "Lost control of %1$s. Multi-Gimbal Connection disabled", + "es": "Se ha perdido el control de %1$s. Conexión de varios estabilizadores desactivada", + "fr": "Perte de contrôle de %1$s. Connexion Multi-nacelle désactivée", + "ja": "%1$sを制御できません。マルチジンバル接続が無効化", + "ko": "%1$s 제어권 상실. 멀티 짐벌 연결 비활성화됨", + "ru": "Потерян контроль %1$s. Все стабилизаторы отключены", + "tr": "%1$s’in kontrolü kaybedildi. Çoklu Gimbal Bağlantısı devre dışı", + "zh": "失去%1$s的控制权,联动取消" + }, + "fpv_tip_0x20010701": { + "de": "Kontrolle verloren: %1$s. %2$s wurde aus der Multi-Gimbal-Verbindung entfernt", + "en": "Lost control of %1$s. %2$s dropped from Multi-Gimbal Connection", + "es": "Se ha perdido el control de %1$s. %2$s se ha desconectado de Conexión de varios estabilizadores", + "fr": "Perte de contrôle de %1$s. %2$s a quitté la connexion Multi-nacelle", + "ja": "%1$sを制御できません。%2$sはマルチジンバル接続を中止", + "ko": "%1$s 제어권 상실. 멀티 짐벌 연결에서 %2$s 끊김", + "ru": "Потерян контроль %1$s. Произошло отключение %2$s", + "tr": "%1$s’ın kontrolü kaybedildi. %2$s, Çoklu Gimbal Bağlantısından düştü", + "zh": "失去%1$s的控制权,%2$s脱离联动" + }, + "fpv_tip_0x20010800": { + "de": "Übertragung unterbrochen. Gimbal Kontrolle verloren.", + "en": "Transmission interrupted. Gimbal control lost", + "es": "Transmisión interrumpida. Se ha perdido el control del estabilizador", + "fr": "Transmission interrompue. Contrôle de la nacelle perdu", + "ja": "伝送が中断されました。ジンバルの制御が失われました", + "ko": "전송 중단됨. 짐벌 제어권 상실", + "ru": "Передача прервана. Управление стабилизатором потеряно", + "tr": "İletim kesintiye uğradı. Gimbal kontrolü kaybedildi", + "zh": "链路中断,您失去了对云台的控制权。" + }, + "fpv_tip_0x20010900": { + "de": "Übertragung der Fernsteuerung %1$s unterbrochen. Steuerung über alle Gimbals übernommen", + "en": "Remote controller %1$s transmission interrupted. Gained control of all gimbals", + "es": "Transmisión del control remoto %1$s interrumpida. Se ha obtenido el control de todos los estabilizadores", + "fr": "Transmission de la radiocommande %1$s interrompue. Vous avez pris le contrôle de toutes les nacelles", + "ja": "送信機%1$sの伝送が中断されました。すべてのジンバルの制御を取得しました", + "ko": "조종기 %1$s 전송이 중단됨. 모든 짐벌에 대한 제어권 획득", + "ru": "Передача данных с пульта %1$s прервана. Получено управление всеми подвесами", + "tr": "%1$s uzaktan kumandası iletimi kesintiye uğradı. Tüm gimbalların kontrolü alındı", + "zh": "%1$s控连接中断,您已经获得所有云台的控制权。" + }, + "fpv_tip_0x20020000": { + "de": "Steuerung über Fluggerät übernommen. Aktueller Steuerknüppelmodus: %1$s", + "en": "Obtained aircraft flight control. Current control stick mode: %1$s", + "es": "Se ha obtenido el control de vuelo de la aeronave. Modo de palanca de control actual: %1$s", + "fr": "Contrôle du vol de l\\'appareil obtenu. Mode de contrôle actuel des joysticks : %1$s", + "ja": "機体の飛行制御権を取得しました。ジンバル操作スティックモード:%1$s", + "ko": "기체 비행 제어권을 획득함. 현재 조종 스틱 모드: %1$s", + "ru": "Получено управление полетом дрона. Текущий режим ручек управления: %1$s", + "tr": "Aracın uçuş kontrolü alındı. Mevcut kumanda çubuğu modu: %1$s", + "zh": "已成功获取飞行器的控制权,您当前的摇杆挡位为%1$s" + }, + "fpv_tip_0x20020001": { + "de": "Steuerung des Fluggeräts entsperrt", + "en": "Aircraft flight control unlocked", + "es": "Control de vuelo de la aeronave desbloqueado", + "fr": "Contrôle du vol de l\\'appareil déverrouillé", + "ja": "機体の飛行制御がロック解除されました", + "ko": "기체 비행 제어권 잠금 해제", + "ru": "Управление дроном разблокировано", + "tr": "Araç uçuş kontrolü kilidi açıldı", + "zh": "控制权已解锁" + }, + "fpv_tip_0x20020002": { + "de": "Steuerung des Fluggeräts gesperrt", + "en": "Aircraft flight control locked", + "es": "Control de vuelo de la aeronave bloqueado", + "fr": "Contrôle du vol de l\\'appareil verrouillé", + "ja": "機体の飛行制御がロックされました", + "ko": "기체 비행 제어권 잠김", + "ru": "Управление дроном заблокировано", + "tr": "Araç uçuş kontrolü kilitlendi", + "zh": "控制权已锁定" + }, + "fpv_tip_0x20020003": { + "de": "Fluggerätesteuerung durch Fernsteuerung %1$s übernommen", + "en": "Aircraft flight control obtained by remote controller %1$s", + "es": "El control remoto %1$s ha obtenido el control de vuelo de la aeronave", + "fr": "Contrôle du vol de l\\'appareil accordé à la radiocommande %1$s", + "ja": "送信機%1$sが機体の飛行制御権を取得しました", + "ko": "조종기 %1$s이(가) 기체 비행 제어권을 획득함", + "ru": "Управление полетом дрона получено пультом %1$s", + "tr": "Araç uçuş kontrolü, %1$s uzaktan kumandası tarafından alındı", + "zh": "飞行器的控制权已经被%1$s控获取" + }, + "fpv_tip_0x20020004": { + "de": "Übername der Gimbal-Steuerung nicht möglich", + "en": "Unable to obtain current gimbal control", + "es": "No se puede obtener el control del estabilizador actual", + "fr": "Impossible de prendre le contrôle de la nacelle actuelle", + "ja": "現在のジンバルの制御を取得できません", + "ko": "현재 짐벌 제어권 가져올 수 없음", + "ru": "Невозможно получить управление стабилизатором", + "tr": "Mevcut gimbalın kontrolünü alamıyor", + "zh": "当前状态下,不可夺取当前云台的控制权" + }, + "fpv_tip_0x20020005": { + "de": "Zweite Fernsteuerung hat Kontrolle über Gimbal %1$s", + "en": "Aircraft flight control locked by remote controller %1$s. Unable to obtain control", + "es": "El control remoto %1$s ha bloqueado el control de vuelo de la aeronave. No se puede obtener el control", + "fr": "La RC assistante a obtenu le contrôle de la nacelle %1$s", + "ja": "コンパニオンコントローラーがジンバル %1$s の制御権を取得", + "ko": "상대방 조종기가 짐벌 %1$s 제어권을 획득했습니다", + "ru": "Вспомогательный пульт получил управление подвесом %1$s", + "tr": "Araç uçuş kontrolü, %1$s uzaktan kumandası tarafından kitlendi. Kontrolü alamıyor", + "zh": "飞行器的控制权已被%1$s控锁定,无法获取控制权" + }, + "fpv_tip_0x20020006": { + "de": "Übername der Flugsteuerung nicht möglich", + "en": "Unable to obtain aircraft flight control", + "es": "No se puede obtener el control de vuelo de la aeronave", + "fr": "Impossible de prendre le contrôle du vol de L\\'appareil", + "ja": "機体の飛行制御を取得できません", + "ko": "기체 비행 제어권 가져올 수 없음", + "ru": "Невозможно получить управление дроном", + "tr": "Araç uçuş kontrolünü alamıyor", + "zh": "当前状态下,不可夺取飞行控制权" + }, + "fpv_tip_0x20020100": { + "de": "Hinweis: Fluggerät hat die maximale Flughöhe erreicht. Vorsichtig fliegen.", + "en": "Tip: Aircraft reached maximum distance, please pay attention to flight safety.\\n", + "es": "Consejo: La aeronave ha alcanzado la distancia máxima. Presta atención a la seguridad de vuelo.\\n", + "fr": "Note : L\\'appareil a atteint la distance maximum. Soyez attentifs à la sécurité du vol.", + "ja": "ヒント:機体は最大距離に到達しました。安全飛行を心掛けてください。\\n", + "ko": "주의: 기체 최대 거리 도달. 비행 시 주의해주세요", + "ru": "Примечание: достигнуто макс. расстояние. Будьте осторожны", + "tr": "İpucu: Araç maksimum mesafeye ulaştı, lütfen uçuş güvenliğine dikkat edin.\\n", + "zh": "提示:飞机已经达到最远距离, 请注意安全飞行" + }, + "fpv_tip_0x20020200": { + "de": "Hohe Windgeschwindigkeit. Vorsichtig fliegen.", + "en": "High Wind Velocity. Fly with caution.", + "es": "Velocidad del viento alta. Vuela con cuidado.", + "fr": "Alerte vent fort. Pilotez avec précaution.", + "ja": "強い風速です。慎重に飛行してください", + "ko": "높은 풍속. 비행 시 주의 필요.", + "ru": "Высокая скорость ветра. Будьте внимательны при полете.", + "tr": "Yüksek Rüzgar Hızı. Dikkatli uçun.", + "zh": "风速过大,谨慎飞行" + }, + "fpv_tip_0x20020201": { + "de": "Hohe Windgeschwindigkeit. Vorsichtig fliegen.", + "en": "High Wind Velocity. Fly with caution.", + "es": "Velocidad del viento alta. Vuela con cuidado.", + "fr": "Alerte vent fort. Pilotez avec précaution.", + "it": "", + "ja": "強い風速です。慎重に飛行してください", + "ko": "높은 풍속. 비행 시 주의 필요.", + "pt": "", + "ru": "Высокая скорость ветра. Будьте внимательны при полете.", + "tr": "Yüksek Rüzgar Hızı. Dikkatli uçun.", + "zh": "风速过大,谨慎飞行" + }, + "fpv_tip_0x20020300": { + "de": "ATTI-Modus", + "en": "ATTI mode", + "es": "Modo ATTI", + "fr": "Mode ATTI", + "ja": "ATTIモード", + "ko": "ATTI 모드", + "ru": "Режим ATTI", + "tr": "DAVRANIŞ modu", + "zh": "姿态模式" + }, + "fpv_tip_0x20020301": { + "de": "Kann den Flugmodus nicht umschalten. In den Flugreglereinstellungen den \\\"Multi-Flugmodus\\\" aktivieren, bevor der Flugmodus gewechselt wird.", + "en": "Cannot switch flight mode. Turn on \\\"Multiple Flight Modes\\\" to enable Atti and Sport Modes", + "es": "No se puede cambiar de modo de vuelo. Activa \\\"Modo de vuelo múltiple\\\" para habilitar los modos Atti y Sport", + "fr": "Impossible de changer de Mode de vol. Activer \\\"Modes de vol multiples\\\" pour activer les modes Atti et Sport", + "ja": "フライトモードを切り替えられません。「複数のフライトモード」をオンにして高度とスポーツモードを有効にしてください", + "ko": "비행 모드 변경 불가. 조종기 설정으로 이동해 비행 모드 전환 전 \\'다중 비행 모드\\'를 켭니다", + "ru": "Не удается изменить режим полета. Нажмите \\\"Выбор режима полета\\\", чтобы активировать режим аса и спортивный", + "tr": "Uçuş moduna geçiş yapılamıyor. Davranış ve Spor Modları etkinleştirmek için \\\"Çoklu Uçuş Modunu\\\" açın", + "zh": "不允许切换飞行挡位,如需切到其他挡,请在飞控设置打开\\'允许切换飞行挡位\\'开关" + }, + "fpv_tip_0x20020302": { + "de": "Auf den Modus \\\"S\\\" (Sport) gewechselt.", + "en": "Switched to S (Sport)-mode.", + "es": "Cambiado al modo-S (Sport).", + "fr": "Mode S (Sport) activé.", + "ja": "S (スポーツ) モードに切り替えました。", + "ko": "S(스포츠) 모드로 전환됨", + "ru": "Активирован режим S (спортивный).", + "tr": "S (Spor) moduna geçti.", + "zh": "已切换至S挡(运动)" + }, + "fpv_tip_0x20020303": { + "de": "Auf Modus \\\"P\\\" (Positon) gewechselt.", + "en": "Switched to P (Positioning)-mode.", + "es": "Cambiado al modo-P (Posicionamiento).", + "fr": "Mode P (Position) activé.", + "ja": "P (ポジショニング) モードに切り替えました。", + "ko": "P(포지셔닝) 모드로 전환됨", + "ru": "Режим P (позиционирования) активирован.", + "tr": "P (Konumlandırma) moduna geçti.", + "zh": "已切换至P挡(定位)" + }, + "fpv_tip_0x20020304": { + "de": "Auf den Modus \\\"T\\\" (Tripod) gewechselt.", + "en": "Switched to T (Tripod)-mode.", + "es": "Cambiado al modo-T (Trípode).", + "fr": "Mode T (Trépied) activé.", + "ja": "T (トライポッド) モードに切り替えました。", + "ko": "T(삼각대) 모드로 전환됨", + "ru": "Активирован режим T (штатив).", + "tr": "T (Tripot) moduna geçti.", + "zh": "已切换至T挡(三脚架)" + }, + "fpv_tip_0x20020305": { + "de": "Auf Modus \\\"A\\\" (Attitude) gewechselt.", + "en": "Switched to A (Attitude)-mode.", + "es": "Cambiado al modo-A (Atti).", + "fr": "Mode A (Attitude) activé.", + "ja": "A (Atti) モードに切り替えました。", + "ko": "A(자세) 모드로 전환됨", + "ru": "Активирован режим А (аса).", + "tr": "A (Davranış) moduna geçti.", + "zh": "已切换至A挡(姿态)" + }, + "fpv_tip_0x20020306": { + "de": "Zum Abheben in allen Modi außer „P“, den Flugmodusschalter in einen anderen Modus umschalten und ihn dann zurückzuschalten.", + "en": "To take off in non-P mode, toggle Flight Mode Switch to another mode and then toggle it back.", + "es": "Para despegar en modo-P, cambia el selector de modo de vuelo a otro modo y luego vuelve a cambiarlo.", + "fr": "Pour décoller dans des modes autres que le Mode-P, changez de mode de vol puis réactivez celui-ci.", + "ja": "P 以外のモードで離陸するには、フライトモードスイッチを別のモードに切り替えてから、戻してください。", + "ko": "P 모드가 아닌 모드로 이륙하면, 비행 모드 스위치를 사용해 다른 모드로 전환한 후 다시 돌아와야 합니다", + "ru": "Чтобы взлететь в другом режиме, выберите его на пульте, затем переведите переключатель в прежнее положение.", + "tr": "P modu dışında kalkış yapmak için Uçuş Modu Anahtarını diğer moda kaydırıp sonra tekrar geri eski konumuna kaydırın.", + "zh": "如果要以非P挡起飞,请切换挡位至其他挡再切回当前挡以确认。" + }, + "fpv_tip_0x20020307": { + "en": "When winch mode is enabled, aircraft acceleration is limited and braking time is extended", + "zh": "空吊模式下,加速度受限,刹停时间变长" + }, + "fpv_tip_0x20020400": { + "de": "Verbleibender Akkustand reicht nur noch für Rückkehr. Jetzt automatisch zum Startpunkt zurückkehren", + "en": "The remaining battery is only enough for RTH. Return home now.", + "es": "La batería restante solo es suficiente para RPO. Regresa al punto de origen ahora.", + "fr": "Le niveau de batterie restant ne suffit qu\\'au RTH. Retour au point de départ immédiat.", + "ja": "残量バッテリーでは RTH のみを実行できます。今すぐホームに帰還します。", + "ko": "RTH 진행할 배터리 잔량만 남음. 지금 RTH 시작", + "ru": "Оставшегося заряда хватит только на возврат домой. Возврат активирован", + "tr": "Kalan pil sadece eve dönüş için yeterli. Şimdi eve dön.", + "zh": "当前电量仅够返回返航点,请尽快返航。" + }, + "fpv_tip_0x20020500": { + "de": "Startpunkt aufgezeichnet. Höhe des Rückflugs: %1$.1f %2$s", + "en": "Home Point recorded. Return-to-Home Altitude:%1$.1f %2$s", + "es": "Punto de origen registrado. Altitud de Regreso al punto de origen: %1$.1f %2$s", + "fr": "Point de départ enregistré. Altitude RTH : %1$.1f %2$s", + "ja": "ホームポイントを記録。RTH高度:%1$.1f %2$s", + "ko": "홈포인트 기록됨. RTH 고도: %1$.1f %2$s", + "ru": "Дом. точка записана. Высота возврата домой: %1$.1f %2$s", + "tr": "Ev Noktası kaydedildi. Eve Dönüş İrtifası:%1$.1f %2$s", + "zh": "返航点已记录,返航高度:%1$.1f %2$s" + }, + "fpv_tip_0x20020600": { + "de": "Niedriger Akkustand. Fluggerät kehrt zum Startpunkt zurück.", + "en": "Low power. Aircraft will return home.", + "es": "Batería baja. La aeronave regresará al punto de origen.", + "fr": "Batterie faible. L\\'appareil retournera à son point de départ.", + "ja": "低電力。機体は帰還します。", + "ko": "배터리 부족. 기체 RTH 시작", + "ru": "Низкий заряд батареи. Дрон возвращается в дом. точку", + "tr": "Düşük güç. Araç eve dönecek.", + "zh": "低电量,飞机开始返航" + }, + "fpv_tip_0x20020601": { + "de": "Akkustand sehr niedrig! Fluggerät landet. Mit den Steuerknüppeln kann die Sinkgeschwindigkeit verlangsamt oder Objekten ausgewichen werden.", + "en": "Critically low power. Aircraft is landing.", + "es": "Nivel de batería crítico. La aeronave está aterrizando.", + "fr": "Batterie dangereusement faible. Atterrissage de l\\'appareil.", + "ja": "重度の低電力。機体は着陸中です。", + "ko": "배터리 매우 부족. 기체 착륙 중. 조종 스틱을 조정해 하강 속도를 늦추거나 장애물을 피하세요", + "ru": "Критически низкий заряд батареи. Дрон садится. Управляйте джойстиками, чтобы снизить скорость или избежать препятствие", + "tr": "Kritik seviyede düşük güç. Araç iniş yapıyor.", + "zh": "严重低电量,系统强制降落,无法取消,您可以通过推油门减缓下降速度,调整摇杆方向避开危险" + }, + "fpv_tip_0x20020602": { + "de": "Der verbleibende Akkustand reicht nur zur Rückkehr zum Startpunkt.", + "en": "Low power. Returning home.", + "es": "Batería baja. Regresando al punto de origen.", + "fr": "Batterie faible. Retour au point de départ.", + "ja": "低電力。ホームに帰還中。", + "ko": "RTH 진행할 배터리 잔량만 남음. 지금 RTH 시작", + "ru": "Заряда батареи хватит только на возврат домой. Дрон начинает возврат", + "tr": "Düşük güç. Eve dönüyor.", + "zh": "系统计算您当前电量仅足够返回返航点,飞机开始返航" + }, + "fpv_tip_0x20020603": { + "de": "Verbleibender Akkustand reicht nur zur Landung. Fluggerät landet.", + "en": "Critically low power. Aircraft is landing.", + "es": "Nivel de batería crítico. La aeronave está aterrizando.", + "fr": "Batterie dangereusement faible. Atterrissage de l\\'appareil.", + "ja": "重度の低電力。機体は着陸中です。", + "ko": "RTH 진행할 배터리 잔량만 남음. 기체 착륙 중", + "ru": "Заряда батареи хватит только на посадку. Дрон садится", + "tr": "Kritik seviyede düşük güç. Araç iniş yapıyor.", + "zh": "当前电量仅够当前高度降落,系统将强制下降,无法取消" + }, + "fpv_tip_0x20020604": { + "de": "Akkuladezustand sehr niedrig. Fluggerät landet. RTH-Taste auf der Fernsteuerung drücken um abzubrechen.", + "en": "Critically low voltage. Aircraft is landing. Press the RTH button on the remote controller to stop.", + "es": "Voltaje crítico. La aeronave está aterrizando. Pulsa el botón RPO en el control remoto para detener.", + "fr": "Tension dangereusement faible. L\\'appareil est en phase d\\'atterrissage. Appuyez sur le bouton RTH (Return to Home) de la radiocommande pour interrompre.", + "ja": "重度の低電圧。機体は着陸中。送信機のRTHボタンを押すと、停止します。", + "ko": "전압 매우 낮음. 기체 착륙 중. 조종기의 RTH 버튼을 누르면 취소합니다", + "ru": "Критически низкое напряжение. Дрон садится. Нажмите кнопку \\\"RTH\\\" на пульте, чтобы отменить посадку.", + "tr": "Kritik seviyede düşük voltaj. Araç iniş yapıyor. Durmak için uzaktan kumanda üzerindeki Eve Dönüş düğmesine basın.", + "zh": "严重低电压,系统强制降落,短按遥控器上的返航按钮停止降落" + }, + "fpv_tip_0x20020605": { + "de": "Niedrige Spannung. Fluggerät kehrt zum Startpunkt zurück. RTH-Taste auf der Fernsteuerung drücken, um abzubrechen.", + "en": "Low voltage. Returning home now. Press the RTH button on the remote controller to stop.", + "es": "Voltaje bajo. Regresando al punto de origen ahora. Pulsa el botón RPO en el control remoto para detener.", + "fr": "Tension faible. Retour au point de départ. Appuyez sur le bouton RTH (Return to Home) de la radiocommande pour annuler.", + "ja": "低電圧。ホームに直ちに帰還します。送信機のRTHボタンを押すと、停止します。", + "ko": "저전압. 즉시 RTH 진행 필요. 조종기의 RTH 버튼을 누르면 취소합니다", + "ru": "Низкое напряжение. Дрон возвращается домой. Нажмите кнопку \\\"RTH\\\" на пульте, чтобы отменить возврат.", + "tr": "Düşük voltaj. Şimdi eve dönüyor. Durmak için uzaktan kumanda üzerindeki Eve Dönüş düğmesine basın.", + "zh": "低电压报警,飞机开始返航,短按遥控器上的返航按钮停止返航" + }, + "fpv_tip_0x20020606": { + "de": "Warnung! Fluggerät landet aufgrund zu niedriger Spannung. Steuerknüppel nutzen um Hindernissen auszuweichen und die Sinkgeschwindigkeit zu reduzieren.", + "en": "Aircraft is landing due to low voltage, which cannot be stopped. You can decelerate the descending speed and avoid obstacles using sticks.", + "es": "La aeronave está aterrizando debido a un voltaje bajo. No se puede detener. Puedes reducir la velocidad de descenso y evitar obstáculos mediante el uso de las palancas.", + "fr": "Atterrissage de l\\'appareil causé par une faible tension. Impossible de l\\'interrompre. Vous pouvez ralentir la vitesse de descente et éviter les obstacles avec les joysticks.", + "ja": "低電圧のため、機体は着陸中です。停止できません。下降速度を減速し、操作スティックで障害物を避けることはできます。", + "ko": "저전압으로 기체가 강제 착륙 중. 조종 스틱을 사용해 하강 속도를 줄이고 장애물을 피할 수 있습니다", + "ru": "Дрон садится из-за низкого напряжения. Посадку нельзя отменить. Используйте джойстики, чтобы снизить скорость или избегать препятствия.", + "tr": "Araç, durdurulamayan düşük voltaj nedeniyle iniş yapıyor. Kumanda kollarını kullanarak iniş hızını azaltabilir ve engelleri önleyebilirsiniz.", + "zh": "电池电压过低,系统强制降落,无法取消,您可以通过推油门减缓下降速度,调整摇杆方向避开危险" + }, + "fpv_tip_0x20020607": { + "de": "Fluggerät kehrt zum Startpunkt zurück. Die minimale Flughöhe für die Rückkehr beträgt %1$d m. Diese Flughöhe kann in den Einstellungen der Fernsteuerung festgelegt werden nachdem RTH abgebrochen wurde.", + "en": "Aircraft is returning to the Home Point. Minimum RTH Altitude is %1$dm. You can reset the RTH Altitude in Remote Controller Settings after cancelling RTH if necessary.", + "es": "La aeronave está regresando al punto de origen. La altitud de RPO mínima es de %1$d m. Si es necesario, puedes restaurar la altitud de RPO en Configuración del control remoto después de cancelar RPO.", + "fr": "Retour de l\\'appareil au point de départ. L’altitude minimum de RTH est de %1$d m. Vous pouvez réinitialiser l’altitude RTH dans les paramètres de radiocommande après avoir annulé le Retour au point de départ.", + "ja": "機体はホームポイントに帰還します。最低 RTH 高度は %1$dm です。必要に応じて、RTH をキャンセルした後に送信機の設定で RTH をリセットできます。", + "ko": "기체 RTH 중. 최저 RTH 고도 %1$d m. 필요한 경우, RTH 취소 후 조종기에서 RTH 고도를 조정할 수 있습니다", + "ru": "Дрон возвращается в дом. точку. Мин. высота: %1$d м. Высоту возврата домой можно изменить в настройках пульта после отмены процедуры возврата.", + "tr": "Araç, Ev Noktasına dönüyor. Minimum Eve Dönüş İrtifası %1$dm. Gerekirse, Eve Dönüşü iptal ettikten sonra Uzaktan Kumanda Ayarları’nda Eve Dönüş İrtifasını sıfırlayabilirsiniz.", + "zh": "开始自动返航,最低返航高度%1$d米。如需调整返航高度,可在取消返航后到飞控设置中重新设置返航高度" + }, + "fpv_tip_0x20020608": { + "de": "Fluggerät kehrt zum Startpunkt zurück. Die minimale Flughöhe für die Rückkehr beträgt %1$d m. Diese Flughöhe kann in den Einstellungen der Fernsteuerung festgelegt werden nachdem RTH abgebrochen wurde.", + "en": "Aircraft is returning to the Home Point. RTH Altitude is %1$dm. You can reset the RTH Altitude in Remote Controller Settings after cancelling RTH if necessary.", + "es": "La aeronave está regresando al punto de origen. La altitud de RPO es de %1$d m. Si es necesario, puedes restaurar la altitud de RPO en Configuración del control remoto después de cancelar RPO.", + "fr": "Retour de l\\'appareil au point de départ. L’altitude de RTH est de %1$d m. Vous pouvez réinitialiser l’altitude RTH dans les paramètres de radiocommande après avoir annulé le Retour au point de départ.", + "ja": "機体はホームポイントに帰還中。RTH高度は %1$dm。必要な場合、RTH操作をキャンセルした後、送信機設定でRTH高度をリセットできます。", + "ko": "기체 RTH 중. 최저 RTH 고도 %1$d m. 필요한 경우, RTH 취소 후 조종기에서 RTH 고도를 조정할 수 있습니다", + "ru": "Дрон возвращается в дом. точку. Мин. высота: %1$d м. Высоту возврата домой можно изменить в настройках пульта после отмены процедуры возврата.", + "tr": "Araç, Ev Noktasına dönüyor. Eve Dönüş İrtifası %1$dm. Gerekirse, Eve Dönüşü iptal ettikten sonra Uzaktan Kumanda Ayarları’nda Eve Dönüş İrtifasını sıfırlayabilirsiniz.", + "zh": "开始自动返航,最低返航高度%1$d米。如需调整返航高度,可在取消返航后到飞控设置中重新设置返航高度" + }, + "fpv_tip_0x20020609": { + "de": "Fluggerätsignal verloren. Rückkehrfunktion (RTH) gestartet", + "en": "Aircraft signal lost. RTH started", + "es": "Se ha perdido la señal de la aeronave. RPO iniciado", + "fr": "Signal de l'appareil perdu. RTH lancé", + "ja": "機体の信号ロストです。RTHが開始しました", + "ko": "기체 신호 끊김. RTH 시작됨", + "ru": "Сигнал дрона потерян. Возврат домой начался", + "tr": "Hava aracı sinyali kayboldu. Eve Dönüş başladı", + "zh": "飞行器失联,开始返航" + }, + "fpv_tip_0x2002060A": { + "de": "Sie befinden sich in einem Flugbeschränkungsgebiet. Die automatische Landung wird eingeleitet ...", + "en": "You are in a No-Fly Zone. Auto landing initiated.", + "es": "Estás en una zona de exclusión aérea. Se ha iniciado el aterrizaje automático.", + "fr": "Vous êtes dans une zone restreinte. Atterrissage automatique enclenché.", + "ja": "飛行禁止区域です。自動着陸が開始しました。", + "ko": "제한 구역에 있음. 자동 착륙 중...", + "ru": "Дрон в зоне GEO. Идет автопосадка.", + "tr": "Uçuşa Kapalı bölgedesiniz. Otomatik iniş başlatıldı.", + "zh": "飞行器在禁飞区内,开始自动降落" + }, + "fpv_tip_0x2002060B": { + "de": "Fluggerät befindet sich in der Nähe des Startpunkts. Autom. Rückkehrfunktion leitet autom. Landung ein.", + "en": "Aircraft is close to the Home Point. Initiating Return to Home will now trigger Auto Landing.", + "es": "La aeronave está cerca del punto de origen. Si inicias Regreso al punto de origen ahora, se activará Aterrizaje automático.", + "fr": "Appareil proche du point de départ. Lancer le retour au point de départ active aussi l\\'atterrissage automatique.", + "ja": "機体とホームポイントの距離は近すぎます。RTHを開始すると自動着陸がトリガーされます。", + "ko": "기체가 홈포인트에 너무 가까움. RTH에서 착륙으로 전환됨", + "ru": "Дрон рядом с дом. точкой. Если вы начнете возврат домой, дрон выполнит автопосадку.", + "tr": "Araç, Ev Noktasına yakın. Eve Dönüş başlatıldığında Otomatik İnişi tetikler.", + "zh": "飞行器距离返航点太近,返航切换为自动降落" + }, + "fpv_tip_0x2002060C": { + "de": "Fluggerät befindet sich zu weit vom Startpunkt entfernt. Rückkehrfunktion leitet autom. Landung ein.", + "en": "Aircraft is too far from the Home Point. Initiating Return to Home will now trigger Auto Landing.", + "es": "La aeronave está demasiado lejos del punto de origen. Si inicias Regreso al punto de origen ahora, se activará Aterrizaje automático.", + "fr": "Appareil trop éloigné du point de départ. Lancer le Retour au point de départ active l\\'atterrissage automatique.", + "ja": "機体とホームポイントの距離が遠すぎます。RTHを開始すると自動着陸がトリガーされます。", + "ko": "기체 홈포인트에서 너무 떨어져 있음. RTH에서 자동 착륙으로 전환됨", + "ru": "Дрон слишком далеко от дом. точки. Если вы начнете возврат домой, дрон выполнит автопосадку.", + "tr": "Araç, Ev Noktasından çok uzakta. Eve Dönüş başlatıldığında Otomatik İnişi tetikler.", + "zh": "飞行器距离返航点太远,返航切换为自动降落" + }, + "fpv_tip_0x2002060D": { + "de": "Landet ...", + "en": "Landing", + "es": "Aterrizando", + "fr": "Atterrissage", + "ja": "着陸中", + "ko": "착륙 중...", + "ru": "Посадка", + "tr": "İniş yapıyor", + "zh": "开始自动降落" + }, + "fpv_tip_0x2002060E": { + "de": "Erzwungene Landung durch App anfordern.", + "en": "Force Landing request from APP.", + "es": "La aplicación ha solicitado el aterrizaje forzoso.", + "fr": "Forcer la demande d\\'atterrissage depuis l\\'appli.", + "ja": "アプリが強制着陸を要求。", + "ko": "DJI Pilot 요청으로 강제 착륙", + "ru": "Принудительная посадка через приложение", + "tr": "Uygulama, Zorunlu İniş talebinde bulundu.", + "zh": "App请求强制降落" + }, + "fpv_tip_0x20020610": { + "de": "Hindernis während RTH erkannt. Fluggerät landet ...", + "en": "Obstacle detected. Aircraft is landing", + "es": "Obstáculo detectado. La aeronave está aterrizando", + "fr": "Obstacle détecté. L\\'appareil atterrit", + "ja": "障害物を検出しました。機体は着陸中です。", + "ko": "RTH 장애물 감지됨. 기체 착륙 중...", + "ru": "Обнаружено препятствие. Дрон садится", + "tr": "Engel tespit edildi. Araç iniş yapıyor", + "zh": "返航时遇到障碍,正在降落" + }, + "fpv_tip_0x20020611": { + "de": "Fehler: IMU. Fluggerät kehrt zum Startpunkt zurück.", + "en": "IMU error. Aircraft is returning home.", + "es": "Error de IMU. La aeronave está regresando al punto de origen.", + "fr": "Erreur IMU. L\\'appareil retourne au point de départ.", + "ja": "IMUエラー。機体は帰還中です。", + "ko": "IMU 오류. 기체 RTH 진행", + "ru": "Ошибка IMU. Дрон возвращается домой.", + "tr": "IMU hatası. Araç eve dönüyor.", + "zh": "IMU异常,正在返航" + }, + "fpv_tip_0x20020612": { + "de": "Fluggerät kehrt zum Startpunkt zurück.", + "en": "Aircraft is returning to the Home Point.", + "es": "La aeronave está regresando al punto de origen.", + "fr": "Retour de l\\'appareil au point de départ.", + "ja": "機体はホームポイントに帰還中。", + "ko": "기체 RTH 중.", + "ru": "Дрон возвращается в дом.", + "tr": "Araç, Ev Noktasına dönüyor.", + "zh": "开始智能高度返航" + }, + "fpv_tip_0x2002061F": { + "de": "Inoffizieller Akku erkannt. Fluggerät landet ...", + "en": "Unofficial battery detected. Aircraft is landing.", + "es": "Se ha detectado una batería no oficial. La aeronave está aterrizando.", + "fr": "Batterie non officielle détectée. L\\'appareil atterrit.", + "ja": "純正でないバッテリーを検出。機体は着陸中です。", + "ko": "비순정 DJI 배터리 감지됨. 기체 착륙 중...", + "ru": "Обнаружена нелицензионная батарея. Дрон садится.", + "tr": "Lisanssız pil tespit edildi. Araç iniş yapıyor.", + "zh": "检测到非法电池,正在降落" + }, + "fpv_tip_0x20020700": { + "de": "Flugmodus-Konfiguration: A/P/S. Aktueller Flugmodus: %1$s.", + "en": "Flight mode configuration: A/P/S. Current flight mode: %1$s.", + "es": "Configuración de modo de vuelo: A/P/S. Modo de vuelo actual: %1$s.", + "fr": "Configuration du mode de vol : S/P/A. Mode de vol actuel : %1$s.", + "ja": "フライトモードの設定:S/P/A 現在のフライトモード:%1$s", + "ko": "비행 모드 구성: A/P/S. 현재 비행 모드: %1$s.", + "ru": "Конфигурация режимов полета: A/P/S. Текущий режим полета: %1$s.", + "tr": "Uçuş modu yapılandırması: A/P/S. Mevcut uçuş modu: %1$s.", + "zh": "飞行挡位为A/P/S,且当前飞行挡位为%1$s挡" + }, + "fpv_tip_0x20020700_rc511": { + "ar": "", + "de": "Flugmodus-Konfiguration: A/N/S. Aktueller Flugmodus: %1$s.", + "en": "Flight mode configuration: A/N/S. Current flight mode: %1$s.", + "es": "Configuración de modo de vuelo: A/N/S. Modo de vuelo actual: %1$s.", + "fr": "Configuration du mode de vol : A/N/S. Mode de vol actuel : %1$s.", + "it": "", + "ja": "フライトモードの設定:A/N/S 現在のフライトモード:%1$s", + "ko": "비행 모드 구성: A/N/S. 현재 비행 모드: %1$s.", + "pt": "", + "ru": "Конфигурация режимов полета: A/N/S. Текущий режим полета: %1$s.", + "tr": "Uçuş modu yapılandırması: A/N/S. Mevcut uçuş modu: %1$s.", + "zh": "飞行挡位为A/N/S,且当前飞行挡位为%1$s挡" + }, + "fpv_tip_0x20020800": { + "de": "Fernsteuerung %1$s fordert Fluggerätesteuerung an", + "en": "Remote controller %1$s requesting aircraft flight control", + "es": "El control remoto %1$s ha solicitado el control de vuelo de la aeronave", + "fr": "La radiocommande %1$s demande le contrôle du vol de l\\'appareil", + "ja": "送信機%1$sが機体の飛行制御権を要求中", + "ko": "조종기 %1$s이(가) 기체 비행 제어권 요청 중", + "ru": "Пульт %1$s запрашивает управление полетом дрона", + "tr": "%1$s uzaktan kumandası, aracın uçuş kontrolünü almak istiyor", + "zh": "%1$s控请求获取飞行器的控制权" + }, + "fpv_tip_0x20020900": { + "de": "Mission unterbrochen. Fluggerät manuell steuern", + "en": "Mission interrupted. Fly aircraft manually", + "es": "Misión interrumpida. Vuela la aeronave manualmente", + "fr": "Mission interrompue. Contrôlez L\\'appareil manuellement", + "ja": "ミッション中断。機体を手動で飛行させてください", + "ko": "임무 중단됨. 기체를 수동으로 비행", + "ru": "Задание прервано. Управляйте дроном вручную", + "tr": "Görev kesintiye uğradı. Aracı manuel olarak uçurun", + "zh": "任务已中断,可控制飞行器手动飞行" + }, + "fpv_tip_0x20020A00": { + "ar": "", + "de": "ATTI-Modus", + "en": "ATTI mode", + "es": "Modo ATTI", + "fr": "Mode ATTI", + "it": "", + "ja": "ATTIモード", + "ko": "ATTI 모드", + "pt": "", + "ru": "Режим ATTI", + "tr": "DAVRANIŞ modu", + "zh": "姿态模式" + }, + "fpv_tip_0x20020C00": { + "ar": "", + "de": "", + "en": "FlyTo location synced to current controller", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "目标点已同步", + "zh-Hant": "" + }, + "fpv_tip_0x20020C01": { + "ar": "", + "de": "", + "en": "Severe flight controller error. Control aircraft manually and land promptly", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "飞行系统发生严重异常,请立即手动降落!", + "zh-Hant": "" + }, + "fpv_tip_0x20020D00": { + "de": "Landegestell wird eingefahren. Hindernisvermeidung nicht verfügbar", + "en": "Rising landing gear. Obstacle avoidance unavailable", + "es": "Levantando el tren de aterrizaje. Sistema anticolisión no disponible", + "fr": "Relevée du train d'atterrissage. Évitement d'obstacles non disponible", + "ja": "ランディングギア上昇中障害物回避は使用できません", + "ko": "랜딩 기어를 올리고 있습니다. 장애물 회피를 사용할 수 없습니다", + "ru": "Подъем шасси. Обход препятствий недоступен", + "tr": "İniş takımı kaldırılıyor. Engellerden kaçınma kullanılamıyor", + "zh": "起落架正在上升,避障失效" + }, + "fpv_tip_0x20020D01": { + "de": "Landegestell wird ausgefahren. Hindernisvermeidung nicht verfügbar", + "en": "Lowering landing gear. Obstacle avoidance unavailable", + "es": "Bajando el tren de aterrizaje. Sistema anticolisión no disponible", + "fr": "Abaissement du train d'atterrissage. Obstacle avoidance unavailable", + "ja": "ランディングギア下降中です。障害物回避は使用できません", + "ko": "랜딩 기어를 내리고 있습니다. 장애물 회피를 사용할 수 없습니다", + "ru": "Выпуск шасси. Обход препятствий недоступен", + "tr": "İniş takımı indiriliyor. Engellerden kaçınma kullanılamıyor", + "zh": "起落架正在下降,避障失效" + }, + "fpv_tip_0x20020b00": { + "ar": "", + "de": "", + "en": "Taking off", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "起飞", + "zh-Hant": "" + }, + "fpv_tip_0x20020b01": { + "ar": "", + "de": "", + "en": "Takeoff canceled", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "取消起飞", + "zh-Hant": "" + }, + "fpv_tip_0x20021000": { + "ar": "", + "de": "Start fehlgeschlagen. Steuerknüppel nicht zentriert. Steuerknüppel während des Starts zentriert lassen", + "en": "Control sticks not centered. Unable to take off. Ensure control sticks are centered", + "es": "Palancas de control descentradas. No se puede despegar. Asegúrate de que las palancas de control estén centradas", + "fr": "Échec du décollage. Les joysticks ne sont pas centrés. Assurez-vous de les centrer", + "it": "", + "ja": "操作スティックが中央位置にありません。離陸できません。操作スティックが中央にあるか確認してください", + "ko": "이륙 실패. 조종 스틱이 중앙에 있지 않음. 조종 스틱이 중앙에 있는지 확인 필요", + "pt": "", + "ru": "Сбой взлета. Убедитесь, что джойстики расположены по центру", + "tr": "Kumanda çubukları merkez dışında. Kalkış yapamıyor. Kumanda çubuklarının merkezde olduğundan emin olun", + "zh": "无法起飞:请确认摇杆在中位" + }, + "fpv_tip_0x20022001": { + "de": "QuickSpin gestartet", + "en": "QuickSpin started", + "es": "QuickSpin iniciado", + "fr": "QuickSpin a démarré", + "ja": "クイックスピンが開始されました", + "ko": "QuickSpin 시작됨", + "ru": "QuickSpin запущен", + "tr": "QuickSpin başlatıldı", + "zh": "开始快速自旋" + }, + "fpv_tip_0x20022002": { + "de": "Kein GNSS-Signal. Flugbereich unbekannt. Max. Flughöhe auf %1$s begrenzt", + "en": "No GNSS signal. Flight area unknown. Max flight altitude limited to %1$s", + "es": "No hay señal GNSS. Área de vuelo desconocida. Altitud de vuelo máxima limitada a %1$s", + "fr": "Aucun signal GNSS. Zone de vol inconnue. Altitude de vol max. limitée à %1$s", + "ja": "GNSS信号がありません。飛行エリアが不明です。最大飛行高度が%1$sに制限されています", + "ko": "GNSS 신호가 없습니다. 비행 영역을 알 수 없습니다. 최고 비행 고도가 %1$s(으)로 제한됨", + "ru": "Отсутствует сигнал GNSS. Зона полета неизвестна. Максимальная высота полета ограничена значением %1$s", + "tr": "GNSS sinyali yok. Uçuş alanı bilinmiyor. Maks. uçuş irtifası %1$s ile sınırlıdır", + "zh": "无GNSS信号,飞行区域未知,限高%1$s" + }, + "fpv_tip_0x20022003": { + "de": "Kein GNSS-Signal. Flugbereich unbekannt und Lichtverhältnisse zu schlecht. Max. Flughöhe auf %1$s begrenzt", + "en": "No GNSS signal. Flight area unknown and ambient light too weak. Max flight altitude limited to %1$s", + "es": "No hay señal GNSS. Área de vuelo desconocida y luz ambiental demasiado débil. Altitud de vuelo máxima limitada a %1$s", + "fr": "Aucun signal GNSS. Zone de vol inconnue et lumière ambiante trop faible. Altitude de vol max. limitée à %1$s", + "ja": "GNSS信号がありません。飛行エリアが不明で、周囲光が暗すぎます。最大飛行高度が%1$sに制限されています", + "ko": "GNSS 신호가 없습니다. 비행 영역을 알 수 없으며 주변이 너무 어둡습니다. 최고 비행 고도가 %1$s(으)로 제한됨", + "ru": "Отсутствует сигнал GNSS. Зона полета неизвестна, и недостаточное окружающее освещение. Максимальная высота полета ограничена значением %1$s", + "tr": "GNSS sinyali yok. Uçuş alanı bilinmiyor ve ortam ışığı çok zayıf. Maks. uçuş irtifası %1$s ile sınırlıdır", + "zh": "无GNSS信号,飞行区域未知,环境光过暗,限高%1$s" + }, + "fpv_tip_0x20030000": { + "de": "Bemanntes Fluggerät in der Nähe entdeckt. Mit Vorsicht fliegen", + "en": "Manned aircraft detected nearby. Fly with caution", + "es": "Aeronave tripulada cerca. Vuela con cuidado", + "fr": "Appareil piloté détecté à proximité. Pilotez avec précaution", + "ja": "有人航空機が付近で検出された。慎重に飛行してください", + "ko": "유인 기체가 근처에서 감지됨. 비행 시 주의 필요", + "ru": "Рядом обнаружен пилотируемый летательный аппарат. Соблюдайте осторожность при полете", + "tr": "Yakında insanlı araç tespit edildi. Aracınızı dikkatli uçurun", + "zh": "附近有载人飞行器,请谨慎飞行!" + }, + "fpv_tip_0x20040000": { + "de": "Fluggeschwindigkeit zu hoch. Intervallaufnahme schlägt evtl. fehl.", + "en": "Flight speed too fast. Interval shooting may fail", + "es": "Velocidad de vuelo demasiado rápida. Es posible que el disparo en intervalos no funcione correctamente", + "fr": "Vitesse de vol trop rapide. L\\'intervalle de prise de vue pourrait échouer", + "ja": "飛行速度が速すぎます。インターバル撮影が失敗する可能性があります", + "ko": "비행 속도 너무 빠름. 인터벌 촬영이 실패할 수 있음", + "ru": "Слишком высокая скорость полета. Может возникнуть сбой интервала съемки", + "tr": "Uçuş hızı çok yüksek. Ara çekimler başarısız olabilir", + "zh": "飞行速度过快,可能造成等距拍照失败" + }, + "fpv_tip_0x20040100": { + "de": "Manuelle Belichtung aktiv. Messung deaktiviert.", + "en": "Manual exposure is enabled. Metering is disabled.", + "es": "Exposición manual activada. Medición desactivada.", + "fr": "Exposition manuelle activée. Mesure désactivée.", + "ja": "手動露光が有効になりました。測光が無効になりました。", + "ko": "수동 노출 켜짐. 측광 비활성화됨", + "ru": "Режим ручной экспозиции. Экспозамер отключен.", + "tr": "Manuel ışıklandırma etkinleştirildi. Ölçme devre dışı.", + "zh": "当前曝光模式处于M档,无法测光" + }, + "fpv_tip_0x20040200": { + "de": "Objekt zu nah am Laser-Entfernungsmesser", + "en": "Object too close to laser rangefinder", + "es": "Objeto demasiado cerca del telémetro láser", + "fr": "Objet trop proche pour télémètre laser", + "ja": "被写体がレーザーレンジファインダーに近すぎます", + "ko": "대상이 레이저 거리측정기에 너무 가까움", + "ru": "Объект слишком близко к лазерному дальномеру", + "tr": "Nesne lazer menzil belirleyiciye çok yakın", + "zh": "激光测距过近" + }, + "fpv_tip_0x20040201": { + "de": "Objekt zu weit vom Laser-Entfernungsmesser entfernt", + "en": "Object too far for laser rangefinder", + "es": "Objeto demasiado lejos del telémetro láser", + "fr": "Objet trop loin pour télémètre laser", + "ja": "被写体がレーザーレンジファインダーから遠すぎます", + "ko": "대상이 레이저 거리측정기에서 너무 멀리 있음", + "ru": "Объект слишком далеко от лазерного дальномера", + "tr": "Nesne lazer menzil belirleyiciye çok uzak", + "zh": "激光测距过远" + }, + "fpv_tip_0x20040300": { + "de": "Panorama mit RGB-Kamera und nur einem Tastendruck aufnehmen", + "en": "Capturing one-tap pano with visible light camera", + "es": "Capturando panorámica de un solo toque con la cámara visual", + "fr": "Prise de pano en une touche avec la caméra visible", + "ja": "可視光カメラを使ってワンタッチパノラマを撮影中", + "ko": "가시광 카메라로 원터치 파노라마 촬영 중", + "ru": "Съемка панорамы одним нажатием в видимом свете", + "tr": "Tek dokunuşla görünür ışıklı kamera ile panorama çekimi yapma", + "zh": "当前飞行器正在使用可见光相机进行一键全景拍摄" + }, + "fpv_tip_0x20040400": { + "de": "Zenmuse XT S ist mit anderen IR-Kameras nicht kompatibel", + "en": "Zenmuse XT S not compatible with other infrared cameras", + "es": "Zenmuse XT S no es compatible con otras cámaras infrarrojas", + "fr": "Zenmuse XT S non compatible avec d\\'autres caméras infrarouges", + "ja": "Zenmuse XT Sは他の赤外線カメラには対応していない", + "ko": "젠뮤즈 XT S는 다른 적외선 카메라와 호환 안 됨", + "ru": "Камера Zenmuse XT S не совместима с другими инфракрасными камерами", + "tr": "Zenmuse XT S diğer kızıl ötesi kameralara uygun değildir", + "zh": "Zenmuse XT S不兼容其它红外相机" + }, + "fpv_tip_0x20040500": { + "de": "Kamera %component_index überhitzt. Foto-/Videoaufnahmen schlagen evtl. fehl", + "en": "Camera %component_index overheated. Shooting photos/videos may fail", + "es": "Cámara %component_index sobrecalentada. Es posible que se produzcan errores al capturar fotos//vídeos", + "fr": "Surchauffe de la caméra %component_index. La prise de photo/vidéos peut échouer", + "ja": "カメラ%component_indexが高温。写真/動画撮影ができない可能性あり", + "ko": "카메라 %component_index 과열. 사진/동영상 촬영에 실패할 수 있음", + "ru": "Камера %component_index перегрета. Возможны ошибки при съемке фото и видео", + "tr": "Kamera %component_index aşırı ısındı. Fotoğraf/video çekimi başarısız olabilir", + "zh": "%component_index号云台相机过热,可能会无法拍照/录像" + }, + "fpv_tip_0x20040501": { + "de": "Kamera %component_index überhitzt. Vor Gebrauch bitte auf normale Temperatur abkühlen lassen", + "en": "Camera %component_index overheated. Wait for temperature to return to normal before use", + "es": "Cámara %component_index sobrecalentada. Espera a que la temperatura vuelva a la normalidad antes del uso", + "fr": "Surchauffe caméra %component_index. Attendez que la température de la caméra revienne à la normale avant usage", + "ja": "カメラ%component_indexが高温。常温に戻るまで待ってからご使用ください", + "ko": "카메라 %component_index 과열. 사용 전에 온도가 정상으로 돌아올 때까지 기다리세요", + "ru": "Камера %component_index перегрета. Перед использованием подождите, пока температура не вернется в норму", + "tr": "Kamera %component_index aşırı ısındı. Kullanmadan önce sıcaklığın normale dönmesini bekleyin", + "zh": "%component_index号云台相机过热,请等待降温后再使用" + }, + "fpv_tip_0x20040600": { + "de": "SD-Karten ist langsamen. Kann nicht in 4K aufnehmen.", + "en": "SD card speed is slow, cannot record 4K video.", + "es": "Velocidad lenta de la tarjeta SD. No se puede grabar vídeo 4K.", + "fr": "La vitesse de la carte SD est lente, impossible d\\'enregistrer en 4K.", + "it": "", + "ja": "SD カードの速度が遅いため、4K ビデオを撮影できません。", + "ko": "SD 카드 속도 느림. 4K 촬영할 수 없습니다", + "pt": "", + "ru": "медленная скорость карты памяти. Невозможно записывать в 4K.", + "tr": "SD kart hızı yavaş, 4K videoyu kaydedemiyor.", + "zh": "SDCard速度慢,无法录制4K视频" + }, + "fpv_tip_0x20040700": { + "de": "Bildrate des Live-Streams unter 9 Hz. Vorsichtig fliegen.", + "en": "Live stream video frame rate less than 9Hz. Fly with caution.", + "es": "Ratio de fotogramas de retransmisión en directo de vídeo inferior a 9 Hz. Vuela con cuidado.", + "fr": "Taux de rafraichissement de la diffusion en direct inférieur à 9 Hz. Volez avec précaution.", + "ja": "ライブストリームビデオフレームレートは 9Hz 未満です。注意して飛行してください。", + "ko": "라이브 영상 프레임 속도 9Hz 이하. 비행 시 주의해주세요", + "ru": "Скорость трансляции 9 Гц. Будьте осторожны", + "tr": "Canlı yayın video kare hızı 9 Hz’den az. Dikkatli uçun.", + "zh": "当前画面流畅度过低,请注意飞行安全" + }, + "fpv_tip_0x20040800": { + "de": "Fluggerät kehrt zurück oder landet. Panorama nicht möglich", + "en": "Aircraft RTH or landing. Unable to enter Pano mode", + "es": "Aeronave en RPO o aterrizaje. No se puede acceder al modo Pano", + "fr": "RTH appareil ou atterrissage en cours. Impossible d\\'entrer en mode Pano", + "ja": "機体はRTHまたは着陸中。パノラマモードは利用できません", + "ko": "기체 RTH 또는 착륙. 파노라마 모드 실행 불가", + "ru": "Дрон возвращается домой или садится. Невозможно перейти в режим панорамы", + "tr": "Araç Eve Dönüyor ya da iniş yapıyor. Panorama moduna geçilemiyor", + "zh": "飞行器处于返航或降落状态下,无法进入全景拍照模式" + }, + "fpv_tip_0x20040801": { + "de": "Panorama aufgenommen. In der Wiedergabe ansehen", + "en": "Panorama taken successfully. View in Playback", + "es": "Panorámica capturada correctamente. Ver en Reproducción", + "fr": "Panorama pris avec succès. Visualiser dans le menu de lecture", + "ja": "パノラマ撮影完了。再生で確認してください", + "ko": "파노라마 촬영 성공. \\'재생\\'에서 확인 가능", + "ru": "Съемка панорамы завершена. Посмотрите ее в меню воспроизведения", + "tr": "Panorama görüntüsü başarıyla alındı. Oynatma bölümünde görüntüleyin", + "zh": "全景拍摄成功,可在回放中查看" + }, + "fpv_tip_0x20040802": { + "de": "Panorama fehlgeschlagen", + "en": "Taking panorama failed", + "es": "Error al capturar la panorámica", + "fr": "La prise du panorama a échoué", + "ja": "パノラマ撮影できません", + "ko": "파노라마 촬영 실패", + "ru": "Не удалось снять панораму", + "tr": "Panorama görüntüsü alma başarısız", + "zh": "全景拍摄失败" + }, + "fpv_tip_0x20040803": { + "de": "Panorama beendet", + "en": "Panorama stopped", + "es": "Panorámica detenida", + "fr": "Panorama interrompu", + "ja": "パノラマが停止", + "ko": "파노라마 촬영 중지됨", + "ru": "Съемка панорамы остановлена", + "tr": "Panorama çekimi durduruldu", + "zh": "全景拍摄终止" + }, + "fpv_tip_0x20040804": { + "de": "Fluggerät nicht gestartet. Panorama nicht möglich", + "en": "Aircraft not in flight. Unable to take panorama", + "es": "La aeronave no ha despegado. No se puede capturar la panorámica", + "fr": "L\\'appareil n\\'a pas décollé. Impossible de prendre le panorama", + "ja": "機体は飛行していません。パノラマ撮影できません", + "ko": "기체 비행 전. 파노라마 촬영 불가", + "ru": "Дрон не в воздухе. Невозможно снять панораму", + "tr": "Araç kalkış yapmadı. Panorama görüntüsü alınamıyor", + "zh": "飞机未起飞,无法开始全景拍摄" + }, + "fpv_tip_0x20040805": { + "de": "Übernahme der Steuerung fehlgeschlagen. Panorama beendet", + "en": "Getting control failed. Panorama stopped", + "es": "Error al obtener el control. Panorámica detenida", + "fr": "Impossible de prendre le contrôle. Panorama interrompu", + "ja": "制御権を取得できません。パノラマ撮影停止", + "ko": "제어권 가져오기 실패. 파노라마 촬영 중지됨", + "ru": "Ошибка управления. Съемка панорамы остановлена", + "tr": "Kontrolü ele geçirme başarısız. Panorama çekimi durduruldu", + "zh": "控制权获取失败,全景拍摄终止" + }, + "fpv_tip_0x20040806": { + "de": "Unbekannter Kamerafehler. Panorama nicht möglich", + "en": "Unknown camera error. Unable to start panorama", + "es": "Error desconocido de la cámara. No se puede iniciar la panorámica", + "fr": "Erreur caméra inconnue. Impossible de lancer le panorama", + "ja": "原因不明のカメラエラー。パノラマ撮影を開始できません", + "ko": "알 수 없는 카메라 오류. 파노라마 시작 불가", + "ru": "Неизвестная ошибка камеры. Невозможно начать съемку панорамы", + "tr": "Bilinmeyen kamera hatası. Panorama çekimi başlatılamıyor", + "zh": "未知相机错误,无法开始全景拍摄" + }, + "fpv_tip_0x20040807": { + "de": "Zeitüberschreitung der Kamera. Panorama beendet", + "en": "Camera response timed out. Panorama stopped", + "es": "Se agotó el tiempo de espera de la cámara. Panorámica detenida", + "fr": "Délai de réponse de la caméra expiré. Panorama interrompu", + "ja": "カメラ応答 時間切れ。パノラマが停止", + "ko": "카메라 반응 시간 초과. 파노라마 촬영 중지됨", + "ru": "Время запроса истекло. Съемка панорамы остановлена", + "tr": "Kamera yanıt süresi doldu. Panorama çekimi durduruldu", + "zh": "相机超时,全景拍摄终止" + }, + "fpv_tip_0x20040808": { + "de": "Nicht genug Speicherplatz. Panorama beendet", + "en": "Insufficient storage. Panorama stopped", + "es": "Almacenamiento insuficiente. Panorámica detenida", + "fr": "Stockage insuffisant. Panorama interrompu", + "ja": "空き容量不足。パノラマが停止", + "ko": "저장 공간 부족. 파노라마 촬영 중지됨", + "ru": "Недостаточно места. Съемка панорамы остановлена", + "tr": "Yetersiz depolama alanı. Panorama çekimi durduruldu", + "zh": "存储空间不足,全景拍摄终止" + }, + "fpv_tip_0x20040809": { + "de": "Fluggerät bewegt sich. Panorama nicht möglich", + "en": "Aircraft moving. Unable to take panorama", + "es": "Aeronave en movimiento. No se puede capturar la panorámica", + "fr": "Appareil en mouvement. Impossible de lancer le panorama", + "ja": "機体が動作中。パノラマ撮影できません", + "ko": "기체 흔들림. 파노라마 촬영 불가", + "ru": "Дрон в движении. Невозможно начать съемку", + "tr": "Araç hareket ediyor. Panorama görüntüsü alınamıyor", + "zh": "飞行器运动中,无法开始全景拍摄" + }, + "fpv_tip_0x2004080A": { + "de": "Gimbal bewegt sich. Panorama nicht möglich", + "en": "Gimbal moving. Unable to take panorama", + "es": "Estabilizador en movimiento. No se puede capturar la panorámica", + "fr": "Nacelle en mouvement. Impossible de lancer le panorama", + "ja": "ジンバルが動作中。パノラマ撮影できません", + "ko": "짐벌 흔들림. 파노라마 촬영 불가", + "ru": "Камера в движении. Невозможно начать съемку", + "tr": "Gimbal hareket ediyor. Panorama görüntüsü alınamıyor", + "zh": "云台运动中,无法开始全景拍摄" + }, + "fpv_tip_0x2004080B": { + "de": "Steuerknüppel bewegt. Panorama beendet", + "en": "Control stick moved. Panorama stopped", + "es": "Se ha movido la palanca de control. Panorámica detenida", + "fr": "Joystick bougé. Panorama interrompu", + "ja": "操作スティックが動作。パノラマが停止", + "ko": "조종 스틱 움직임. 파노라마 촬영 중지됨", + "ru": "Совершено движение джойстиком. Съемка панорамы остановлена", + "tr": "Kumanda çubuğu hareket etti. Panorama çekimi durduruldu", + "zh": "用户操作摇杆,全景拍摄终止" + }, + "fpv_tip_0x2004080C": { + "de": "Max. Höhenlimit erreicht. Panorama unterbrochen", + "en": "Max altitude limit reached. Panorama stopped", + "es": "Se ha alcanzado el límite de altitud máx. Panorámica detenida", + "fr": "Limite d\\'altitude max. atteinte. Panorama interrompu", + "ja": "最大高度に達した。パノラマが停止しました", + "ko": "최고 고도 제한에 도달함. 파노라마 중단됨.", + "ru": "Достигнута предельная высота полета. Панорамная съемка остановлена", + "tr": "Maksimum irtifa sınırına ulaşıldı. Panorama çekimi durduruldu", + "zh": "触碰到限飞高度,全景拍摄终止" + }, + "fpv_tip_0x2004080D": { + "de": "Max. Distanz erreicht. Panorama beendet", + "en": "Max distance reached. Panorama stopped", + "es": "Se ha alcanzado la distancia máxima. Panorámica detenida", + "fr": "Distance max. atteinte. Panorama interrompu", + "ja": "最大距離に到達。パノラマが停止", + "ko": "최대 거리 도달. 파노라마 촬영 중지됨", + "ru": "Достигнуто макс. расстояние. Съемка панорамы остановлена", + "tr": "Maksimum mesafeye ulaşıldı. Panorama çekimi durduruldu", + "zh": "触发距离限制,全景拍摄终止" + }, + "fpv_tip_0x2004080E": { + "de": "Gimbal blockiert. Panorama beendet", + "en": "Gimbal stuck. Panorama stopped", + "es": "El estabilizador está atascado. Panorámica detenida", + "fr": "Nacelle bloquée. Panorama interrompu", + "ja": "ジンバルが動作しません。パノラマが停止", + "ko": "짐벌 막힘. 파노라마 촬영 중지됨", + "ru": "Камера заблокирована. Съемка панорамы остановлена", + "tr": "Gimbal sıkıştı. Panorama çekimi durduruldu", + "zh": "云台受阻,全景拍摄终止" + }, + "fpv_tip_0x2004080F": { + "de": "Fotoaufnahme fehlgeschlagen. Panorama beendet", + "en": "Taking photo failed. Panorama stopped", + "es": "Error al capturar la foto. Panorámica detenida", + "fr": "Échec de la prise de vue. Panorama interrompu", + "ja": "写真撮影できません。パノラマが停止", + "ko": "사진 촬영 실패. 파노라마 촬영 중지됨", + "ru": "Не удалось сфотографировать. Съемка панорамы остановлена", + "tr": "Fotoğraf çekimi başarısız. Panorama çekimi durduruldu", + "zh": "拍照失败,全景拍摄终止" + }, + "fpv_tip_0x20040810": { + "de": "Zusammenfügen des Panoramas fehlgeschlagen", + "en": "Stitching panorama failed", + "es": "Error al crear la panorámica", + "fr": "Assemblage du panorama échoué", + "ja": "パノラマを合成できません", + "ko": "파노라마 합성 실패", + "ru": "Не удалось объединить снимки панорамы", + "tr": "Panorama görüntülerini birleştirme başarısız", + "zh": "全景图片拼接失败" + }, + "fpv_tip_0x20040811": { + "de": "Laden der Kalibrierungsparameter fehlgeschlagen. Panorama beendet", + "en": "Loading calibration parameters failed. Panorama stopped", + "es": "Error al cargar los parámetros de calibración. Panorámica detenida", + "fr": "Chargement des paramètres d\\'étalonnage échoué. Panorama interrompu", + "ja": "キャリブレーション パラメーター読み込み失敗。パノラマが停止", + "ko": "캘리브레이션 매개변수 로딩 실패. 파노라마 촬영 중지됨", + "ru": "Сбой загрузки параметров калибровки. Съемка панорамы остановлена", + "tr": "Kalibrasyon parametre yüklemesi başarısız. Panorama çekimi durduruldu", + "zh": "加载标定参数失败,全景拍摄终止" + }, + "fpv_tip_0x20040812": { + "de": "Anpassung der Kameraparameter fehlgeschlagen. Panorama beendet", + "en": "Adjusting camera parameters failed. Panorama stopped", + "es": "Error al ajustar los parámetros de la cámara. Panorámica detenida", + "fr": "Réglage des paramètres de la caméra échoué. Panorama interrompu", + "ja": "カメラパラメーターの調整失敗。パノラマが停止", + "ko": "카메라 매개변수 조정 실패. 파노라마 촬영 중지됨", + "ru": "Сбой настройки параметров камеры. Съемка панорамы остановлена", + "tr": "Kamera parametreleri ayarlama başarısız. Panorama çekimi durduruldu", + "zh": "调整相机参数失败,全景拍摄终止" + }, + "fpv_tip_0x20040813": { + "de": "Erstelle Panorama...", + "en": "Stitching panorama...", + "es": "Creando panorámica...", + "fr": "Création du panorama", + "ja": "パノラマ作成中", + "ko": "파노라마 생성 중...", + "ru": "Идет создание панорамы", + "tr": "Panorama oluşturuluyor...", + "zh": "全景图正在拼接合成,请耐心等待" + }, + "fpv_tip_0x20040900": { + "de": "Wiedergabe auf primärer Fernsteuerung. Liveansicht wurde von der sekundären Fernsteuerung getrennt.", + "en": "Playback for Primary remote controller in progress. Disconnected from Liveview for Secondary remote controller", + "es": "Reproducción para el control remoto principal en curso. Se ha desconectado la vista en directo para el control remoto secundario", + "fr": "Lecture en cours sur la radiocommande principale. RC secondaire déconnectée de l\\'aperçu en direct", + "ja": "メインの送信機で再生中です。2台目の送信機用のライブビューから接続が切断されました。", + "ko": "마스터 조종기 재생 진행 중. 부마스터 조종기의 라이브 뷰에서 연결 끊김", + "ru": "Идет воспроизведение с главного пульта. Трансляция с второстепенного пульта отключена", + "tr": "Birincil uzaktan kumanda için tekrar oynatma devam ediyor. İkincil uzaktan kumanda için Canlı Görüntü bağlantısı kesildi", + "zh": "主控已进入回放,辅控将断开图传" + }, + "fpv_tip_0x20040A00": { + "de": "Kamera in Verwendung. Wiedergabe nicht möglich.", + "en": "Camera busy, cannot enter playback.", + "es": "Cámara ocupada. No se puede acceder a la reproducción.", + "fr": "Caméra en cours d\\'utilisation. Impossible d\\'ouvrir le menu de lecture.", + "ja": "カメラがビジーです。再生できません。", + "ko": "카메라 사용 중. 재생 실행 불가", + "ru": "Камера занята. Невозможно открыть меню воспроизведения", + "tr": "Kamera meşgul, tekrar oynatmaya girilemiyor.", + "zh": "相机正忙,无法进入回放" + }, + "fpv_tip_0x20040A01": { + "de": "Keine Speicherkarte", + "en": "No memory card", + "es": "No hay tarjeta de memoria", + "fr": "Aucune carte mémoire", + "it": "", + "ja": "メモリーカードがありません", + "ko": "메모리 카드 없음", + "pt": "", + "ru": "Нет карты памяти", + "tr": "Hafıza kartı yok", + "zh": "无存储卡" + }, + "fpv_tip_0x20040B00": { + "de": "Installation von LiDAR an Gimbal I für optimale Nutzung", + "en": "Install LiDAR on Gimbal I for optimal use", + "es": "Instalar LiDAR en el estabilizador I para un uso óptimo", + "fr": "Installer LiDAR sur la nacelle I pour une utilisation optimale", + "ja": "最適な使用のためにはジンバルIにLiDARを取り付けてください", + "ko": "최적의 사용을 위해 짐벌 I에 LiDAR 설치", + "ru": "Установите LiDAR на Gimbal I для оптимального использования", + "tr": "En iyi kullanım için Gimbal'a LiDAR takın", + "zh": "为保证激光雷达负载使用效果,建议在I号云台安装" + }, + "fpv_tip_0x20040C00": { + "de": "Verwendung von Steuerung B. LiDAR kann nicht unterstützt werden. Zu Steuerung A wechseln", + "en": "Using Controller B. Unable to support LiDAR. Switch to Controller A", + "es": "Utilizando el controlador B. No se puede admitir LiDAR. Cambio al control A", + "fr": "Utilisation du contrôleur B. Prise en charge de LiDAR impossible. Passer à la radiocommande A", + "ja": "送信機Bを使用中です。LiDARに対応していません。送信機Aに切り替えてください", + "ko": "조종기 B 사용. LiDAR을 지원할 수 없습니다. 조종기 A로 전환하세요.", + "ru": "Использование контроллера B. Поддержка LiDAR не осуществляется. Переключиться на контроллер А", + "tr": "Kumada B. Kullanılıyor. LiDAR desteklenmiyor. Kumanda A'ya geçin", + "zh": "当前控为B控,不支持激光雷达负载,请切换为A控" + }, + "fpv_tip_0x20040D00": { + "de": "Kalibrierung fehlgeschlagen. Bitte prüfen und erneut versuchen", + "en": "Calibration failed. Check and try again", + "es": "Error de calibración. Vuelve a intentarlo", + "fr": "Échec de l\\'étalonnage. Vérifiez et réessayez", + "ja": "キャリブレーション失敗。確認して再試行してください", + "ko": "캘리브레이션 실패. 확인 후 재시도 필요", + "ru": "Сбой калибровки. Проверьте и повторите попытку", + "tr": "Kalibrasyon başarısız. Tekrar deneyin", + "zh": "标定失败,请尝试重新标定。" + }, + "fpv_tip_0x20040D01": { + "de": "Kalibrierung fehlgeschlagen. Wenden dich bitte an DJI Support", + "en": "Calibration failed. Contact DJI Support", + "es": "Error de calibración. Contacta con Asistencia DJI", + "fr": "Étalonnage échoué. Veuillez contacter le service client DJI", + "ja": "キャリブレーション失敗。DJIサポートにご連絡ください", + "ko": "캘리브레이션 실패. DJI 고객지원으로 문의해주세요", + "ru": "Сбой калибровка. Обратитесь в службу поддержки DJI", + "tr": "Kalibrasyon başarısız. DJI Destek ile iletişime geçin", + "zh": "标定失败,请联系大疆售后服务。" + }, + "fpv_tip_0x20040E00": { + "de": "%1$s Kameraobjektiv ist nicht kalibriert. Die Fokussierung ist beeinträchtigt. Bitte unter den Einstellungen Objektivkalibrierung aufrufen.", + "en": "%1$s camera lens not calibrated. Focusing will be affected. Go to Settings > Calibrate Lens to calibrate.", + "es": "El objetivo de la cámara %1$s no está calibrado. El enfoque se verá afectado. Accede a Configuración > Calibrar objetivo para realizar la calibración.", + "fr": "Objectif de la caméra %1$s non étalonné. La mise au point sera affectée. Rendez-vous dans paramètres > Étalonner l\\'objectif pour étalonner.", + "ja": "%1$s カメラレンズがキャリブレーションされていません。フォーカスが影響されます。 設定 >レンズ キャリブレーションを開き、実行してください。", + "ko": "%1$s 카메라 렌즈 캘리브레이션 안 됨. 초점에 영향을 줌. \\'설정\\' > \\'렌즈 캘리브레이션\\' 이동 후 캘리브레이션하세요", + "ru": "Объектив камеры %s не откалиброван. Это повлияет на фокусировку. Откройте \"Настройки > Калибровка объектива\", чтобы откалибровать.", + "tr": "%s kamera lensi kalibre edilmedi. Odaklanmayı etkileyecektir. Kalibre etmek için Ayarlar > Lensi Kalibre Et menüsüne gidin.", + "zh": "%s相机镜头未标定,会影响对焦效果,您可以通过相机设置中的『标定镜头』功能进行标定。" + }, + "fpv_tip_0x20040F00": { + "de": "Punktwolkedaten werden gesammelt. Echtzeit-Datenübertragung instabil", + "en": "Collecting point cloud data. Real-time data transfer unstable", + "es": "Recopilando información de nube de puntos. Transferencia de datos en tiempo real inestable", + "fr": "Collecte des données des nuages de points. Transfert de données en temps réel instable", + "ja": "点群データを収集中。リアルタイムデータ転送が不安定", + "ko": "포인트 클라우드 데이터 수집. 실시간 데이터 전송 불안정", + "ru": "Сбор данных облака точек. Передача данных в реальном времени нестабильна", + "tr": "Nokta bulutu verilerinin toplanması. Gerçek zamanlı veri aktarımı güvenilir değil", + "zh": "实时点云传输不稳定,点云数据正常采集中" + }, + "fpv_tip_0x20041000": { + "de": "Nutzlast-IMU wird erwärmt", + "en": "Payload IMU warmed up", + "es": "IMU del instrumento calentada", + "fr": "Réchauffage de l'IMU de la charge utile", + "ja": "ペイロードIMUウォームアップ済み", + "ko": "페이로드 IMU 예열 완료", + "ru": "Полезная нагрузка IMU прогрелась", + "tr": "Yük IMU'su ısındı", + "zh": "负载惯导预热已完成" + }, + "fpv_tip_0x20041100": { + "de": "Punktwolken-Modellaufzeichnung läuft. Video kann nicht aufgenommen werden", + "en": "Point cloud model recording in progress. Unable to record video", + "es": "Grabación del modelo de nube de puntos en curso. No se puede grabar vídeo", + "fr": "Enregistrement du modèle de nuage de point en cours. Enregistrement vidéo impossible", + "ja": "点群モデル録画進行中。動画撮影できません", + "ko": "포인트 클라우드 모델 기록 중. 동영상 촬영 불가", + "ru": "Идет запись модели облака точек. Невозможно записать видео", + "tr": "Nokta bulutu modeli kaydı sürüyor. Video kaydedilemiyor", + "zh": "点云模型录制中,无法开始录像" + }, + "fpv_tip_0x20041200": { + "de": "Kalibrierungsflug abgeschlossen. Fluggerät wieder voll einsatzbereit", + "en": "Calibration Flight complete. Proceed ahead", + "es": "Vuelo de calibración completo. Continúa con normalidad", + "fr": "Vol d\\'étalonnage terminé. Continuez normalement", + "ja": "キャリブレーション飛行完了。操作を継続してください", + "ko": "캘리브레이션 비행 완료. 정상으로 진행", + "ru": "Калибровочный полет завершен. Продолжите использование", + "tr": "Kalibrasyon Uçuşu tamamlandı. İleriye doğru devam et", + "zh": "已完成标定飞行,请继续操作" + }, + "fpv_tip_0x20041300": { + "de": "Der Kalibrierungsflug wurde manuell gestoppt. Überprüfen und erneut versuchen.", + "en": "Calibration Flight stopped manually. Check and try again", + "es": "El vuelo de calibración se ha detenido manualmente. Compruébalo y vuelve a intentarlo", + "fr": "Le vol d’étalonnage a été arrêté manuellement. Vérifiez et refaites une tentative", + "ja": "キャリブレーション飛行が手動で停止されました。確認して再試行してください", + "ko": "캘리브레이션 비행 수동 중지. 확인 후 다시 시도해주세요", + "ru": "Калибровочный полет остановлен вручную. Проверьте и повторите попытку", + "tr": "", + "zh": "标定飞行已被手动打断,请重新操作" + }, + "fpv_tip_0x20041400": { + "de": "Kommunikationsfehler zwischen Fluggerät und Nutzlast", + "en": "Communication error between aircraft and payload", + "es": "Error de comunicación entre la aeronave y el instrumento", + "fr": "Erreur de communication entre l'appareil et la nacelle", + "ja": "機体とペイロード間の通信エラー", + "ko": "기체-페이로드 통신 오류", + "ru": "Ошибка подключения дрона к полезной нагрузке", + "tr": "Araç ve yük arasında iletişim hatası", + "zh": "负载与飞行器连接通信异常" + }, + "fpv_tip_0x20041500": { + "de": "IR-Zoom max", + "en": "IR Zoom Max", + "es": "Zoom IR máx.", + "fr": "Zoom infrarouge maximum", + "ja": "IRズームが最大です", + "ko": "IR 줌 최대", + "ru": "ИК-зум макс.", + "tr": "IR Yakınlaştırma Maks.", + "zh": "红外变焦已达最大倍数" + }, + "fpv_tip_0x20041600": { + "de": "Wechsel erfolgt. Größerer Temperaturmessbereich verfügbar", + "en": "Switched successfully. A wider temperature measurement range available", + "es": "Cambio correcto. Un rango de medición de temperatura más amplio disponible", + "fr": "Basculement réussi. Plage de mesure de température plus large disponible", + "ja": "正常に切り替えました。温度測定範囲が広がりました", + "ko": "전환 성공. 보다 넓은 온도 측정 범위 사용 가능", + "ru": "Переключение успешно выполнено. Доступен более широкий диапазон измерения температуры", + "tr": "Başarıyla geçiş yapıldı. Daha geniş sıcaklık ölçüm aralığı mevcut", + "zh": "切换成功,该模式提供更大的测温区间" + }, + "fpv_tip_0x20041601": { + "de": "Wechsel erfolgt. Genauere Temperaturmessung verfügbar", + "en": "Switched successfully. A more precise temperature measurement available", + "es": "Cambio correcto. Una medición de temperatura más precisa disponible", + "fr": "Basculement réussi. Mesure de température plus précise disponible", + "ja": "正常に切り替えました。温度測定の精度が上がりました", + "ko": "전환 성공. 보다 정확한 온도 측정 가능", + "ru": "Переключение успешно выполнено. Доступно более точное измерение температуры", + "tr": "Başarıyla geçiş yapıldı. Daha hassas sıcaklık ölçümü mevcut", + "zh": "切换成功,该模式提供更精准的测温能力" + }, + "fpv_tip_0x20041602": { + "de": "Wechsel erfolgt. Im hochauflösenden Modus werden Infrarotbilder klarer dargestellt. Temperaturmessung wird nicht unterstützt", + "en": "Switched successfully. High-Res mode provides clearer infrared image. Temperature measurement not supported", + "es": "Cambio correcto. El modo Alta resolución proporciona imágenes infrarrojas más nítidas. Medición de temperatura no compatible", + "fr": "Basculement réussi. Le mode Haute résolution fournit une image infrarouge plus claire. Mesure de température non prise en charge", + "it": "", + "ja": "正常に切り替わりました。高解像度モードでは、より鮮明な赤外線画像が得られます。温度測定はサポートされていません", + "ko": "전환 성공. 고해상도 모드는 보다 선명한 적외선 이미지를 제공합니다. 온도 측정이 지원 안 됨", + "ru": "Переключение успешно выполнено. Режим высокого разрешения обеспечивает более четкое инфракрасное изображение. Измерение температуры не поддерживается", + "tr": "Başarıyla geçiş yapıldı. Yüksek Çözünürlük modu daha net kızılötesi görüntü sağlar. Sıcaklık ölçümü desteklenmiyor", + "zh": "切换成功,红外超清模式提供更清晰的红外画面,不支持测温" + }, + "fpv_tip_0x20041700": { + "de": "Lichtsensor blockiert. Erfassung von Multispektraldaten beeinträchtigt", + "en": "Light sensor blocked. Multispectral data collection affected", + "es": "Sensor de luz bloqueado. Recopilación de datos multiespectrales afectada", + "fr": "Capteur de lumière bloqué. Collecte de données multisprectrales affectée", + "ja": "光センサーがブロックされています。マルチスペクトルデータ収集に影響します", + "ko": "광 센서가 차단되었습니다. 다중 스펙트럼 데이터 수집이 영향을 받습니다", + "ru": "Датчик света заблокирован. Нарушен сбор мультиспектральных данных", + "tr": "Işık sensörü engellendi. Multispektral veri toplama işlemi etkilendi", + "zh": "光照传感器被遮挡,影响多光谱数据采集" + }, + "fpv_tip_0x20041801": { + "en": "Incompatible camera parameters. Restart app and go to home screen to update", + "zh": "摄像头参数不匹配,请重启APP进入首页更新参数" + }, + "fpv_tip_0x20050100": { + "de": "GEO-Zone in der Nähe hat temporärer Flugbeschränkungen, die in 1 Stunde wirksam werden", + "en": "Nearby GEO Zone has temporary restrictions preparing to take effect in 1 hour", + "es": "La zona GEO cercana tiene restricciones temporales preparadas para entrar en vigor en 1 hora", + "fr": "La Zone GEO à proximité a des restrictions temporaires prenant effet dans une heure", + "ja": "付近のGEO区域には、1時間後に適用される一時的な制限が設けられています", + "ko": "인근 GEO 구역 임시 제한 적용, 1시간 후 발효에 준비 필요", + "ru": "В зоне GEO поблизости через 1 час вступят в силу ограничения на полеты", + "tr": "Yakındaki GEO Bölgesinde 1 saat içinde geçerli olacak kısıtlama hazırlıkları yapılıyor", + "zh": "附近有1小时后生效的临时限飞区" + }, + "fpv_tip_0x20050200": { + "de": "GEO-Zone in der Nähe hat bald temporärer Flugbeschränkungen (%1$d)", + "en": "Nearby GEO Zone has temporary restrictions preparing to take effect (%1$d)", + "es": "La zona GEO cercana tiene restricciones temporales preparadas para entrar en vigor (%1$d)", + "fr": "La Zone GEO à proximité a des restrictions temporaires prenant bientôt effet (%1$d)", + "ja": "付近のGEO区域に一時的な制限が適用される予定です (%1$d)", + "ko": "인근 GEO 구역 임시 제한 발효 준비 중 (%1$d)", + "ru": "В зонах GEO поблизости скоро вступят в силу ограничения на полеты (%1$d)", + "tr": "Yakındaki GEO Bölgesinde geçici kısıtlama hazırlıkları yapılıyor (%1$d)", + "zh": "附近有即将生效的临时限飞区(%1$d)" + }, + "fpv_tip_0x20050300": { + "de": "Fluggerät sinkt in %1$s automatisch ab.", + "en": "Aircraft will automatically descend in %1$s", + "es": "La aeronave descenderá automáticamente en %1$s", + "fr": "L\\'appareil va descendre automatiquement dans %1$s", + "ja": "機体は自動的に %1$s 秒後に下降します", + "ko": "%1$s 초 후에 기체 자동으로 하강", + "ru": "Дрон автоматически снизится через %1$s сек.", + "tr": "Araç otomatik olarak %1$s içinde alçalacak", + "zh": "飞行器将在%1$s秒后自动下降" + }, + "fpv_tip_0x20050400": { + "de": "Fluggerät verlässt die freigeschaltete GEO-Zone. Vorsichtig fliegen", + "en": "Aircraft leaving unlocked GEO zone. Fly with caution", + "es": "Aeronave abandonando zona GEO desbloqueada. Vuela con precaución", + "fr": "L\\'appareil sort de la zone GEO déverrouillée. Volez avec précaution", + "ja": "機体はロック解除されたGEO区域の外に出ます。慎重に飛行してください", + "ko": "기체 잠금 해제된 GEO 구역 벗어나는 중. 비행 시 주의 필요", + "ru": "Дрон покидает разблокированную зону GEO. Будьте осторожны в полете", + "tr": "Araç kilidi açılan GEO bölgesini terk ediyor. Aracınızı dikkatli uçurun", + "zh": "飞行器已触碰到解禁证书的区域边界,请注意飞行安全。" + }, + "fpv_tip_0x20050401": { + "de": "Fluggerät an der Grenze einer GEO-Zone. Rückkehrfunktion (RTH) wird möglicherweise gestoppt. Sofort wegfliegen", + "en": "Aircraft at the boundary of a GEO Zone. RTH may be stopped. Fly away promptly", + "es": "La aeronave está en el límite de una zona GEO. RPO puede detenerse. Vuela lejos rápidamente", + "fr": "Appareil à la limite d'une zone GEO. Le RTH peut être arrêté. Partez rapidement", + "it": "", + "ja": "機体はGEO区域の境界にあります。RTHが停止する可能性があります。速やかに離れてください", + "ko": "기체가 GEO 구역의 경계에 있습니다. RTH가 중지될 수 있습니다. 즉시 벗어나세요", + "pt": "", + "ru": "Дрон находится на границе зоны GEO. Возврат домой может быть прерван. Покиньте зону как можно скорее", + "tr": "Hava aracı GEO Bölgesi'nin sınırında. RTH durdurulabilir. Hemen bölgenin dışına doğru uçun", + "zh": "飞行器已触碰到限飞区,返航可能中止。请尽快操控飞行器远离。" + }, + "fpv_tip_0x20050402": { + "de": "Fluggerät befindet sich an der Grenze zu einer Höhenlagezone. (%1$s). Von Grenze wegbewegen oder Sinkflug einleiten", + "en": "Aircraft at boundary of an Altitude Zone (%1$s ). Fly away or descend as soon as possible", + "es": "Aeronave en el límite de una zona de altitud (%1$s). Aléjate o desciende lo antes posible", + "fr": "L\\'appareil est à la limite d\\'une zone d\\'altitude (%1$s). Éloignez-vous ou descendez rapidement", + "ja": "機体は高度制限区域(%1$s)の境界線付近を飛行中。ただちに離れるか、下降してください", + "ko": "기체 고도 제한 구역(%1$s) 경계에 있음. 재빨리 멀리 이동 또는 하강 필요", + "ru": "Дрон находится на границе зоны ограничения высоты (%1$s). Покиньте зону или приземлитесь как можно скорее", + "tr": "Araç İrtifa Bölgesi sınırlarında (%1$s). En kısa sürede bölgenin dışına doğru uçun veya irtifayı düşürün", + "zh": "飞行器已触碰到限高区(限高 %1$s),当前飞行高度高于限飞高度,请操控飞行器远离或下降" + }, + "fpv_tip_0x20050403": { + "de": "Fluggerät befindet sich in einer Höhenlagezone (%1$s). Vorsichtig fliegen", + "en": "Aircraft entered Altitude Zone (%1$s). Fly with caution", + "es": "La aeronave entró en una zona de altitud (%1$s). Vuela con precaución", + "fr": "L\\'appareil est dans une zone d’altitude (%1$s). Volez avec précaution", + "ja": "機体が高度制限区域に到達(%1$s)。慎重に飛行してください", + "ko": "기체 고도 제한 구역(%1$s) 진입. 비행 시 주의 필요", + "ru": "Дрон в зоне ограничения высоты (%1$s). Будьте осторожны", + "tr": "Araç İrtifa Bölgesine girdi (%1$s). Aracınızı dikkatli uçurun", + "zh": "飞行器进入限高区(限高 %1$s),请注意飞行安全" + }, + "fpv_tip_0x20050404": { + "de": "Fluggerät an der Grenze eines Flugbeschränkungsgebiets. Sofort von Grenze wegbewegen", + "en": "Aircraft at the boundary of a Restricted Zone. Fly away promptly", + "es": "Aeronave en el límite de una zona restringida. Aléjate lo antes posible", + "fr": "L’appareil est à la limite d’une zone restreinte. Éloignez-vous rapidement", + "ja": "機体が制限区域の境界付近を飛行。すぐに離れてください", + "ko": "기체 제한 구역 경계에 있음. 즉시 멀리 이동 필요", + "ru": "Дрон находится на границе зоны c ограничениями. Отдалитесь от границы зоны как можно скорее", + "tr": "Araç Kısıtlı Bölge sınırlarında. Hemen bölgenin dışına doğru uçun", + "zh": "飞行器已触碰到禁飞区,请尽快操控飞行器远离" + }, + "fpv_tip_0x20050405": { + "de": "Fluggerät befindet sich in einer Warnzone (%1$s). Bitte vorsichtig fliegen.", + "en": "GEO: You are in a Warning Zone (%1$s). Fly with caution.", + "es": "GEO: Estás en una zona de advertencia (%1$s). Vuela con cuidado.", + "fr": "GEO : Vous êtes dans une zone de prudence (%1$s). Volez avec précaution.", + "ja": "GEO:(%1$s) 警告区域にいます。注意して飛行してください。", + "ko": "현재 경고 구역(%1$s)에 있음. 비행 시 주의해주세요", + "ru": "GEO: дрон в зоне предупреждения (%1$s). Будьте осторожны.", + "tr": "GEO: Bir Uyarı Bölgesindesiniz (%1$s). Dikkatli uçun.", + "zh": "飞行器处于警告区(%1$s)内,请注意飞行安全。" + }, + "fpv_tip_0x20050406": { + "ar": "", + "de": "Das Fluggerät fliegt in einer Höhenlage-Zone (%1$s). Bitte vorsichtig Fliegen.", + "en": "Your aircraft is flying in an Altitude Zone (%1$s). Please fly with caution.", + "es": "La aeronave está volando en una zona de altitud (%1$s). Vuela con cuidado.", + "fr": "Votre appareil vole dans une zone à altitude limitée (%1$s). Volez avec précaution.", + "it": "", + "ja": "機体が高度制限区域 (%1$s)を飛行。慎重に飛行してください。", + "ko": "고도 제한 구역(%1$s)에서 비행 중. 비행 시 주의해주세요", + "pt": "", + "ru": "Дрон в зоне ограничения высоты (%1$s). Будьте осторожны", + "tr": "Aracınız bir İrtifa Bölgesi içinde (%1$s). Lütfen dikkatli uçun.", + "zh": "飞行器在限高区(%1$s)下方,请注意飞行安全。" + }, + "fpv_tip_0x20050407": { + "de": "Fluggerät in GEO-Zone. Max. Flughöhe: %1$s", + "en": "Aircraft in GEO Zone. Max flight altitude: %1$s", + "es": "Aeronave en zona GEO. Altitud máx. de vuelo: %1$s", + "fr": "Appareil dans une zone GEO. Altitude en vol max. : %1$s", + "ja": "機体がGEO区域内です。最大飛行高度: %1$s", + "ko": "GEO 구역의 기체. 최고 비행 고도: %1$s", + "ru": "Дрон в зоне GEO. Максимальная высота полета: %1$s", + "tr": "Hava aracı GEO Bölgesinde. Maksimum uçuş irtifası: %1$s", + "zh": "当前在限飞区,限高%1$s。" + }, + "fpv_tip_0x20050408": { + "de": "Fluggerät fliegt in einer Höhenlagezone (%s). Vorsichtig fliegen", + "en": "Aircraft flying in an Altitude Zone (%s). Fly with caution", + "es": "Aeronave volando en zona de altitud (%s). Vuela con precaución", + "fr": "L'appareil vole dans une zone à altitude limitée (%s). Volez avec précaution", + "ja": "機体が高度制限区域内(%s)を飛行中。慎重に飛行してください", + "ko": "기체 고도 제한 구역(%s) 내 있음. 비행 시 주의 필요", + "ru": "Дрон в зоне ограничения высоты (%s). Будьте осторожны", + "tr": "Araç İrtifa Bölgesinde uçuyor (%s). Aracınızı dikkatli uçurun", + "zh": "飞行器在限高区(%s)下方,请注意飞行安全" + }, + "fpv_tip_0x20050500": { + "de": "Erreiche Max. Flughöhe ...", + "en": "Reaching maximum altitude...", + "es": "Pronto se alcanzará la altitud máxima", + "fr": "Altitude max. atteinte", + "ja": "もうすぐ最大飛行高度に到達します", + "ko": "최고 고도 도달 중...", + "ru": "Достигнута макс. высота", + "tr": "Maksimum irtifaya erişiyor…", + "zh": "即将达到限飞高度" + }, + "fpv_tip_0x20050600": { + "de": "Mehrere erweiterte Warnzonen in der Nähe des Fluggeräts. Mit Vorsicht fliegen.", + "en": "Multiple Enhanced Warning Zones near aircraft. Fly with caution", + "es": "Múltiples zonas de advertencia reforzadas cerca de la aeronave. Vuele con cuidado.", + "fr": "Plusieurs zones de prudence accrue à proximité de l'appareil. Pilotez avec précaution", + "ja": "機体付近に多数の強化警告区域あり。慎重に飛行してください", + "ko": "기체 주변에 경고 강화 구역이 여러 개 있음. 비행 시 주의 필요.", + "ru": "Несколько особых зон предупреждения рядом с дроном. Соблюдайте осторожность при полете", + "tr": "Aracın yanında birden fazla Geliştirilmiş Uyarı Bölgesi mevcut. Dikkatlice uçurun", + "zh": "飞行器附近区域有多个加强警示区,请注意飞行安全" + }, + "fpv_tip_0x20050601": { + "de": "Mehrere erweiterte Warnzonen unterhalb des Fluggeräts. Mit Vorsicht fliegen.", + "en": "Multiple Enhanced Warning Zones below aircraft. Fly with caution", + "es": "Múltiples zonas de advertencia reforzadas debajo de la aeronave. Vuele con cuidado.", + "fr": "Plusieurs zones de prudence accrue à proximité sous l'appareil. Pilotez avec précaution", + "ja": "機体下方に多数の強化警告区域あり。慎重に飛行してください", + "ko": "기체 아래쪽에 경고 강화 구역이 여러 개 있음. 비행 시 주의 필요.", + "ru": "Несколько особых зон предупреждения под дроном. Соблюдайте осторожность при полете", + "tr": "Aracın altında birden fazla Geliştirilmiş Uyarı Bölgesi mevcut. Dikkatlice uçurun", + "zh": "飞行器下方区域有多个加强警示区,请注意飞行安全" + }, + "fpv_tip_0x20050602": { + "de": "Mehrere erweiterte Warnzonen oberhalb des Fluggeräts. Mit Vorsicht fliegen.", + "en": "Multiple Enhanced Warning Zones above aircraft. Fly with caution", + "es": "Múltiples zonas de advertencia reforzadas encima de la aeronave. Vuele con cuidado.", + "fr": "Plusieurs zones de prudence accrue à proximité au-dessus de l'appareil. Pilotez avec précaution", + "ja": "機体上方に多数の強化警告区域あり。慎重に飛行してください", + "ko": "기체 위쪽에 경고 강화 구역이 여러 개 있음. 비행 시 주의 필요.", + "ru": "Несколько особых зон предупреждения над дроном. Соблюдайте осторожность при полете", + "tr": "Aracın üstünde birden fazla Geliştirilmiş Uyarı Bölgesi mevcut. Dikkatlice uçurun", + "zh": "飞行器上方区域有多个加强警示区,请注意飞行安全" + }, + "fpv_tip_0x20050603": { + "de": "Erweiterte Warnzone in der Nähe (%s. Flughöhenbereich: %s m. Tatsächliche Zeit: %s). Mit Vorsicht fliegen.", + "en": "Enhanced Warning Zone nearby (%s. Altitude range: %s m. Effective time: %s). Fly with caution", + "es": "Zona de advertencia reforzada cercana (%s. Rango de altitud: %s m. Tiempo efectivo: %s). Vuele con cuidado.", + "fr": "Zone de prudence accrue à proximité (%s. Plage d'altitude : %sm. Temps effectif : %s). Pilotez avec précaution", + "ja": "付近に強化警告区域 (%s。高度範囲: %s m。実効時間: %s)。慎重に飛行してください", + "ko": "근처에 경고 강화 구역(%s. 고도 범위: %sm. 유효 시간: %s). 비행 시 주의 필요.", + "ru": "Особая зона предупреждения поблизости (%s. Диапазон высот: %s м. Эффективное время: %s). Соблюдайте осторожность при полете", + "tr": "Yakınlarda Geliştirilmiş Uyarı Bölgesi mevcut (%s. İrtifa menzili: %s dk. geçerlilik süresi: %s). Dikkatlice uçurun", + "zh": "飞行器附近有加强警示区(%s,高度区间:%s,生效时段:%s),请注意飞行安全" + }, + "fpv_tip_0x20050604": { + "de": "Erweiterte Warnzone unterhalb (%s. Flughöhenbereich: %s m. Tatsächliche Zeit: %s). Mit Vorsicht fliegen.", + "en": "Enhanced Warning Zone below (%s. Altitude range: %s m. Effective time: %s). Fly with caution", + "es": "Zona de advertencia reforzada debajo (%s. Rango de altitud: %s m. Tiempo efectivo: %s). Vuele con cuidado.", + "fr": "Zone de prudence accrue sous (%s. Plage d'altitude : %sm. Temps effectif : %s). Pilotez avec précaution", + "ja": "下方に強化警告区域 (%s。高度範囲: %s m。実効時間: %s)。慎重に飛行してください", + "ko": "아래쪽에 경고 강화 구역(%s. 고도 범위: %sm. 유효 시간: %s). 비행 시 주의 필요.", + "ru": "Особая зона предупреждения ниже (%s. Диапазон высот: %s м. Эффективное время: %s). Соблюдайте осторожность при полете", + "tr": "Altta Geliştirilmiş Uyarı Bölgesi (%s. İrtifa menzili: %s dk. geçerlilik süresi: %s). Dikkatlice uçurun", + "zh": "飞行器下方区域有加强警示区(%s,高度区间:%s,生效时段:%s),请注意飞行安全" + }, + "fpv_tip_0x20050605": { + "de": "Erweiterte Warnzone oberhalb (%s. Flughöhenbereich: %s m. Tatsächliche Zeit: %s). Mit Vorsicht fliegen.", + "en": "Enhanced Warning Zone above (%s. Altitude range: %s m. Effective time: %s). Fly with caution", + "es": "Zona de advertencia reforzada encima (%s. Rango de altitud: %s m. Tiempo efectivo: %s). Vuele con cuidado.", + "fr": "Zone de prudence accrue au-dessus (%s. Plage d'altitude : %sm. Temps effectif : %s). Pilotez avec précaution", + "ja": "上方に強化警告区域 (%s。高度範囲: %s m。実効時間: %s)。慎重に飛行してください", + "ko": "위쪽에 경고 강화 구역(%s. 고도 범위: %sm. 유효 시간: %s). 비행 시 주의 필요.", + "ru": "Особая зона предупреждения выше (%s. Диапазон высот: %s м. Эффективное время: %s). Соблюдайте осторожность при полете", + "tr": "Yukarıda Geliştirilmiş Uyarı Bölgesi (%s. İrtifa menzili: %s dk. geçerlilik süresi: %s). Dikkatlice uçurun", + "zh": "飞行器上方区域有加强警示区(%s,高度区间:%s,生效时段:%s),请注意飞行安全" + }, + "fpv_tip_0x20050606": { + "de": "Fluggerät in erweiterter Warnzone (%s. Flughöhenbereich: %s. Tatsächliche Zeit: %s). Mit Vorsicht fliegen.", + "en": "Aircraft in Enhanced Warning Zone (%s. Altitude range: %s. Effective time: %s). Fly with caution", + "es": "Aeronave en zona de advertencia reforzada (%s. Rango de altitud: %s. Tiempo efectivo: %s). Vuele con cuidado.", + "fr": "Appareil dans la zone de prudence accrue (%s. Plage d'altitude : %s. Temps effectif : %s). Pilotez avec précaution", + "ja": "機体が強化警告区域に侵入 (%s。高度範囲: %s。実効時間: %s)。慎重に飛行してください", + "ko": "기체가 경고 강화 구역 진입(%s. 고도 범위: %s. 유효 시간: %s). 비행 시 주의 필요.", + "ru": "Дрон находится в особой зоне предупреждения (%s. Диапазон высот: %s. Эффективное время: %s). Соблюдайте осторожность при полете", + "tr": "Araç Geliştirilmiş Uyarı Bölgesinde (%s. İrtifa menzili: %s. Geçerlilik süresi: %s). Dikkatlice uçurun", + "zh": "飞行器在加强警示区(%s,区间:%s,生效时段:%s)内,请注意飞行安全" + }, + "fpv_tip_0x20050607": { + "de": "Mehrere erweiterte Warnzonen in der Nähe. Mit Vorsicht fliegen.", + "en": "Multiple Enhanced Warning Zones nearby. Fly with caution", + "es": "Múltiples zonas de advertencia reforzadas cercanas. Vuele con cuidado.", + "fr": "Plusieurs zones de prudence accrue à proximité. Pilotez avec précaution", + "ja": "付近に多数の強化警告区域あり。慎重に飛行してください", + "ko": "주변에 경고 강화 구역이 여러 개 있음. 비행 시 주의 필요.", + "ru": "Несколько особых зон предупреждения поблизости. Соблюдайте осторожность при полете", + "tr": "Yakınlarda birden fazla Geliştirilmiş Uyarı Bölgesi mevcut. Dikkatlice uçurun", + "zh": "附近有多个加强警示区,请注意飞行安全" + }, + "fpv_tip_0x20050608": { + "de": "GPS-Signal schwach. Geo-Awareness-Funktion beeinträchtigt. Mit Vorsicht fliegen.", + "en": "GPS signal weak. Geo-awareness function degraded. Fly with caution", + "es": "Señal GPS débil. Función de reconocimiento geográfico deteriorada. Vuele con cuidado.", + "fr": "Signal GPS faible. Fonction de géovigilance dégradée. Pilotez avec précaution", + "ja": "GPS信号 弱。ジオアウェアネス機能が低下しています。慎重に飛行してください", + "ko": "GPS 신호 약함. 지리 인식 기능 저하됨. 비행 시 주의 필요.", + "ru": "Слабый сигнал GPS. Функция гео-осведомленности ухудшилась. Соблюдайте осторожность при полете", + "tr": "GPS sinyali zayıf. Coğrafi farkındalık işlevi bozuldu. Dikkatlice uçurun", + "zh": "GPS信号差,地理感知功能降级,请谨慎飞行" + }, + "fpv_tip_0x20060100": { + "de": "GPS-Koordinaten kopiert %s", + "en": "GPS location copied. %s", + "es": "Ubicación de GPS copiada. %s", + "fr": "Géolocalisation GPS copiée. %s", + "ja": "GPS 位置情報がコピーされました。 %s", + "ko": "GPS 좌표 복사됨 %s", + "ru": "Координаты GPS скопированы %s", + "tr": "GPS konumu kopyalandı. %s", + "zh": "GPS坐标已复制 %s" + }, + "fpv_tip_0x20060200": { + "de": "RNG-Info kopiert. %s", + "en": "RNG info copied. %s", + "es": "Información RNG copiada. %s", + "fr": "Informations RNG copiées. %s", + "ja": "RNG 情報がコピーされました %s", + "ko": "RNG 정보 복사됨. %s", + "ru": "Информация RNG скопирована. %s", + "tr": "RNG bilgisi kopyalandı. %s", + "zh": "RNG信息已复制 %s" + }, + "fpv_tip_0x20070100": { + "de": "Fehler: Antriebssystem des Fluggeräts. Notlandung. Fluggerät manuell steuern und in einem offenen Bereich landen", + "en": "Aircraft propulsion system error. Forced landing. Manually control the aircraft and land in an open area", + "es": "Error del sistema de propulsión de la aeronave. Aterrizaje forzoso. Controla la aeronave manualmente y aterriza en un espacio abierto", + "fr": "Erreur du système de propulsion de l\\'appareil. Atterrissage forcé. Contrôlez l\\'appareil manuellement et atterrissez dans une zone dégagée", + "it": "", + "ja": "機体推進システムエラー。強制着陸。機体を手動で制御し、開けた場所に着陸してください", + "ko": "기체 추진력 시스템 오류. 강제 착륙. 기체를 수동으로 제어하여 개방 영역에 착륙하세요", + "pt": "", + "ru": "Ошибка винтомоторной системы дрона. Принудительное приземление. Вручную управляя дроном, приземлитесь на открытом участке", + "tr": "Araç itiş gücü sistemi hatası. Zorunlu iniş. Aracı manuel olarak kontrol edin ve açık bir alana iniş yapın", + "zh": "飞行器动力异常,现已强制降落!请尽快打杆操作飞行器降落至空旷地区" + }, + "fpv_tip_0x20070101": { + "de": "Fehler: Antriebssystem des Fluggeräts. Start nicht möglich", + "en": "Aircraft propulsion system error. Unable to take off", + "es": "Error del sistema de propulsión de la aeronave. No se puede despegar", + "fr": "Erreur du système de propulsion de l\\'appareil. Impossible de décoller", + "ja": "機体推進システムエラー。離陸できません", + "ko": "기체 추진력 시스템 오류. 이륙 불가", + "ru": "Ошибка винтомоторной системы дрона. Невозможно выполнить взлет", + "tr": "Araç itiş gücü sistemi hatası. Kalkış yapamıyor", + "zh": "飞行器动力异常,无法起飞!" + }, + "fpv_tip_0x20080100": { + "de": "Auf OcuSync-Bildübertragung gewechselt", + "en": "Switched to OcuSync image transmission", + "es": "Cambiado a transmisión de imagen OcuSync", + "fr": "Système de transmission d\\'images OcuSync activé", + "ja": "OcuSync映像伝送に切り替えました", + "ko": "이미지 전송을 위해 OcuSync로 전환됨", + "ru": "Включена передача изображения OcuSync", + "tr": "OcuSync görüntü iletim moduna geçti", + "zh": "已切换为Ocusync图传" + }, + "fpv_tip_0x20080101": { + "de": "Zum LTE-Übertragungsbackup gewechselt", + "en": "Switched to LTE Dual Link", + "es": "Cambiado a LTE Dual Link", + "fr": "Passage à la transmission LTE auxiliaire", + "ja": "LTE補助伝送に切り替わりました", + "ko": "LTE 듀얼 링크로 전환됨", + "ru": "Переключено на резерв передачи LTE", + "tr": "LTE İkili Bağlantıya geçildi", + "zh": "图传链路已切换至LTE增强链路" + }, + "fpv_tip_0x20080200": { + "de": "LTE Dual-Link ist im Dual-Steuerungsmodus nicht verfügbar oder falls diese Fernsteuerung als B-Fernsteuerung eingestellt ist", + "en": "In dual control mode or current RC set as controller B. LTE Dual Link unavailable", + "es": "Modo control dual o CR actual establecido como control B. LTE Dual Link no disponible", + "fr": "Mode double contrôle ou RC actuelle définie comme radiocommande B. Transmission LTE auxiliaire indisponible", + "ja": "デュアル制御モード中か、現在の送信機がコントローラーBとして設定されています。LTEデュアルリンクは利用不可", + "ko": "듀얼 컨트롤 모드에서 또는 현 RC를 B 컨트롤러로 설정. LTE 듀얼 링크 사용 불가", + "ru": "Активирован режим двойного управления или пульт ДУ установлен в качестве пульта B. LTE Dual Link недоступен", + "tr": "İkili kontrol modunda veya B kontrol cihazı olarak ayarlanan mevcut uzaktan kumandada LTE İkili Bağlantı kullanılamaz", + "zh": "双控模式或当前控为B控,无法使用LTE增强链路" + }, + "fpv_tip_0x20080300": { + "de": "LTE-Netzwerk instabil. Mit Vorsicht fliegen", + "en": "LTE network unstable. Fly with caution", + "es": "Red LTE inestable. Vuela con cuidado", + "fr": "Réseau LTE instable. Volez avec précaution", + "ja": "LTEネットワークが不安定。慎重に飛行してください", + "ko": "LTE 네트워크 불안정. 주의해서 비행하세요", + "ru": "Сеть LTE нестабильна. Будьте внимательны при полете", + "tr": "LTE ağı sabit değil. Dikkatli uçurun", + "zh": "当前LTE网络质量差, 请谨慎飞行!" + }, + "fpv_tip_0x20080400": { + "de": "Schwaches Bildübertragungssignal. Antennen ausrichten und mit Vorsicht fliegen", + "en": "Image transmission signal weak. Adjust antennas and fly with caution", + "es": "Señal de transmisión de la imagen débil. Ajusta las antenas y vuela con cuidado", + "fr": "Signal de transmission d'image faible. Ajustez les antennes et pilotez avec précaution", + "ja": "映像伝送信号が弱い。アンテナを調整し、慎重に飛行してください", + "ko": "이미지 전송 신호 약함. 안테나를 조정하고 주의하여 비행하세요.", + "ru": "Плохое качество сигнала передачи изображения. Отрегулируйте антенны и соблюдайте осторожность при полете", + "tr": "Görüntü aktarım sinyali zayıf. Antenleri ayarlayın ve aracınızı dikkatli uçurun", + "zh": "图传信号微弱,请调整天线并谨慎打杆" + }, + "fpv_tip_0x20080500": { + "de": "Schwaches Fernsteuerungssignal", + "en": "Remote Controller Signal Weak", + "es": "Señal débil del control remoto", + "fr": "Signal de la radiocommande faible", + "ja": "送信機信号微弱", + "ko": "조종기 신호 약함", + "ru": "Слабый сигнал пульта", + "tr": "Uzaktan Kumanda Sinyali Zayıf", + "zh": "遥控器信号微弱,请调整天线" + }, + "fpv_tip_0x20080600": { + "de": "Starke Signalstörung an der Fernsteuerung. Entfernen Sie sich von anderen Fernsteuerungen oder Störquellen", + "en": "Strong remote controller signal interference. Move away from other remote controllers or the source of interference", + "es": "Fuerte interferencia de la señal del control remoto. Aléjate de otros controles remotos o de la fuente de interferencia", + "fr": "Fortes interférences de signal de la radiocommande. Éloignez-vous des autres radiocommandes ou de la source d'interférence", + "ja": "強度の送信機信号干渉。他の送信機や干渉源から離れてください", + "ko": "조종기 신호 간섭 강함. 다른 조종기 또는 간섭원에서 벗어나야 함", + "ru": "Сильные помехи сигнала пульта управления. Отдалитесь от других пультов управления как можно скорее", + "tr": "Güçlü uzaktan kumanda sinyali müdahalesi. Diğer uzaktan kumandalardan veya müdahale kaynaklarından uzak durun", + "zh": "遥控器侧干扰较强,请远离其他遥控器或干扰源" + }, + "fpv_tip_0x20080700": { + "de": "Starke Signalstörung am Fluggerät. Kehren Sie sofort zurück oder entfernen Sie sich von der Störquelle", + "en": "Strong aircraft signal interference. Return to home promptly or move away from the source of interference", + "es": "Fuerte interferencia de la señal de la aeronave. Regresa al punto de origen rápidamente o aléjate de la fuente de interferencia", + "fr": "Fortes interférences de signal de l'appareil. Retournez au point de départ rapidement ou éloignez-vous de la source d'interférence", + "ja": "強度の機体信号干渉。直ちに帰還するか干渉源から離れてください", + "ko": "조종기 신호 간섭 강함. 즉시 리턴 투 홈 또는 간섭원에서 벗어나야 함", + "ru": "Сильные помехи сигнала летательного аппарата. Вернитесь домой или отдалитесь от источника помех как можно скорее", + "tr": "Güçlü araç sinyali müdahalesi. Hemen eve geri dönün veya müdahalenin kaynağından uzaklaşın", + "zh": "飞行器侧干扰较强,请尽快返航或飞离干扰源" + }, + "fpv_tip_0x20090000": { + "de": "Bildmittenstabilisierung ausgesetzt", + "en": "Vision stabilization paused.", + "es": "Estabilización visual en pausa.", + "fr": "Stabilisation optique mise en pause.", + "ja": "ビジョン安定化を一時停止しました。", + "ko": "비전 안정화 시스템 일시 정지", + "ru": "Стабилизация изображения приостановлена", + "tr": "Görüş stabilizasyonu duraklatıldı.", + "zh": "视觉增稳功能已暂停" + }, + "fpv_tip_0x20090001": { + "de": "Bildmittenstabilisierung fortgesetzt.", + "en": "Vision stabilization resumed.", + "es": "Estabilización visual reanudada.", + "fr": "Reprise de la stabilisation optique.", + "ja": "ビジョン安定化を再開しました。", + "ko": "비전 안정화 시스템 재개", + "ru": "Стабилизация изображения возобновлена", + "tr": "Görüş stabilizasyonu devam ettirildi.", + "zh": "视觉增稳功能已恢复" + }, + "fpv_tip_0x20090002": { + "de": "Bildmittenstabilisierung ausgesetztReason: Features too few in current video.", + "en": "Vision stabilization paused.Reason: Features too few in current video.", + "es": "Estabilización visual en pausa.Reason: Features too few in current video.", + "fr": "Stabilisation optique mise en pause.Reason: Features too few in current video.", + "ja": "ビジョン安定化を一時停止しました。Reason: Features too few in current video.", + "ko": "비전 안정화 시스템 일시 정지Reason: Features too few in current video.", + "ru": "Стабилизация изображения приостановленаReason: Features too few in current video.", + "tr": "Görüş stabilizasyonu duraklatıldı.Reason: Features too few in current video.", + "zh": "视觉增稳功能已暂停,原因:画面特征点过少" + }, + "fpv_tip_0x20090003": { + "de": "Bildmittenstabilisierung fortgesetzt.Reason: Features too few in current video.", + "en": "Vision stabilization resumed.Reason: Features too few in current video.", + "es": "Estabilización visual reanudada.Reason: Features too few in current video.", + "fr": "Reprise de la stabilisation optique.Reason: Features too few in current video.", + "ja": "ビジョン安定化を再開しました。Reason: Features too few in current video.", + "ko": "비전 안정화 시스템 재개Reason: Features too few in current video.", + "ru": "Стабилизация изображения возобновленаReason: Features too few in current video.", + "tr": "Görüş stabilizasyonu devam ettirildi.Reason: Features too few in current video.", + "zh": "视觉增稳功能已暂停,原因:相机参数已变更" + }, + "fpv_tip_0x20090004": { + "de": "Bildmittenstabilisierung ausgesetztReason: Features too few in current video.Reason: Features too few in current video.", + "en": "Vision stabilization paused.Reason: Features too few in current video.Reason: Features too few in current video.", + "es": "Estabilización visual en pausa.Reason: Features too few in current video.Reason: Features too few in current video.", + "fr": "Stabilisation optique mise en pause.Reason: Features too few in current video.Reason: Features too few in current video.", + "ja": "ビジョン安定化を一時停止しました。Reason: Features too few in current video.Reason: Features too few in current video.", + "ko": "비전 안정화 시스템 일시 정지Reason: Features too few in current video.Reason: Features too few in current video.", + "ru": "Стабилизация изображения приостановленаReason: Features too few in current video.Reason: Features too few in current video.", + "tr": "Görüş stabilizasyonu duraklatıldı.Reason: Features too few in current video.Reason: Features too few in current video.", + "zh": "视觉增稳功能已暂停,原因:当前处于跟踪模式" + }, + "fpv_tip_0x20090100": { + "de": "Stellenmarkierung hinzugefügt", + "en": "Pin Point Success", + "es": "Marca añadida correctamente", + "fr": "Pin Point réussi", + "ja": "ピンの設置に成功しました", + "ko": "핀 포인트 성공", + "ru": "Точка успешно прикреплена", + "tr": "İsabet Başarısı", + "zh": "打点成功" + }, + "fpv_tip_0x20090101": { + "de": "Datenabruf von Laserentfernungsmesser nicht möglich. Standortaufzeichnung fehlgeschlagen", + "en": "Unable to get laser rangefinder data. Recording location failed", + "es": "No se pueden obtener datos del telémetro láser. Error de registro de ubicación", + "fr": "Impossible d\\'obtenir les données du télémètre laser. Enregistrement de l\\'emplacement échoué", + "ja": "レーザー距離計データを取得できません。場所の記録に失敗しました", + "ko": "레이저 거리계 데이터를 얻을 수 없습니다. 위치 레코딩 실패", + "ru": "Невозможно получить данные лазерного дальномера. Не удалось записать расположение", + "tr": "Lazer menzil bulucu verisini alamıyor. Konum kaydı başarısız", + "zh": "未获取到激光测距数据,打点失败" + }, + "fpv_tip_0x20090102": { + "de": "Unzureichende Satelliten verfügbar. Standortaufzeichnung fehlgeschlagen", + "en": "Insufficient satellites available. Recording location failed", + "es": "No hay suficientes satélites disponibles. Error de registro de ubicación", + "fr": "Nombre de satellites disponibles insuffisant. Enregistrement de l\\'emplacement échoué", + "ja": "衛星が不十分。場所の記録に失敗しました", + "ko": "이용 가능한 위성이 충분하지 않습니다. 위치 레코딩 실패", + "ru": "Недостаточно доступных спутников. Не удалось записать расположение", + "tr": "Yeterli sayıda kullanılabilir uydu yok. Konum kaydı başarısız", + "zh": "位置信息无效,打点失败" + }, + "fpv_tip_0x20090103": { + "de": "Position des Fluggeräts erfolgreich gepinnt", + "en": "Aircraft location pinned successfully", + "es": "Ubicación de la aeronave fijada con éxito", + "fr": "Emplacement de l'appareil épinglé avec succès", + "ja": "機体の位置を正常に固定しました", + "ko": "기체 위치가 성공적으로 고정되었습니다", + "ru": "Местоположение дрона успешно зафиксировано", + "tr": "Hava aracının konumu başarıyla işaretlendi", + "zh": "原地打点成功" + }, + "fpv_tip_0x20090200": { + "de": "Smarte Verfolgung starten", + "en": "Starting Smart Track", + "es": "Iniciando Smart Track", + "fr": "Début de L\\'acquisition de cible", + "it": "", + "ja": "ターゲット捕捉を開始しています", + "ko": "스마트 트랙 시작", + "pt": "", + "ru": "Начинается интеллектуальное следование", + "tr": "Akıllı Takip Başlatılıyor", + "zh": "开始智能跟踪" + }, + "fpv_tip_0x20090201": { + "de": "TA Deaktiviert", + "en": "Smart Track Turn Off", + "es": "Desactivar ST", + "fr": "ST Éteindre", + "it": "", + "ja": "ST オフにする", + "ko": "ST 닫기", + "pt": "", + "ru": "Определение цели выключено", + "tr": "Kapat ST", + "zh": "智能跟踪关闭" + }, + "fpv_tip_0x20090202": { + "de": "Zielidentifikation nicht möglich. Ziel durch Ziehen auf Bildschirm auswählen", + "en": "Unable to identify target. Drag-select target on screen", + "es": "No se puede identificar el objetivo. Arrastra para seleccionar el objetivo en pantalla", + "fr": "Impossible d\\'identifier le sujet. Encadrez le sujet à l\\'écran", + "ja": "ターゲットを特定できません。ドラッグして画面上でターゲットを選択してください", + "ko": "타겟을 식별할 수 없습니다. 화면에서 타겟을 끌어서 선택하세요", + "ru": "Невозможно идентифицировать цель. Перетащите и выберите цель на экране", + "tr": "Hedefi tanımlayamıyor. Ekran üzerinde hedefi sürükleyin-seçin", + "zh": "未识别到目标,请在屏幕上手动框选" + }, + "fpv_tip_0x20100000": { + "de": "D-RTK-Akkustand niedrig", + "en": "D-RTK Low Battery", + "es": "Batería baja de D-RTK", + "fr": "Batterie D-RTK faible", + "ja": "D-RTKローバッテリー", + "ko": "D-RTK 배터리 부족", + "ru": "Низкий заряд батареи D-RTK", + "tr": "Düşük Pilde Eve Dönüş", + "zh": "D-RTK低电量警报" + }, + "fpv_tip_0x20100100": { + "de": "RTK-Statusfehler. Der Modus \\\"Positioniergenauigkeit beibehalten\\\" wird gestartet. Das Fluggerät verlässt RTK, falls eine Verbindung nicht in angemessener Zeit wiederhergestellt werden kann", + "en": "RTK status error. Entering Maintain Positioning Accuracy mode. Aircraft will exit RTK if reconnection timed out", + "es": "Error de RTK. La aeronave está accediendo al modo Mantener precisión de posicionamiento. La aeronave saldrá de RTK si se agota el tiempo de reconexión", + "fr": "Erreur de statut RTK. Passage au mode Maintien de la précision de positionnement. L\\'appareil sort du RTK si le délai de reconnexion est expiré", + "ja": "RTKステータスエラー。測位精度維持モードに入ります。時間内に再接続できない場合、機体はRTKを終了します", + "ko": "RTK 상태 오류. \\'포지셔닝 정확도 유지\\' 모드 실행. 연결 시간 초과 시 기체 RTK 종료", + "ru": "Ошибка статуса RTK. Вход в режим поддержания точности позиционирования. Дрон выйдет из режима RTK, если время повторного подключения истекло", + "tr": "RTK durumu hatası. Konum Doğruluğunu Koruma moduna giriliyor. Bağlantı zaman aşımına uğrarsa araç RTK\\'dan çıkacaktır", + "zh": "RTK状态异常,将进入精度维持模式,超时将自动退出RTK" + }, + "fpv_tip_0x20100200": { + "de": "RTK-Basisstation nicht gefunden. Basisstation überprüfen und erneut suchen", + "en": "RTK base station not found. Check base station and search again", + "es": "No se ha encontrado la estación base RTK. Comprueba la estación base y vuelve a buscar", + "fr": "Station de base RTK introuvable. Vérifiez la station de base et effectuez une nouvelle recherche", + "ja": "RTK基地局が見つかりません。基地局を確認し、もう一度検索してください", + "ko": "RTK 기지국을 찾을 수 없습니다. 기지국을 확인하고 다시 검색하세요", + "ru": "Базовая станция RTK не найдена. Проверьте базовую станцию и повторите поиск", + "tr": "RTK baz istasyonu bulunamadı. Baz istasyonu kontrol edin ve tekrar arayın", + "zh": "未搜索到RTK基站,请检查RTK基站后重新搜索" + }, + "fpv_tip_0x2010D000": { + "de": "D-RTK -Akkustand niedrig", + "en": "D-RTK Low Battery", + "es": "Batería baja de D-RTK", + "fr": "Batterie D-RTK faible", + "it": "", + "ja": "D-RTK ローバッテリー", + "ko": "D-RTK 배터리 부족", + "pt": "", + "ru": "Низкий заряд батареи D-RTK", + "tr": "Düşük Pilde Eve Dönüş", + "zh": "D-RTK 低电量警报" + }, + "fpv_tip_0x20110000": { + "de": "Autom. vorwärmen der Akkus ...", + "en": "Battery heating", + "es": "Calentamiento de la batería", + "fr": "Préchauffage batterie", + "ja": "バッテリー過熱", + "ko": "배터리 자동 예열 중...", + "ru": "Прогрев батареи", + "tr": "Pil ısınıyor", + "zh": "电池加热中" + }, + "fpv_tip_0x20120000": { + "de": "Zugriff auf die GPS-Informationen des Mobilgeräts fehlgeschlagen.", + "en": "Fail to access mobile device GPS information.", + "es": "No se pudo acceder al GPS del dispositivo móvil.", + "fr": "Impossible d\\'accéder aux informations GPS de votre appareil mobile.", + "ja": "モバイルデバイスの GPS 情報へのアクセスに失敗しました。", + "ko": "모바일 기기 GPS 정보 액세스 실패", + "ru": "Не удалось получить доступ к информации о GPS мобильного устройства.", + "tr": "Mobil cihaz GPS bilgilerine erişilemedi.", + "zh": "获取移动设备GPS失败" + }, + "fpv_tip_0x20120001": { + "de": "Zugriff auf die GPS-Informationen des DJI Geräts fehlgeschlagen.", + "en": "Fail to access DJI device GPS information.", + "es": "No se pudo acceder al GPS del dispositivo DJI.", + "fr": "Impossible d\\'accéder aux informations GPS de votre appareil DJI.", + "ja": "DJI デバイスの GPS 情報へのアクセスに失敗しました。", + "ko": "DJI 기기 GPS 정보 액세스 실패", + "ru": "Не удалось получить доступ к информации о GPS устройства DJI.", + "tr": "DJI cihaz GPS bilgilerine erişilemedi.", + "zh": "获取DJI设备GPS失败" + }, + "fpv_tip_0x20120200": { + "de": "Fluggerät vor den nächsten Schritt landen.", + "en": "Land aircraft before continuing to next step", + "es": "Aterriza la aeronave antes de proceder con el siguiente paso", + "fr": "Faire atterrir aéronef avant poursuite étape suivante", + "ja": "次のステップに進む前に、機体を着陸させてください", + "ko": "다음 단계 진행 전에 기체를 착륙시키세요", + "ru": "Приземлитесь перед тем как продолжить", + "tr": "Bir sonraki adıma devam etmeden önce aracı indirin", + "zh": "请先将飞机降落至地面,再进行下一步操作" + }, + "fpv_tip_0x20120300": { + "de": "Fluggerät fliegt zum Startpunkt", + "en": "Aircraft flying to editing start point", + "es": "La aeronave está volando al punto de partida editado", + "fr": "L\\'appareil vole vers le point de départ modifié", + "ja": "機体は編集開始点に向かって飛行しています", + "ko": "기체가 \\'편집 시작 지점\\'으로 비행", + "ru": "Дрон летит к точке начала редактирования", + "tr": "Araç düzeltme başlangıç noktasına dönüyor", + "zh": "飞行器自动飞至起始点,请耐心等待" + }, + "fpv_tip_0x20120301": { + "de": "Fluggerät am Startpunkt angekommen. Bitte Bearbeitung starten.", + "en": "Arrived at editing start point. Begin editing", + "es": "La aeronave está en el punto de partida editado. Inicia la edición ahora", + "fr": "L\\'appareil est au point de départ modifié. Vous pouvez éditer la balise", + "ja": "機体は編集開始点に到着。ここで編集を開始してください", + "ko": "기체가 \\'편집 시작 지점\\'에 있음. 편집 시작 가능", + "ru": "Дрон в точке начала редактирования. Вы можете начинать процесс", + "tr": "Düzenleme başlangıç noktasına varıldı. Düzenlemeye başla", + "zh": "飞行器已到达起始点,请开始操作" + }, + "fpv_tip_0x20120302": { + "de": "Bearbeitung der Flugroute beenden", + "en": "Exit Flight Route Editing", + "es": "Salir de edición de ruta de vuelo", + "fr": "Quitter la modification de l\\'itinéraire de vol", + "ja": "飛行ルート編集を終了", + "ko": "비행 경로 편집 종료", + "ru": "Выход из редактирования маршрута полета", + "tr": "Uçuş Rotası Düzenleme Menüsünden Çık", + "zh": "退出飞行编辑" + }, + "fpv_tip_0x20120400": { + "de": "Keine Telefonnummer verknüpft. Max. Höhe und Distanz wurden beschränkt. Bitte Telefonnummer vor dem Start verknüpfen.", + "en": "Phone not bound. Altitude and distance limited. Bind phone before taking off.", + "es": "El teléfono no está vinculado. Se han limitado la altitud y la distancia. Agrupa el teléfono antes de despegar.", + "fr": "Téléphone non lié. L\\'altitude et la distance permises pour votre vol sont limitées. Liez votre téléphone avant de décoller.", + "ja": "電話が紐付けされていません。 高度と距離が制限。 離陸前に電話と紐付けしてください。", + "ko": "전화번호 바인딩 안 됨. 고도 및 거리에 제한 있음. 이륙 전에 전화번호를 바인딩하세요", + "ru": "Тел. номер не привязан. Высота и расстояние полета ограничены. Привяжите тел. номер перед взлетом", + "tr": "Telefon bağlı değil. Uçuş irtifası ve mesafe sınırlandı. Kalkıştan önce telefonu bağlayın.", + "zh": "未绑定手机,已限高限远。请完成绑定手机再起飞。" + }, + "fpv_tip_0x20120500": { + "de": "Mediendateien werden über die aktuelle Fernsteuerung hochgeladen.", + "en": "Media files will be uploaded through current remote controller", + "es": "Los archivos multimedia se cargarán a través del control remoto actual", + "fr": "Les fichiers multimédias seront téléchargés via la radiocommande actuelle", + "ja": "メディアファイルは、現在の送信機からアップロードされます", + "ko": "미디어 파일은 현재 조종기를 통해 자동으로 업로드됩니다.", + "ru": "Медиафайлы будут загружены с помощью текущего пульта дистанционного управления", + "tr": "Medya dosyaları mevcut uzaktan kumanda aracılığıyla yüklenecektir", + "zh": "媒体资源将从当前控上传云端" + }, + "fpv_tip_0x20120501": { + "de": "Mediendateien werden über eine andere Fernsteuerung hochgeladen.", + "en": "Media files will be uploaded through another remote controller", + "es": "Los archivos multimedia se cargarán a través de otro control remoto", + "fr": "Les fichiers multimédias seront téléchargés via une autre radiocommande", + "ja": "メディアファイルは別の送信機からアップロードされます", + "ko": "미디어 파일은 다른 조종기를 통해 자동으로 업로드됩니다.", + "ru": "Медиафайлы будут загружены с помощью другого пульта дистанционного управления", + "tr": "Medya dosyaları başka bir uzaktan kumanda aracılığıyla yüklenecektir", + "zh": "媒体资源将从另一个控上传云端" + }, + "fpv_tip_0x20120502": { + "ar": "", + "de": "", + "en": "Aircraft cloud control enabled", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "飞行器已接受云端命令控制", + "zh-Hant": "" + }, + "fpv_tip_0x20120503": { + "ar": "", + "de": "", + "en": "Aircraft bound to other team. Cloud service unavailable", + "es": "", + "fr": "", + "id": "", + "it": "", + "ja": "", + "ko": "", + "nl": "", + "pl": "", + "pt": "", + "pt-PT": "", + "ru": "", + "th": "", + "tr": "", + "ug": "", + "vi": "", + "zh": "飞行器跨团队,云服务不可用", + "zh-Hant": "" + }, + "fpv_tip_0x20120600": { + "de": "Aus Projekt entfernt. Projektdetails können nicht angezeigt werden", + "en": "Removed from project. Unable to view project details", + "es": "Eliminado del proyecto. No se pueden ver los detalles del proyecto", + "fr": "Supprimé du projet. Impossible d'afficher les détails du projet", + "ja": "プロジェクトから削除されました。プロジェクトの詳細を表示できません", + "ko": "프로젝트에서 제거됨. 프로젝트 세부 정보 확인 불가", + "ru": "Удалено из проекта. Невозможно просмотреть сведения о проекте", + "tr": "Projeden kaldırıldı. Proje bilgileri görüntülenemiyor", + "zh": "您已被当前项目移除,将无法查看该项目内容" + }, + "fpv_tip_0x20120700": { + "de": "Projekt archiviert. Projektdetails können nicht angezeigt werden", + "en": "Project archived. Unable to view project details", + "es": "Proyecto archivado. No se pueden ver los detalles del proyecto", + "fr": "Projet archivé. Impossible d'afficher les détails du projet", + "ja": "プロジェクトがアーカイブされました。プロジェクトの詳細を表示できません", + "ko": "프로젝트가 보관됨. 프로젝트 세부 정보 확인 불가", + "ru": "Проект в архиве. Невозможно просмотреть сведения о проекте", + "tr": "Proje arşivlendi. Proje bilgileri görüntülenemiyor", + "zh": "您所在项目已归档,将无法查看该项目内容" + }, + "fpv_tip_0x20120800": { + "de": "Projektteam aufgelöst. Projektdetails können nicht angezeigt werden", + "en": "Project team disbanded. Unable to view project details", + "es": "El equipo del proyecto se disolvió. No se pueden ver los detalles del proyecto", + "fr": "Équipe du projet dissoute. Impossible d'afficher les détails du projet", + "ja": "プロジェクトチームが削除されました。プロジェクトの詳細を表示できません", + "ko": "프로젝트 팀이 해산됨. 프로젝트 세부 정보 확인 불가", + "ru": "Команда проекта расформирована. Невозможно просмотреть сведения о проекте", + "tr": "Proje ekibi dağıldı. Proje bilgileri görüntülenemiyor", + "zh": "您所在项目已解散,将无法查看该项目内容" + }, + "fpv_tip_0x20120900": { + "de": "Echtzeit-Kartierung gestoppt", + "en": "Real-time mapping stopped", + "es": "Cartografía en tiempo real detenida", + "fr": "Cartographie en temps réel arrêtée", + "ja": "リアルタイムマッピングが停止しました", + "ko": "실시간 매핑 중단됨", + "ru": "Создание карт в реальном времени остановлено", + "tr": "Gerçek zamanlı haritalama durduruldu", + "zh": "实时建图停止" + }, + "fpv_tip_0x20120A00": { + "de": "Livestream gestartet", + "en": "Livestream started", + "es": "Retransmisión en directo iniciada", + "fr": "La diffusion en direct a commencé", + "ja": "ライブ配信が開始されました", + "ko": "라이브 스트림 시작됨", + "ru": "Прямая трансляция началась", + "tr": "Canlı yayın başladı", + "zh": "已开启直播" + }, + "fpv_tip_0x20120B00": { + "de": "Der Flugrouteneinsatz wurde manuell unterbrochen", + "en": "Flight route mission paused manually", + "es": "Misión de ruta de vuelo pausada manualmente", + "fr": "Mission d\\'itinéraire de vol interrompue manuellement", + "ja": "飛行ルート ミッションを手動で一時停止", + "ko": "수동으로 비행경로 임무 일시 정지됨", + "ru": "Полетная миссия приостановлена вручную", + "tr": "Uçuş rotası görevi manuel olarak duraklatıldı", + "zh": "您已手动暂停航线任务" + }, + "fpv_tip_0x20120B01": { + "de": "RTK-Signal schwach. Flugrouteneinsatz wurde unterbrochen", + "en": "RTK signal weak. Flight route mission paused", + "es": "Señal RTK débil. Misión de ruta de vuelo en pausa", + "fr": "Signal RTK faible. Mission d\\'itinéraire de vol interrompue", + "ja": "RTK信号 弱。飛行ルート ミッションを一時停止", + "ko": "RTK 신호 약함. 비행경로 임무 일시 정지됨", + "ru": "Слабый сигнал RTK. Полетная миссия приостановлена", + "tr": "RTK sinyali zayıf. Uçuş rotası görevi duraklatıldı", + "zh": "RTK信号差,航线任务已暂停" + }, + "fpv_tip_0x20120B02": { + "de": "Max. Flughöhe erreicht. Flugrouteneinsatz wurde unterbrochen", + "en": "Max flight altitude reached. Flight route mission paused", + "es": "Se ha alcanzado la altitud máxima de vuelo. Misión de ruta de vuelo en pausa", + "fr": "Altitude de vol max. atteinte. Mission d\\'itinéraire de vol interrompue", + "ja": "最大飛行高度に到達。飛行ルート ミッションを一時停止", + "ko": "최고 비행 고도 도달. 비행경로 임무 일시 정지됨", + "ru": "Достигнут предел высоты полета дрона. Полетная миссия приостановлена", + "tr": "Maksimum uçuş irtifasına ulaşıldı. Uçuş rotası görevi duraklatıldı", + "zh": "飞行器已达到飞行最大高度,航线任务已暂停" + }, + "fpv_tip_0x20120B03": { + "de": "Max. Flugdistanz erreicht. Flugrouteneinsatz wurde unterbrochen", + "en": "Max flight distance reached. Flight route mission paused", + "es": "Se ha alcanzado la distancia máxima de vuelo. Misión de ruta de vuelo en pausa", + "fr": "Distance de vol max. atteinte. Mission d\\'itinéraire de vol interrompue", + "ja": "最大飛行距離に到達。飛行ルート ミッションを一時停止", + "ko": "최대 비행 거리 도달. 비행경로 임무 일시 정지됨", + "ru": "Достигнуто макс. расстояние полета. Полетная миссия приостановлена", + "tr": "Maksimum uçuş mesafesine ulaşıldı. Uçuş rotası görevi duraklatıldı", + "zh": "飞行器已达到飞行最远距离,航线任务已暂停" + }, + "fpv_tip_0x20120B04": { + "de": "Flugaufgabe pausiert. Hindernis erkannt oder Fluggerät nähert sich einer GEO-Zone", + "en": "Flight task paused. Obstacle detected or aircraft approaching GEO Zone", + "es": "Tarea de vuelo en pausa. Obstáculo detectado o aeronave acercándose a la zona GEO.", + "fr": "Tâche de vol mise en pause. Obstacle détecté ou appareil en approche d'une zone GEO", + "ja": "飛行タスクが一時停止。障害物が検知されたか、機体がGEO区域に接近中です", + "ko": "비행 작업 일시 정지됨. 장애물이 감지되었거나 기체가 GEO 구역에 접근 중입니다.", + "ru": "Полетная задача приостановлена. Обнаружено препятствие или дрон приближается к зоне GEO", + "tr": "Uçuş görevi duraklatıldı. Engel algılandı veya hava aracı GEO Bölgesine yaklaşıyor", + "zh": "航线任务暂停,飞行器检测到障碍物或靠近限飞区" + }, + "fpv_tip_0x20120B05": { + "de": "Fluggerät nähert sich einer GEO-Zone. Aufgabe unterbrochen.", + "en": "Approaching GEO Zone. Task paused", + "es": "Se está acercando a una zona GEO. Tarea en pausa", + "fr": "Approche de la zone GEO. Tâche interrompue", + "it": "", + "ja": "GEO区域に近づいています。タスクが一時停止しました", + "ko": "GEO 구역에 접근 중. 작업 일시 중지됨", + "pt": "", + "ru": "Приближение к зоне GEO. Задание приостановлено", + "tr": "GEO Bölgesine yaklaşılıyor. Görev duraklatıldı", + "zh": "飞行器接近限飞区,航线任务已暂停" + }, + "fpv_tip_0x20120B06": { + "de": "Mindestflughöhe erreicht. Aufgabe unterbrochen.", + "en": "Min flight altitude reached. Task paused", + "es": "Se ha alcanzado la altitud mín. de vuelo. Tarea en pausa", + "fr": "Altitude en vol minimale atteinte. Tâche interrompue", + "ja": "最低飛行高度に達しました。タスクが一時停止されました", + "ko": "최저 비행 고도에 도달했습니다. 작업 일시 중지됨", + "ru": "Достигнута минимальная высота полета. Задание приостановлено", + "tr": "Min. uçuş irtifasına ulaşıldı. Görev duraklatıldı", + "zh": "飞行器已达到飞行最低高度,航线任务已暂停" + }, + "fpv_tip_0x20120B07": { + "de": "Unbekannter Fehler. Aufgabe unterbrochen.", + "en": "Unknown error. Task paused", + "es": "Error desconocido. Tarea en pausa", + "fr": "Erreur inconnue. Tâche interrompue", + "ja": "原因不明のエラー。タスクが一時停止されました", + "ko": "알 수 없는 오류. 작업 일시 중지됨", + "ru": "Неизвестная ошибка. Задание приостановлено", + "tr": "Bilinmeyen hata. Görev duraklatıldı", + "zh": "未知原因,航线任务已暂停" + }, + "fpv_tip_0x20120B08": { + "de": "Maximale Flughöhe der Flughafen-Höhenlagezone erreicht", + "en": "Max flight altitude of airport Altitude Zone reached", + "es": "Altitud máxima de vuelo de zona de aeropuerto alcanzada", + "fr": "Altitude maximale de vol de la zone d'altitude de l'aéroport atteinte", + "ja": "空港の高度制限区域の最大飛行高度に達しました", + "ko": "공항 고도 제한 구역 최고 비행 고도에 도달했습니다", + "ru": "Достигнута максимальная высота полета в зоне ограничения высоты полета аэропорта", + "tr": "Havaalanı İrtifa Bölgesinin maks. uçuş irtifasına ulaşıldı", + "zh": "超过机场限高区限高" + }, + "fpv_tip_0x20120B09": { + "de": "Notbremse ausgelöst. Flugaufgabe pausiert", + "en": "Emergency brake triggered. Flight task paused", + "es": "Freno de emergencia accionado. Tarea de vuelo en pausa", + "fr": "Frein d'urgence déclenché. Tâche de vol mise en pause", + "ja": "緊急ブレーキが作動しました。飛行タスクが一時停止しました", + "ko": "비상 브레이크가 작동되었습니다. 비행이 일시 정지되었습니다", + "ru": "Сработал аварийный тормоз. Полетная задача приостановлена", + "tr": "Acil durum freni tetiklendi. Uçuş görevi duraklatıldı", + "zh": "触发紧急刹停,航线任务已暂停" + }, + "fpv_tip_0x20120B0A": { + "de": "Umgebungslicht zu hell oder zu dunkel", + "en": "Ambient light is too bright or too dark", + "es": "La luz ambiental es demasiado brillante o demasiado oscura", + "fr": "La lumière ambiante est trop intense ou trop sombre", + "ja": "環境光が明るすぎるか、暗すぎます", + "ko": "주변 조명이 너무 밝거나 너무 어두움", + "ru": "Окружающий свет слишком яркий или слишком темный", + "tr": "Ortam ışığı çok parlak veya çok az", + "zh": "环境光过亮或过暗" + }, + "fpv_tip_0x20120B0B": { + "de": "Schwaches GPS-Signal. Flugaufgabe pausiert", + "en": "Weak GPS signal. Flight task paused", + "es": "Señal GPS débil. Tarea de vuelo en pausa", + "fr": "Signal GPS faible. Tâche de vol mise en pause", + "ja": "GPS信号が弱い。飛行タスクが一時停止しました", + "ko": "GPS 신호 약함. 비행 작업이 일시 정지됩니다.", + "ru": "Слабый сигнал GPS. Полетная задача приостановлена", + "tr": "Zayıf GPS sinyali. Uçuş görevi duraklatıldı", + "zh": "GPS信号差,航线任务已暂停" + }, + "fpv_tip_0x20120B0C": { + "de": "Startpunkt nicht aktualisiert. Flugaufgabe pausiert", + "en": "Home Point not updated. Flight task paused", + "es": "Punto de origen no actualizado. Tarea de vuelo en pausa", + "fr": "Point de départ non mis à jour. Tâche de vol mise en pause", + "ja": "ホームポイントが更新されていません。飛行タスクが一時停止しました", + "ko": "홈포인트 업데이트 안 됨. 비행 작업이 일시 정지됩니다.", + "ru": "Домашняя точка не обновлена. Полетная задача приостановлена", + "tr": "Başlangıç Noktası güncellenmedi. Uçuş görevi duraklatıldı", + "zh": "返航点未刷新,航线任务已暂停" + }, + "fpv_tip_0x20120B0D": { + "de": "Fernsteuerung getrennt. Intelligente Rückkehr zum Startpunkt läuft", + "en": "Remote controller disconnected. Smart RTH in progress", + "es": "Control remoto no conectado. RPO inteligente en curso", + "fr": "Radiocommande déconnectée. RTH intelligent en cours", + "ja": "送信機の接続が切断されました。スマートRTHが進行中です", + "ko": "조종기 연결 끊김. 스마트 RTH가 진행 중입니다.", + "ru": "Пульт ДУ отключен. Выполняется умный возврат домой", + "tr": "Uzaktan kumanda bağlantısı kesildi. Akıllı BND sürdürülüyor", + "zh": "遥控器断连,正在执行智能返航" + }, + "fpv_tip_0x20120B0E": { + "de": "Automatischer Start fehlgeschlagen. Flugroute versuchsweise erneut hochladen", + "en": "Auto takeoff failed. Try uploading flight route again", + "es": "Error de despegue automático. Pruebe a cargar la ruta de vuelo de nuevo", + "fr": "Échec du décollage automatique. Essayer de recharger à nouveau la trajectoire de vol", + "ja": "自動離陸に失敗しました。飛行ルートをアップロードし直してください", + "ko": "자동 이륙 실패. 비행 경로를 다시 업로드해 보세요.", + "ru": "Не удалось выполнить автовзлет. Попробуйте загрузить маршрут полета еще раз", + "tr": "Otomatik kalkış başarısız. Uçuş rotasını tekrar yüklemeyi deneyin", + "zh": "自动起飞失败,请尝试重新上传航线" + }, + "fpv_tip_0x20120B0F": { + "de": "Annäherung an Grenze von benutzerdefiniertem Fluggebiet. Flugaufgabe pausiert", + "en": "Approaching boundary of custom flight area. Flight task paused", + "es": "Acercándose al límite de la zona de vuelo personalizada. Tarea de vuelo en pausa", + "fr": "Approche en cours des limites de la zone de vol personnalisée. Tâche de vol mise en pause", + "ja": "カスタム飛行エリアの境界に近づいています。飛行タスクが一時停止しました", + "ko": "맞춤 설정 비행 영역의 경계에 접근 중. 비행 작업이 일시 정지됩니다.", + "ru": "Приближение к границе пользовательской зоны полета. Полетная задача приостановлена", + "tr": "Özel uçuş alanının sınırına yaklaşılıyor. Uçuş görevi duraklatıldı", + "zh": "接近自定义飞行区,航线任务已暂停" + }, + "fpv_tip_0x20120B10": { + "de": "Fehler Terrain-Follow-Flughöhe (mehr als 200 m oder weniger als 30 m). Parameter ändern", + "en": "Terrain Follow altitude error (greater than 200 m or less than 30 m). Modify parameter", + "es": "Error de altitud y altura constante (más de 200 m o menos de 30 m). Modificar parámetro", + "fr": "Erreur d’altitude du suivi terrain (supérieure à 200 m ou inférieure à 30 m). Modifier le paramètre", + "ja": "地形フォロー高度エラー (200 m超または30 m未満)。パラメーターを修正してください", + "ko": "지형 팔로우 고도 오류(200m 초과 또는 30m 미만). 매개변수를 수정하세요.", + "ru": "Ошибка высоты в режиме огибания рельефа (более 200 м или менее 30 м). Изменить параметр", + "tr": "Arazi Takip irtifası hatası (200 m'den fazla veya 30 m'den az). Parametreyi değiştirin", + "zh": "仿地高度异常(大于200m或小于30m),请修改参数" + }, + "fpv_tip_0x20120B11": { + "de": "Windgeschwindigkeit zu hoch. Flugaufgabe pausiert", + "en": "Wind speed too high. Flight task paused", + "es": "Velocidad del viento demasiado alta. Tarea de vuelo en pausa", + "fr": "Vitesse du vent trop élevée. Tâche de vol mise en pause", + "ja": "風速が強すぎます。飛行タスクが一時停止しました", + "ko": "풍속이 너무 높음. 비행 작업이 일시 정지됩니다.", + "ru": "Слишком высокая скорость ветра. Полетная задача приостановлена", + "tr": "Rüzgar hızı çok yüksek. Uçuş görevi duraklatıldı", + "zh": "风速过大,航线任务已暂停" + }, + "fpv_tip_0x20120B12": { + "de": "Fluggerät an der Grenze einer Höhenlagezone oder Flughöhe des Fluggeräts zu niedrig. Flugaufgabe pausiert", + "en": "Aircraft at the boundary of an Altitude Zone or aircraft altitude too low. Flight task paused", + "es": "Aeronave en el límite de una zona de altitud o altitud de la aeronave demasiado baja. Tarea de vuelo en pausa", + "fr": "Appareil à proximité immédiate d’une zone à altitude limitée ou altitude de l’appareil trop basse. Tâche de vol mise en pause", + "ja": "機体が高度制限区域の境界にあるか、機体の高度が低すぎます。飛行タスクが一時停止しました", + "ko": "기체가 고도 제한 구역의 경계에 있거나 기체 고도가 너무 낮음. 비행 작업이 일시 정지됩니다.", + "ru": "Дрон на границе зоны ограничения высоты полета или высота полета слишком мала. Полетная задача приостановлена", + "tr": "Hava aracı bir İrtifa Bölgesinin sınırında veya araç irtifası çok düşük. Uçuş görevi duraklatıldı", + "zh": "触碰到限高区或飞行器高度过低,航线任务已中断" + }, + "fpv_tip_0x20120C00": { + "de": "Sichtpositionierung deaktivieren", + "en": "Disable Vision Positioning", + "es": "Desactivar sistema de visión inferior", + "fr": "Positionnement visuel OFF", + "ja": "下方ビジョンシステムをオフ", + "ko": "하향 비전 시스템 꺼짐", + "ru": "выкл систему нижнего обзора", + "tr": "Aşağı Görüş Sistemini Kapat", + "zh": "禁用视觉定位" + }, + "fpv_tip_0x20120C01": { + "de": "ichtpositionierung aktivieren", + "en": "Enable Vision Positioning", + "es": "Activar sistema de visión inferior", + "fr": "Positionnement visuel ON", + "ja": "下方ビジョンシステムをオン", + "ko": "하향 비전 시스템 켜짐", + "ru": "Вкл систему нижнего обзора", + "tr": "Aşağı Görüş Sistemini Aç", + "zh": "启用视觉定位" + }, + "fpv_tip_0x20120C02": { + "en": "Cloud control from DJI DeliveryHub enabled", + "zh": "已允许大疆司运指令" + }, + "fpv_tip_0x20120C03": { + "en": "Pausing flight through cloud control", + "zh": "执行云端急停指令" + }, + "fpv_tip_0x20120C04": { + "en": "Aircraft landing through cloud control", + "zh": "执行云端降落指令" + }, + "fpv_tip_0x20120C05": { + "en": "Aircraft returning to home through cloud control", + "zh": "执行云端返航指令" + }, + "fpv_tip_0x20120C06": { + "en": "Operating winch system through cloud control", + "zh": "执行云端空吊指令" + }, + "fpv_tip_0x20120C07": { + "en": "Operating FPV gimbal camera through cloud control", + "zh": "执行云端FPV指令" + }, + "fpv_tip_0x20120C08": { + "en": "Performing flight task through cloud control", + "zh": "执行云端航线指令" + }, + "fpv_tip_0x20120C09": { + "en": "Cloud control from DJI DeliveryHub disabled", + "zh": "已撤销云端指令许可" + }, + "fpv_tip_0x20120C0A": { + "en": "RTH canceled by cloud control", + "zh": "云端已取消返航" + }, + "fpv_tip_0x20120D01": { + "en": "Obstacle sensing of all directions disabled. Fly with caution", + "zh": "全部避障已关闭,请安全飞行" + }, + "fpv_tip_0x20120D02": { + "en": "Horizontal obstacle sensing disabled. Fly with caution", + "zh": "水平避障已关闭,请安全飞行" + }, + "fpv_tip_0x20120D03": { + "en": "Upward obstacle sensing disabled. Fly with caution", + "zh": "上避障已关闭,请安全飞行" + }, + "fpv_tip_0x20120D04": { + "en": "Downward obstacle sensing disabled. Fly with caution", + "zh": "下避障已关闭,请安全飞行" + }, + "fpv_tip_0x20120E00": { + "de": "Hohe ionosphärische Aktivität im aktuellen Gebiet. Genauigkeit der Positionsbestimmung möglicherweise beeinträchtigt", + "en": "High ionospheric activity in current area. Positioning accuracy may be affected", + "es": "Alta actividad ionosférica en la zona actual. La precisión de posicionamiento podría verse afectada", + "fr": "Activité ionosphérique élevée dans la zone actuelle. La précision du positionnement risque d'être affectée", + "ja": "現在の場所で電離層活動が活発。測位精度に影響する可能性があります", + "ko": "현재 지역에서 높은 전리층 활동. 위치 정확도가 영향을 받을 수 있습니다", + "ru": "Высокая ионосферная активность в текущем районе. Точность позиционирования может быть нарушена", + "tr": "Geçerli alanda yüksek iyonosferik aktivite. Konumlandırma doğruluğu etkilenebilir", + "zh": "当前地区电离层开始活跃,可能影响定位精度" + }, + "fpv_tip_0x20120F00": { + "ar": "", + "de": "Benutzerkonto nicht gefunden. Flugdistanz beschränkt. Bitte anmelden.", + "en": "Account not logged in. Flight altitude and distance restricted to 30 m and 50 m respectively. Login required", + "es": "No se inició sesión. Distancia y altitud de vuelo limitadas a 50 y 30 m. Inicia sesión", + "fr": "Vous n'êtes pas connecté. La distance et l'altitude de vol sont limitées à 30 m et 50 m. Vérifiez et connectez-vous", + "id": "", + "it": "", + "ja": "アカウントにログインしていません。飛行高度は30 mに、飛行距離は50 mに制限。 確認してログインしてください。", + "ko": "계정 로그인 안 됨. 비행 고도(30m) 및 거리(50m) 제한 있음. 확인 후 로그인하세요", + "nl": "", + "pl": "", + "pt": "Conta não logada. Altitude e distância de voo restritas a 30 m e 50 m. Verifique e faça login", + "pt-PT": "", + "ru": "Вход не выполнен. Высота и расстояние полета ограничены до 30 и 50 м. Проверьте и выполните вход", + "th": "", + "tr": "Hesap otur. açılamadı. Uçuk irtifası ve mesafesi 30 m ve 50 m ile sınırlıdır. Kontrol et ve aç", + "ug": "", + "vi": "", + "zh": "未检测到账号,已限高30m,限远50m,请登录", + "zh-Hant": "" + } +} \ No newline at end of file diff --git a/dk-modules/system/pom.xml b/dk-modules/system/pom.xml index 6ed43f7..bfaf2e9 100644 --- a/dk-modules/system/pom.xml +++ b/dk-modules/system/pom.xml @@ -48,6 +48,12 @@ common-web + + org.dromara + common-cloudsdk + 2.2.2 + + org.dromara common-mybatis diff --git a/dk-modules/workflow/src/main/resources/application.yml b/dk-modules/workflow/src/main/resources/application.yml index afdc1c2..dc2b2a0 100644 --- a/dk-modules/workflow/src/main/resources/application.yml +++ b/dk-modules/workflow/src/main/resources/application.yml @@ -6,7 +6,7 @@ server: spring: application: # 应用名称 - name: workflow + name: dk-workflow profiles: # 环境配置 active: @profiles.active@ diff --git a/dk-visual/monitor/src/main/resources/application.yml b/dk-visual/monitor/src/main/resources/application.yml index 061b13c..e0e843c 100644 --- a/dk-visual/monitor/src/main/resources/application.yml +++ b/dk-visual/monitor/src/main/resources/application.yml @@ -6,7 +6,7 @@ server: spring: application: # 应用名称 - name: monitor + name: dk-monitor profiles: # 环境配置 active: @profiles.active@ diff --git a/dk-visual/nacos/src/main/resources/application.properties b/dk-visual/nacos/src/main/resources/application.properties index 868b823..9a38864 100644 --- a/dk-visual/nacos/src/main/resources/application.properties +++ b/dk-visual/nacos/src/main/resources/application.properties @@ -40,9 +40,9 @@ spring.sql.init.platform=mysql db.num=1 ### Connect URL of DB: -db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true +db.url.0=jdbc:mysql://114.235.183.147:3306/dk_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true db.user.0=root -db.password.0=123456 +db.password.0=dk123456! ### the maximum retry times for push nacos.config.push.maxRetryTime=50 diff --git a/dk-visual/sentinel-dashboard/src/main/resources/application.yml b/dk-visual/sentinel-dashboard/src/main/resources/application.yml index 55f2332..c4f54af 100644 --- a/dk-visual/sentinel-dashboard/src/main/resources/application.yml +++ b/dk-visual/sentinel-dashboard/src/main/resources/application.yml @@ -6,7 +6,7 @@ server: spring: application: # 应用名称 - name: sentinel-dashboard + name: dk-sentinel-dashboard profiles: # 环境配置 active: @profiles.active@ diff --git a/dk-visual/snailjob-server/src/main/resources/application.yml b/dk-visual/snailjob-server/src/main/resources/application.yml index 4ce7033..41d8ff9 100644 --- a/dk-visual/snailjob-server/src/main/resources/application.yml +++ b/dk-visual/snailjob-server/src/main/resources/application.yml @@ -5,7 +5,7 @@ server: spring: application: - name: ruoyi-snailjob-server + name: dk-snailjob-server profiles: active: @profiles.active@ web: diff --git a/pom.xml b/pom.xml index 195cfda..aeff2df 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,11 @@ 3.11.0 3.1.2 1.3.0 + + + 1.0.3 + 6.4.1 + 1.7.0 @@ -73,12 +78,12 @@ dev - 114.235.183.147:8848 + 127.0.0.1:8848 DEFAULT_GROUP DEFAULT_GROUP nacos nacos - 114.235.183.147:4560 + 127.0.0.1:4560 @@ -89,12 +94,12 @@ prod prod - 114.235.183.147:8848 + 127.0.0.1:8848 DEFAULT_GROUP DEFAULT_GROUP nacos nacos - 114.235.183.147:4560 + 127.0.0.1:4560 @@ -371,6 +376,17 @@ ${rocketmq.version} + + org.springframework.integration + spring-integration-mqtt + ${spring-integration-mqtt.version} + + + org.springdoc + springdoc-openapi-ui + ${openapi-ui.version} + + diff --git a/sessionStore/root.data b/sessionStore/root.data new file mode 100644 index 0000000..e69de29