远程调试功能补全

This commit is contained in:
sdy 2026-05-20 16:11:35 +08:00
parent 8029e78127
commit 3265568e69
7 changed files with 474 additions and 20 deletions

View File

@ -2,16 +2,21 @@ package com.multictrl.modules.business.controller;
import com.multictrl.common.annotation.ApiOrder; import com.multictrl.common.annotation.ApiOrder;
import com.multictrl.common.annotation.LogOperation; import com.multictrl.common.annotation.LogOperation;
import com.multictrl.common.exception.ErrorCode;
import com.multictrl.common.utils.Result; import com.multictrl.common.utils.Result;
import com.multictrl.common.validator.ValidatorUtils;
import com.multictrl.modules.business.dto.remote.debug.ESIMActivate;
import com.multictrl.modules.business.dto.remote.debug.ESIMOperatorSwitch;
import com.multictrl.modules.business.dto.remote.debug.RtkCalibration;
import com.multictrl.modules.business.dto.remote.debug.SIMSlotSwitch;
import com.multictrl.modules.business.service.DJIBaseService; import com.multictrl.modules.business.service.DJIBaseService;
import com.multictrl.modules.business.service.DebugService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/** /**
* 远程调试 * 远程调试
@ -27,61 +32,226 @@ import org.springframework.web.bind.annotation.RestController;
@ApiOrder(3) @ApiOrder(3)
@RequiredArgsConstructor @RequiredArgsConstructor
public class DebugController { public class DebugController {
private final DJIBaseService debugService; private final DJIBaseService djiBaseService;
private final DebugService debugService;
@Operation(summary = "调试模式开启") @Operation(summary = "调试模式开启")
@GetMapping("/debugModeOpen/{dockSn}") @PostMapping("/debugModeOpen/{dockSn}")
@LogOperation("调试模式开启") @LogOperation("调试模式开启")
@RequiresPermissions("bus:debug:operation") @RequiresPermissions("bus:debug:operation")
public Result<Object> debugModeOpen(@PathVariable String dockSn) { public Result<Object> debugModeOpen(@PathVariable String dockSn) {
return new Result<>().ok(debugService.executeAndReturnResult(dockSn, "debug_mode_open")); return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "debug_mode_open"));
} }
@Operation(summary = "调试模式关闭") @Operation(summary = "调试模式关闭")
@GetMapping("/debugModeClose/{dockSn}") @PostMapping("/debugModeClose/{dockSn}")
@LogOperation("调试模式关闭") @LogOperation("调试模式关闭")
@RequiresPermissions("bus:debug:operation") @RequiresPermissions("bus:debug:operation")
public Result<Object> debugModeClose(@PathVariable String dockSn) { public Result<Object> debugModeClose(@PathVariable String dockSn) {
return new Result<>().ok(debugService.executeAndReturnResult(dockSn, "debug_mode_close")); return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "debug_mode_close"));
} }
@Operation(summary = "强制关舱盖") @Operation(summary = "强制关舱盖",
@GetMapping("/coverForceClose/{dockSn}") description = "机场“设备属性”推送的 drone_in_dock 字段值为 0 时,且通过机场摄像头观看确认飞行器不在舱内后,可调用该指令强制关闭舱盖。否则可能导致桨叶被夹。")
@PostMapping("/coverForceClose/{dockSn}")
@LogOperation("强制关舱盖") @LogOperation("强制关舱盖")
@RequiresPermissions("bus:debug:operation") @RequiresPermissions("bus:debug:operation")
public Result<Object> coverForceClose(@PathVariable String dockSn) { public Result<Object> coverForceClose(@PathVariable String dockSn) {
return new Result<>().ok(debugService.executeAndReturnResult(dockSn, "cover_force_close")); return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "cover_force_close"));
} }
@Operation(summary = "打开舱盖") @Operation(summary = "打开舱盖")
@GetMapping("/coverOpen/{dockSn}") @PostMapping("/coverOpen/{dockSn}")
@LogOperation("打开舱盖") @LogOperation("打开舱盖")
@RequiresPermissions("bus:debug:operation") @RequiresPermissions("bus:debug:operation")
public Result<Object> coverOpen(@PathVariable String dockSn) { public Result<Object> coverOpen(@PathVariable String dockSn) {
return new Result<>().ok(debugService.executeAndReturnResult(dockSn, "cover_open")); return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "cover_open"));
} }
@Operation(summary = "关闭舱盖") @Operation(summary = "关闭舱盖")
@GetMapping("/coverClose/{dockSn}") @PostMapping("/coverClose/{dockSn}")
@LogOperation("关闭舱盖") @LogOperation("关闭舱盖")
@RequiresPermissions("bus:debug:operation") @RequiresPermissions("bus:debug:operation")
public Result<Object> coverClose(@PathVariable String dockSn) { public Result<Object> coverClose(@PathVariable String dockSn) {
return new Result<>().ok(debugService.executeAndReturnResult(dockSn, "cover_close")); return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "cover_close"));
} }
@Operation(summary = "飞行器开机") @Operation(summary = "飞行器开机")
@GetMapping("/droneOpen/{dockSn}") @PostMapping("/droneOpen/{dockSn}")
@LogOperation("飞行器开机") @LogOperation("飞行器开机")
@RequiresPermissions("bus:debug:operation") @RequiresPermissions("bus:debug:operation")
public Result<Object> droneOpen(@PathVariable String dockSn) { public Result<Object> droneOpen(@PathVariable String dockSn) {
return new Result<>().ok(debugService.executeAndReturnResult(dockSn, "drone_open")); return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "drone_open"));
} }
@Operation(summary = "飞行器关机") @Operation(summary = "飞行器关机")
@GetMapping("/droneClose/{dockSn}") @PostMapping("/droneClose/{dockSn}")
@LogOperation("飞行器关机") @LogOperation("飞行器关机")
@RequiresPermissions("bus:debug:operation") @RequiresPermissions("bus:debug:operation")
public Result<Object> droneClose(@PathVariable String dockSn) { public Result<Object> droneClose(@PathVariable String dockSn) {
return new Result<>().ok(debugService.executeAndReturnResult(dockSn, "drone_close")); return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "drone_close"));
}
@Operation(summary = "eSIM的运营商切换")
@PostMapping("/eSIMOperatorSwitch/{dockSn}")
@LogOperation("eSIM的运营商切换")
@RequiresPermissions("bus:debug:eSIMOperatorSwitch")
public Result<Object> eSIMOperatorSwitch(@PathVariable String dockSn,
@RequestBody ESIMOperatorSwitch eSimOperatorSwitch) {
ValidatorUtils.validateEntity(eSimOperatorSwitch);
return new Result<>().ok(debugService.eSIMOperatorSwitch(dockSn, eSimOperatorSwitch));
}
@Operation(summary = "eSIM和SIM切换")
@PostMapping("/simSlotSwitch/{dockSn}")
@LogOperation("eSIM和SIM切换")
@RequiresPermissions("bus:debug:simSlotSwitch")
public Result<Object> simSlotSwitch(@PathVariable String dockSn,
@RequestBody SIMSlotSwitch simSlotSwitch) {
ValidatorUtils.validateEntity(simSlotSwitch);
return new Result<>().ok(debugService.simSlotSwitch(dockSn, simSlotSwitch));
}
@Operation(summary = "eSIM激活")
@PostMapping("/eSimActivate/{dockSn}")
@LogOperation("eSIM激活")
@RequiresPermissions("bus:debug:eSimActivate")
public Result<Object> eSimActivate(@PathVariable String dockSn,
@RequestBody ESIMActivate esimActivate) {
ValidatorUtils.validateEntity(esimActivate);
return new Result<>().ok(debugService.eSimActivate(dockSn, esimActivate));
}
@Operation(summary = "增强图传开关")
@PostMapping("/sdrWorkModeSwitch/{dockSn}")
@LogOperation("增强图传开关")
@RequiresPermissions("bus:debug:sdrWorkModeSwitch")
public Result<Object> sdrWorkModeSwitch(@PathVariable String dockSn,
@Parameter(description = "图传模式 {0:仅使用 SDR,1:4G 增强模式},在 4G 增强模式下SDR 与 4G 会同时使用")
@RequestParam Integer workMode) {
if (workMode != 0 && workMode != 1) {
return new Result<>().error(ErrorCode.PARAMS_ERROR);
}
return new Result<>().ok(debugService.sdrWorkModeSwitch(dockSn, workMode));
}
@Operation(summary = "关闭充电")
@PostMapping("/chargeClose/{dockSn}")
@LogOperation("关闭充电")
@RequiresPermissions("bus:debug:chargeClose")
public Result<Object> chargeClose(@PathVariable String dockSn) {
return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "charge_close"));
}
@Operation(summary = "打开充电")
@PostMapping("/chargeOpen/{dockSn}")
@LogOperation("打开充电")
@RequiresPermissions("bus:debug:chargeOpen")
public Result<Object> chargeOpen(@PathVariable String dockSn) {
return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "charge_open"));
}
@Operation(summary = "飞行器数据格式化")
@PostMapping("/droneFormat/{dockSn}")
@LogOperation("飞行器数据格式化")
@RequiresPermissions("bus:debug:droneFormat")
public Result<Object> droneFormat(@PathVariable String dockSn) {
return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "drone_format"));
}
@Operation(summary = "机场数据格式化")
@PostMapping("/deviceFormat/{dockSn}")
@LogOperation("机场数据格式化")
@RequiresPermissions("bus:debug:deviceFormat")
public Result<Object> deviceFormat(@PathVariable String dockSn) {
return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "device_format"));
}
@Operation(summary = "机场重启")
@PostMapping("/deviceReboot/{dockSn}")
@LogOperation("机场重启")
@RequiresPermissions("bus:debug:deviceReboot")
public Result<Object> deviceReboot(@PathVariable String dockSn) {
return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "device_reboot"));
}
@Operation(summary = "电池运行模式切换")
@PostMapping("/batteryStoreModeSwitch/{dockSn}")
@LogOperation("电池运行模式切换")
@RequiresPermissions("bus:debug:batteryStoreModeSwitch")
public Result<Object> batteryStoreModeSwitch(@PathVariable String dockSn,
@Parameter(description = "操作 {1:计划模式,2:待命模式}")
@RequestParam Integer action) {
if (action != 1 && action != 2) {
return new Result<>().error(ErrorCode.PARAMS_ERROR);
}
return new Result<>().ok(debugService.batteryStoreModeSwitch(dockSn, action));
}
@Operation(summary = "机场声光报警开关")
@PostMapping("/alarmStateSwitch/{dockSn}")
@LogOperation("机场声光报警开关")
@RequiresPermissions("bus:debug:alarmStateSwitch")
public Result<Object> alarmStateSwitch(@PathVariable String dockSn,
@Parameter(description = "操作 {0:关闭,1:开启}")
@RequestParam Integer action) {
if (action != 0 && action != 1) {
return new Result<>().error(ErrorCode.PARAMS_ERROR);
}
return new Result<>().ok(debugService.alarmStateSwitch(dockSn, action));
}
@Operation(summary = "机场空调工作模式切换")
@PostMapping("/airConditionerModeSwitch/{dockSn}")
@LogOperation("机场空调工作模式切换")
@RequiresPermissions("bus:debug:airConditionerModeSwitch")
public Result<Object> airConditionerModeSwitch(@PathVariable String dockSn,
@Parameter(description = "操作 {0:使机场空调进入空闲模式(关闭制冷、制热或除湿)," +
"1:使机场空调进入制冷模式,2:使机场空调进入制热模式," +
"3:使机场空调进入除湿模式(除湿包含制冷除湿及制热除湿,由设备端根据自身所处情况自动化处理,无需用户介入}")
@RequestParam Integer action) {
if (action != 0 && action != 1 && action != 2 && action != 3) {
return new Result<>().error(ErrorCode.PARAMS_ERROR);
}
return new Result<>().ok(debugService.airConditionerModeSwitch(dockSn, action));
}
@Operation(summary = "电池保养状态切换")
@PostMapping("/batteryMaintenanceSwitch/{dockSn}")
@LogOperation("电池保养状态切换")
@RequiresPermissions("bus:debug:batteryMaintenanceSwitch")
public Result<Object> batteryMaintenanceSwitch(@PathVariable String dockSn,
@Parameter(description = "操作 {0:关闭,1:开启}")
@RequestParam Integer action) {
if (action != 0 && action != 1) {
return new Result<>().error(ErrorCode.PARAMS_ERROR);
}
return new Result<>().ok(debugService.batteryMaintenanceSwitch(dockSn, action));
}
@Operation(summary = "关闭补光灯")
@PostMapping("/supplementLightClose/{dockSn}")
@LogOperation("关闭补光灯")
@RequiresPermissions("bus:debug:supplementLightClose")
public Result<Object> supplementLightClose(@PathVariable String dockSn) {
return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "supplement_light_close"));
}
@Operation(summary = "打开补光灯")
@PostMapping("/supplementLightOpen/{dockSn}")
@LogOperation("打开补光灯")
@RequiresPermissions("bus:debug:supplementLightOpen")
public Result<Object> supplementLightOpen(@PathVariable String dockSn) {
return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "supplement_light_open"));
}
@Operation(summary = "一键标定")
@PostMapping("/rtkCalibration/{dockSn}")
@LogOperation("一键标定")
@RequiresPermissions("bus:debug:rtkCalibration")
public Result<Object> rtkCalibration(@PathVariable String dockSn,
@RequestBody RtkCalibration rtkCalibration) {
ValidatorUtils.validateEntity(rtkCalibration);
return new Result<>().ok(debugService.rtkCalibration(dockSn, rtkCalibration));
} }
} }

View File

@ -0,0 +1,24 @@
package com.multictrl.modules.business.dto.remote.debug;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
* eSIM 激活参数
*
* @author Sdy
* @since 1.0.0 2026/5/20
*/
@Data
@Schema(description = "eSIM激活参数")
public class ESIMActivate {
@NotBlank(message = "dongle imei不能为空")
@Schema(description = "dongle imei", example = "123456789012345")
private String imei;
@NotBlank(message = "目标设备类型不能为空")
@Schema(description = "目标设备类型 {dock:设置机场 Dongle,drone:设置飞行器 Dongle}", example = "dock", allowableValues = {"dock", "drone"})
private String deviceType;
}

View File

@ -0,0 +1,32 @@
package com.multictrl.modules.business.dto.remote.debug;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
* eSIM运营商切换参数
*
* @author Sdy
* @since 1.0.0 2026/5/20
*/
@Data
@Schema(description = "eSIM运营商切换参数")
public class ESIMOperatorSwitch {
@NotBlank(message = "dongle imei不能为空")
@Schema(description = "dongle imei", example = "123456789012345")
private String imei;
@NotBlank(message = "目标设备类型不能为空")
@Schema(description = "目标设备类型 {dock:设置机场 Dongle,drone:设置飞行器 Dongle}", example = "dock", allowableValues = {"dock", "drone"})
private String deviceType;
@NotBlank(message = "切换的目标运营商不能为空")
@Min(value = 1, message = "切换的目标运营商类型错误")
@Max(value = 3, message = "切换的目标运营商类型错误")
@Schema(description = "切换的目标运营商 {1:移动,2:联通,3:电信}", example = "1", allowableValues = {"1", "2", "3"})
private Integer esimOperator;
}

View File

@ -0,0 +1,62 @@
package com.multictrl.modules.business.dto.remote.debug;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
/**
* 一键标定参数
*
* @author Sdy
* @since 1.0.0 2026/5/20
*/
@Data
@Schema(name = "一键标定参数")
public class RtkCalibration {
@Valid
@NotEmpty(message = "标定设备不能为空")
@Schema(description = "标定设备集合")
private List<CalibrationDevice> devices;
@Data
@Schema(name = "标定设备")
public static class CalibrationDevice {
@NotBlank(message = "设备序列号不能为空")
@Schema(description = "设备序列号SN", example = "ABC123456789")
private String sn;
@Schema(description = "标定类型 {1: 手动标定}", example = "1", allowableValues = {"1"})
private Integer type = 1;
@NotBlank(message = "模块类型不能为空")
@Schema(description = "模块枚举值 {3:机场,6:中继}", example = "3", allowableValues = {"3", "6"})
private String module;
@Valid
@NotNull(message = "标定数据不能为空")
@Schema(description = "标定数据")
private CalibrationData data;
}
@Data
@Schema(name = "标定数据")
public static class CalibrationData {
@NotNull(message = "经度不能为空")
@Schema(description = "经度", example = "114.89828051067889")
private Double longitude;
@NotNull(message = "纬度不能为空")
@Schema(description = "纬度", example = "22.755022128112614")
private Double latitude;
@NotNull(message = "高度不能为空")
@Schema(description = "高度", example = "60.285194396972656")
private Double height;
}
}

View File

@ -0,0 +1,32 @@
package com.multictrl.modules.business.dto.remote.debug;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
* eSIM SIM 切换参数
*
* @author Sdy
* @since 1.0.0 2026/5/20
*/
@Data
@Schema(description = "eSIM和SIM切换参数")
public class SIMSlotSwitch {
@NotBlank(message = "dongle imei不能为空")
@Schema(description = "dongle imei", example = "123456789012345")
private String imei;
@NotBlank(message = "目标设备类型不能为空")
@Schema(description = "目标设备类型 {dock:设置机场 Dongle,drone:设置飞行器 Dongle}", example = "dock", allowableValues = {"dock", "drone"})
private String deviceType;
@NotBlank(message = "切换的目标卡槽不能为空")
@Min(value = 1, message = "切换的目标卡槽类型错误")
@Max(value = 2, message = "切换的目标卡槽类型错误")
@Schema(description = "切换的目标卡槽 {1:实体 SIM 卡,2:eSIM}", example = "1", allowableValues = {"1", "2"})
private Integer simSlot;
}

View File

@ -0,0 +1,42 @@
package com.multictrl.modules.business.service;
import com.multictrl.modules.business.dto.remote.debug.ESIMActivate;
import com.multictrl.modules.business.dto.remote.debug.ESIMOperatorSwitch;
import com.multictrl.modules.business.dto.remote.debug.RtkCalibration;
import com.multictrl.modules.business.dto.remote.debug.SIMSlotSwitch;
/**
* 远程调试接口
*
* @author Sdy
* @since 1.0.0 2026/5/20
*/
public interface DebugService {
//eSIM 的运营商切换
String eSIMOperatorSwitch(String dockSn, ESIMOperatorSwitch eSimOperatorSwitch);
//eSIM和SIM切换
String simSlotSwitch(String dockSn, SIMSlotSwitch simSlotSwitch);
//eSIM激活
String eSimActivate(String dockSn, ESIMActivate eSimActivate);
//增强图传开关
String sdrWorkModeSwitch(String dockSn, Integer workMode);
//电池运行模式切换
String batteryStoreModeSwitch(String dockSn, Integer action);
//机场声光报警开关
String alarmStateSwitch(String dockSn, Integer action);
//机场空调工作模式切换
String airConditionerModeSwitch(String dockSn, Integer action);
//电池保养状态切换
String batteryMaintenanceSwitch(String dockSn, Integer action);
//一键标定
String rtkCalibration(String dockSn, RtkCalibration rtkCalibration);
}

View File

@ -0,0 +1,92 @@
package com.multictrl.modules.business.service.impl;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.multictrl.modules.business.dto.remote.debug.ESIMActivate;
import com.multictrl.modules.business.dto.remote.debug.ESIMOperatorSwitch;
import com.multictrl.modules.business.dto.remote.debug.RtkCalibration;
import com.multictrl.modules.business.dto.remote.debug.SIMSlotSwitch;
import com.multictrl.modules.business.service.DJIBaseService;
import com.multictrl.modules.business.service.DebugService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* 远程调试接口
*
* @author Sdy
* @since 1.0.0 2026/5/20
*/
@Service
@RequiredArgsConstructor
public class DebugServiceImpl implements DebugService {
private final DJIBaseService djiBaseService;
@Override
public String eSIMOperatorSwitch(String dockSn, ESIMOperatorSwitch eSimOperatorSwitch) {
JSONObject data = new JSONObject();
data.set("imei", eSimOperatorSwitch.getImei());
data.set("device_type", eSimOperatorSwitch.getDeviceType());
data.set("esim_operator", eSimOperatorSwitch.getEsimOperator());
return djiBaseService.executeAndReturnResult(dockSn, "esim_operator_switch", data);
}
@Override
public String simSlotSwitch(String dockSn, SIMSlotSwitch simSlotSwitch) {
JSONObject data = new JSONObject();
data.set("imei", simSlotSwitch.getImei());
data.set("device_type", simSlotSwitch.getDeviceType());
data.set("sim_slot", simSlotSwitch.getSimSlot());
return djiBaseService.executeAndReturnResult(dockSn, "sim_slot_switch", data);
}
@Override
public String eSimActivate(String dockSn, ESIMActivate eSimActivate) {
JSONObject data = new JSONObject();
data.set("imei", eSimActivate.getImei());
data.set("device_type", eSimActivate.getDeviceType());
return djiBaseService.executeAndReturnResult(dockSn, "esim_activate", data);
}
@Override
public String sdrWorkModeSwitch(String dockSn, Integer workMode) {
JSONObject data = new JSONObject();
data.set("link_workmode", workMode);
return djiBaseService.executeAndReturnResult(dockSn, "sdr_workmode_switch", data);
}
@Override
public String batteryStoreModeSwitch(String dockSn, Integer action) {
JSONObject data = new JSONObject();
data.set("action", action);
return djiBaseService.executeAndReturnResult(dockSn, "battery_store_mode_switch", data);
}
@Override
public String alarmStateSwitch(String dockSn, Integer action) {
JSONObject data = new JSONObject();
data.set("action", action);
return djiBaseService.executeAndReturnResult(dockSn, "alarm_state_switch", data);
}
@Override
public String airConditionerModeSwitch(String dockSn, Integer action) {
JSONObject data = new JSONObject();
data.set("action", action);
return djiBaseService.executeAndReturnResult(dockSn, "air_conditioner_mode_switch", data);
}
@Override
public String batteryMaintenanceSwitch(String dockSn, Integer action) {
JSONObject data = new JSONObject();
data.set("action", action);
return djiBaseService.executeAndReturnResult(dockSn, "battery_maintenance_switch", data);
}
@Override
public String rtkCalibration(String dockSn, RtkCalibration rtkCalibration) {
JSONObject data = new JSONObject();
data.set("devices", rtkCalibration.getDevices());
return djiBaseService.executeAndReturnResult(dockSn, "rtk_calibration", data);
}
}