Merge remote-tracking branch 'origin/dev' into dev
3 files added
13 files modified
| | |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation("格式化存储卡") |
| | | @ApiOperationSupport(order = 9) |
| | | @PostMapping("/formatSdCard") |
| | | public AjaxResult formatSdCard(@RequestBody FormatSdCardDTO formatSdCardDTO) { |
| | | tyService.formatSdCard(formatSdCardDTO); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | @ApiOperation(value = "打开或关闭照片回传", notes = "actionParam值:0-关闭,1-打开") |
| | | @ApiOperationSupport(order = 10) |
| | | @PostMapping("/photoReturnToggle") |
| | |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | log.debug("定时同步Vtdu任务"); |
| | | List<ArdChannel> channels = this.selectArdChannelList(new ArdChannel()); |
| | | if (channels == null || channels.isEmpty()) { |
| | | log.warn("没有获取到通道数据,退出同步"); |
| | | // log.warn("没有获取到通道数据,退出同步"); |
| | | return; |
| | | } |
| | | List<ArdVtdu> ardVtduList = ardVtduService.selectArdVtduList(new ArdVtdu()); |
| | |
| | | eventPublisher.publishEvent(loginEvent); |
| | | log.warn("设备[{}:{}]登录失败: {}({})", camera.getIp(), camera.getPort(), |
| | | SdkErrorCodeEnum.getDescByCode(errorCode), errorCode); |
| | | return; |
| | | } |
| | | log.info("Login Success 【 {}:{} 】", camera.getIp(), camera.getPort()); |
| | | |
| | |
| | | <if test="longitude != null">longitude = #{longitude},</if> |
| | | <if test="latitude != null">latitude = #{latitude},</if> |
| | | <if test="altitude != null">altitude = #{altitude},</if> |
| | | <if test="dockId != null">dock_id = #{dockId},</if> |
| | | <!-- 简洁写法:直接设置值,包括null --> |
| | | dock_id = #{dockId}, |
| | | <if test="loginId != null">login_id = #{loginId},</if> |
| | | <if test="deptId != null">dept_id = #{deptId},</if> |
| | | <if test="userId != null">user_id = #{userId},</if> |
| | |
| | | } catch (IOException | ClassNotFoundException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | // 1.2通过minio获取航线信息 |
| | | |
| | | // 2.将航线信息转换成对应实体类 |
| | | WayLineUploadDTO wayLineUploadDTO = buildWayLineUploadDTO(route); |
| | | wayLineUploadDTO.setBoxSn(boxSn); |
| | | // 3.调用接口 |
| | | tyService.wayLineUpload(wayLineUploadDTO); |
| | | return true; |
| | |
| | | // ardRouteActions2.setType(1); |
| | | // ardRouteActions2.setWaitTime(2); |
| | | // } |
| | | |
| | | public byte[] testParameters() { |
| | | String data = "74 79 01 3C 44 42 4D 32 35 30 39 37 34 30 36 35 30 30 38 D1 00 10 08 01 15 00 00 70 41 1D 00 00 00 41 22 4A 09 06 9C E7 80 8B F0 59 40 11 08 98 33 BA 07 1D 3F 40 1D 00 00 F0 41 25 00 00 00 41 2A 09 08 01 15 00 00 20 41 18 02 2A 09 08 03 15 00 00 80 3F 18 02 2A 09 08 04 15 00 00 80 3F 18 02 30 01 58 FF FF FF FF FF FF FF FF FF 01 22 55 09 F1 BC 12 50 7A F0 59 40 11 08 98 33 BA 07 1D 3F 40 1D 00 00 20 42 25 00 00 00 41 2A 09 08 09 15 00 00 A0 41 18 02 2A 09 08 06 15 00 00 20 42 18 02 2A 09 08 07 15 00 00 20 42 18 02 2A 09 08 08 15 00 00 20 42 18 02 30 01 58 FF FF FF FF FF FF FF FF FF 01 22 3F 09 F1 BC 12 50 7A F0 59 40 11 91 92 E4 DA CC 1C 3F 40 1D 00 00 48 42 25 00 00 00 41 2A 09 08 09 15 00 00 70 41 18 02 2A 09 08 0A 15 00 00 40 40 18 02 30 01 58 FF FF FF FF FF FF FF FF FF 01 22 34 09 06 9C E7 80 8B F0 59 40 11 91 92 E4 DA CC 1C 3F 40 1D 00 00 70 42 25 00 00 00 41 2A 09 08 02 15 00 00 80 3F 18 02 30 01 58 FF FF FF FF FF FF FF FF FF 01 30 32 70 32"; |
| | | String[] hexStrings = data.split(" "); |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append("byte[] encodedBytes = {"); |
| | | for (int i = 0; i < hexStrings.length; i++) { |
| | | sb.append("(byte) 0x").append(hexStrings[i]); |
| | | if (i < hexStrings.length - 1) { |
| | | sb.append(", "); |
| | | } |
| | | } |
| | | sb.append("};"); |
| | | return sb.toString().getBytes(); |
| | | } |
| | | } |
| | |
| | | return null; |
| | | } |
| | | |
| | | public static String getMachineCode() { |
| | | public static String getMachineCode1() { |
| | | StringBuffer sb = new StringBuffer(); |
| | | try { |
| | | InetAddress ia = InetAddress.getLocalHost(); |
| | |
| | | log.debug("机器码:"+code); |
| | | return code; |
| | | } |
| | | public static String getMachineCode() { |
| | | try { |
| | | Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); |
| | | while (interfaces.hasMoreElements()) { |
| | | NetworkInterface nif = interfaces.nextElement(); |
| | | |
| | | // 跳过回环、虚拟、未启动网卡 |
| | | if (nif.isLoopback() || nif.isVirtual() || !nif.isUp()) { |
| | | continue; |
| | | } |
| | | |
| | | // 可选:跳过 idrac 管理网卡 |
| | | if (nif.getName().toLowerCase().contains("idrac")) { |
| | | continue; |
| | | } |
| | | |
| | | byte[] mac = nif.getHardwareAddress(); |
| | | if (mac == null || mac.length == 0) { |
| | | continue; |
| | | } |
| | | |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (int i = 0; i < mac.length; i++) { |
| | | if (i != 0) sb.append("-"); |
| | | sb.append(String.format("%02X", mac[i])); |
| | | } |
| | | |
| | | String macStr = sb.toString(); |
| | | log.debug("物理网卡: " + nif.getName() + " MAC: " + macStr); |
| | | |
| | | // 返回 MAC 的 MD5 作为机器码 |
| | | String code = Md5Utils.hash(macStr); |
| | | log.debug("机器码: " + code); |
| | | return code; |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("获取机器码异常: " + e.getMessage(), e); |
| | | } |
| | | |
| | | // 找不到 MAC 返回 null |
| | | return null; |
| | | } |
| | | |
| | | public static String getCPUCode() { |
| | | String serial = null; |
| | |
| | | } |
| | | // 检查在线状态 |
| | | if (checkDroneStatus.checkOnline()) { |
| | | Boolean online = redisCache.getCacheObject(CacheConstants.UAV_ONLINE_KEY + boxSn); |
| | | if (online == null || !online) { |
| | | // 3️⃣ 检查在线状态 |
| | | BoxInfoReceiver obj = redisCache.getCacheObject(CacheConstants.UAV_ONLINE_KEY + boxSn); |
| | | if (obj == null || !obj.getOnLine().equals(1)) { |
| | | throw new ControlException("无人机离线,无法执行操作!boxSn: " + boxSn); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.work.component.netty.command.camera; |
| | | |
| | | import com.ard.work.component.netty.command.BaseCmd; |
| | | import com.ard.work.domain.dto.camera.FormatSdCardDTO; |
| | | import io.netty.buffer.ByteBuf; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * Description: 格式化存储卡指令 |
| | | * Author: lsy |
| | | * Date: 2025年11月24日9:31 |
| | | **/ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = false) |
| | | public class FormatSdCardCmd extends BaseCmd { |
| | | private final byte encryptFlag = 0x00; // 加密标志 |
| | | private final byte actionCode = 0x40; // 动作编号 |
| | | |
| | | public FormatSdCardCmd(FormatSdCardDTO formatSdCardDTO) { |
| | | setDataHeader((short) 0x7479); |
| | | setDataLength((short) 18); |
| | | setBoxSn(formatSdCardDTO.getBoxSn().getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | } |
| | | @Override |
| | | public void encode(ByteBuf out) { |
| | | out.writeShort(getDataHeader()); // 写入数据头 |
| | | out.writeShort(getDataLength()); // 写入数据长度 |
| | | out.writeBytes(getBoxSn()); // 写入盒子SN |
| | | out.writeByte(getCmdCode()); // 写入命令码 |
| | | out.writeByte(encryptFlag); // 写入加密标志 |
| | | out.writeByte(actionCode); // 写入动作编号 |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.work.component.netty.command.camera; |
| | | |
| | | import com.ard.work.component.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * Description: 格式化存储卡回复指令 |
| | | * Author: lsy |
| | | * Date: 2025年11月24日9:31 |
| | | **/ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = false) |
| | | public class FormatSdCardReplyCmd extends BaseCmd { |
| | | private final byte result; // 执行结果 |
| | | private final Integer errorCode; // 错误码 |
| | | public FormatSdCardReplyCmd(String boxSn, Byte result, Integer errorCode) { |
| | | setDataHeader((short) 0x6A77); |
| | | setDataLength((short) 20); |
| | | setBoxSn(boxSn.getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | this.result = result; |
| | | this.errorCode = errorCode; |
| | | } |
| | | @Override |
| | | public void encode(ByteBuf out) { |
| | | |
| | | } |
| | | } |
| | |
| | | package com.ard.work.component.netty.handler;// MessageProtocolDecoder.java |
| | | |
| | | import com.ard.common.utils.ByteUtils; |
| | | import com.ard.work.component.netty.command.camera.*; |
| | | import com.ard.work.component.netty.command.manual.*; |
| | | import com.ard.work.component.netty.command.wayline.*; |
| | | import com.ard.work.domain.dto.converter.realdata.UavSignalInfoConverter; |
| | |
| | | import com.ard.work.domain.dto.state.UavState; |
| | | import com.ard.work.domain.dto.telemetry.TelemetryData; |
| | | import com.ard.work.component.netty.command.BaseCmd; |
| | | import com.ard.work.component.netty.command.camera.CameraModeReplyCmd; |
| | | import com.ard.work.component.netty.command.camera.CapturePicReplyCmd; |
| | | import com.ard.work.component.netty.command.camera.RecordStartReplyCmd; |
| | | import com.ard.work.component.netty.command.camera.RecordStopReplyCmd; |
| | | import com.ard.work.component.netty.command.notice.BoxPowerStatusReplyCmd; |
| | | import com.ard.work.component.netty.command.notice.FlyWayEndReplyCmd; |
| | | import com.ard.work.component.netty.command.camera.PicUploadCompletedReplyCmd; |
| | | import com.ard.work.component.netty.command.notice.UavReadyReplyCmd; |
| | | import com.ard.work.component.netty.command.real.SignalInfoCmd; |
| | | import com.ard.work.component.netty.command.real.UavStateCmd; |
| | |
| | | return new FlyWayEndReplyCmd(boxSn, result, errorCode); |
| | | // Special cases |
| | | case 0x3D: |
| | | case 0x40: |
| | | return new FormatSdCardReplyCmd(boxSn, result, errorCode); |
| | | case 0x42: |
| | | return processSpecialD1ReplyCmd(in, actionCode, boxSn); |
| | | // Add other cases... |
| | |
| | | import io.netty.handler.codec.MessageToByteEncoder; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | @Slf4j |
| | | public class MessageProtocolEncoder extends MessageToByteEncoder<BaseCmd> { |
| | | @Override |
| | |
| | | // 打印编码后的字节数组 |
| | | byte[] encodedBytes = new byte[out.readableBytes()]; // 创建字节数组,大小为可读字节数 |
| | | out.getBytes(out.readerIndex(), encodedBytes); // 读取ByteBuf中的字节到字节数组中 |
| | | // log.warn("Encoded message bytes: {}", Arrays.toString(encodedBytes)); |
| | | // 将字节数组转换为十六进制格式 |
| | | String hexString = ByteUtils.bytesToHexWithSpaces(encodedBytes); |
| | | log.debug("Encoded message in hex: {}", hexString); |
| | | log.warn("Encoded message in hex: {}", hexString); |
| | | } |
| | | |
| | | public byte[] testParameters() { |
| | | String data = "74 79 01 3C 44 42 4D 32 35 30 39 37 34 30 36 35 30 30 38 D1 00 10 08 01 15 00 00 70 41 1D 00 00 00 41 22 4A 09 06 9C E7 80 8B F0 59 40 11 08 98 33 BA 07 1D 3F 40 1D 00 00 F0 41 25 00 00 00 41 2A 09 08 01 15 00 00 20 41 18 02 2A 09 08 03 15 00 00 80 3F 18 02 2A 09 08 04 15 00 00 80 3F 18 02 30 01 58 FF FF FF FF FF FF FF FF FF 01 22 55 09 F1 BC 12 50 7A F0 59 40 11 08 98 33 BA 07 1D 3F 40 1D 00 00 20 42 25 00 00 00 41 2A 09 08 09 15 00 00 A0 41 18 02 2A 09 08 06 15 00 00 20 42 18 02 2A 09 08 07 15 00 00 20 42 18 02 2A 09 08 08 15 00 00 20 42 18 02 30 01 58 FF FF FF FF FF FF FF FF FF 01 22 3F 09 F1 BC 12 50 7A F0 59 40 11 91 92 E4 DA CC 1C 3F 40 1D 00 00 48 42 25 00 00 00 41 2A 09 08 09 15 00 00 70 41 18 02 2A 09 08 0A 15 00 00 40 40 18 02 30 01 58 FF FF FF FF FF FF FF FF FF 01 22 34 09 06 9C E7 80 8B F0 59 40 11 91 92 E4 DA CC 1C 3F 40 1D 00 00 70 42 25 00 00 00 41 2A 09 08 02 15 00 00 80 3F 18 02 30 01 58 FF FF FF FF FF FF FF FF FF 01 30 32 70 32"; |
| | | String[] hexStrings = data.split(" "); |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append("byte[] encodedBytes = {"); |
| | | for (int i = 0; i < hexStrings.length; i++) { |
| | | sb.append("(byte) 0x").append(hexStrings[i]); |
| | | if (i < hexStrings.length - 1) { |
| | | sb.append(", "); |
| | | } |
| | | } |
| | | sb.append("};"); |
| | | return sb.toString().getBytes(); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.work.domain.dto.camera; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * Description: 格式化存储卡实体对象 |
| | | * Author: lsy |
| | | * Date: 2025年11月24日9:39 |
| | | **/ |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class FormatSdCardDTO { |
| | | private String boxSn; |
| | | } |
| | |
| | | Boolean speedControl(SpeedControlDTO speedControlDto); |
| | | |
| | | /** |
| | | * 格式化存储卡 |
| | | */ |
| | | Boolean formatSdCard(FormatSdCardDTO formatSdCardDTO); |
| | | |
| | | /** |
| | | * 设置相机模式 |
| | | */ |
| | | Boolean updateCameraMode(CameraModeDTO cameraModeDTO); |
| | |
| | | // 只有在线的无人机才存 Redis |
| | | String redisKey = CacheConstants.UAV_ONLINE_KEY + boxSn; |
| | | if (remote.getOnLine() == 1) { |
| | | redisCache.setCacheObject(redisKey, remote, 10, TimeUnit.SECONDS); |
| | | redisCache.setCacheObject(redisKey, remote, 30, TimeUnit.SECONDS); |
| | | } else { |
| | | redisCache.deleteObject(CacheConstants.UAV_ONLINE_KEY + boxSn); |
| | | } |
| | |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean formatSdCard(FormatSdCardDTO formatSdCardDTO) { |
| | | String boxSn = formatSdCardDTO.getBoxSn(); |
| | | ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn); |
| | | if (ardDroneInfo == null) { |
| | | throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn); |
| | | } |
| | | FormatSdCardCmd formatSdCardCmd = new FormatSdCardCmd(formatSdCardDTO); |
| | | this.sendMessage(ardDroneInfo.getServerId(), formatSdCardCmd); |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 设置相机模式 |
| | | */ |
| | |
| | | throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn); |
| | | } |
| | | //wayLineUploadDTO.setWayLineData(this.CreatePlanLineData());//设置航线数据 |
| | | System.out.println("wayLineUploadDTO:-----------------" + wayLineUploadDTO); |
| | | WayLineUploadCmd wayLineUploadCmd = new WayLineUploadCmd(wayLineUploadDTO); |
| | | System.out.println("wayLineUploadCmd:-----------------" + wayLineUploadCmd); |
| | | this.sendMessage(ardDroneInfo.getServerId(), wayLineUploadCmd); |
| | | return true; |
| | | } |
| | |
| | | FlyWayEndReplyCmd flyWayEndReplyCmd = (FlyWayEndReplyCmd) tyCommand; |
| | | logPrint("无人机飞行结束", flyWayEndReplyCmd.getResult(), flyWayEndReplyCmd.getErrorCode()); |
| | | } |
| | | //格式化存储卡 |
| | | if (tyCommand instanceof FormatSdCardReplyCmd) { |
| | | FormatSdCardReplyCmd formatSdCardReplyCmd = (FormatSdCardReplyCmd) tyCommand; |
| | | logPrint("格式化存储卡", formatSdCardReplyCmd.getResult(), formatSdCardReplyCmd.getErrorCode()); |
| | | } |
| | | if (tyCommand instanceof CapturePicReplyCmd) { |
| | | CapturePicReplyCmd capturePicReplyCommand = (CapturePicReplyCmd) tyCommand; |
| | | logPrint("无人机拍照", capturePicReplyCommand.getResult(), capturePicReplyCommand.getErrorCode()); |