| | |
| | | |
| | | import com.ard.tianyu.config.TyConfiguration; |
| | | import com.ard.tianyu.http.TyClient; |
| | | import com.ard.tianyu.model.receiver.AccessTokenReceiver; |
| | | import com.ard.tianyu.model.receiver.BoxReceiver; |
| | | import com.ard.tianyu.model.receiver.TyHttpCommonReceiver; |
| | | import com.ard.tianyu.model.dto.BoxHistoryDTO; |
| | | import com.ard.tianyu.model.dto.BoxPhotosDTO; |
| | | import com.ard.tianyu.model.dto.BoxSettingsDTO; |
| | | import com.ard.tianyu.model.receiver.*; |
| | | import com.ard.tianyu.netty.command.*; |
| | | import com.ard.tianyu.netty.TyNettyTcpClient; |
| | | import com.ard.tianyu.service.ITyService; |
| | | import io.netty.buffer.ByteBuf; |
| | | import io.netty.buffer.Unpooled; |
| | | import io.netty.channel.Channel; |
| | | import io.netty.channel.ChannelFuture; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.Collections; |
| | | import java.net.InetSocketAddress; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | * @author liusuyi |
| | | * @date 2024年10月22日8:37 |
| | | **/ |
| | | @Slf4j |
| | | @Service |
| | | public class TyServiceImpl implements ITyService { |
| | | |
| | | @Resource |
| | | private TyClient tyClient; |
| | | |
| | | @Resource |
| | | private TyConfiguration tyConfiguration; |
| | | |
| | | |
| | | /** |
| | | * 获取天宇token信息 |
| | | * |
| | | * @return AccessTokenReceiver |
| | | */ |
| | | @Override |
| | | public AccessTokenReceiver getAccessToken() { |
| | | return tyConfiguration.getAccessToken(); |
| | | } |
| | | |
| | | /** |
| | | * 获取云盒列表 |
| | | * |
| | | * @return List<BoxInfoReceiver> |
| | | */ |
| | | @Override |
| | | public List<BoxReceiver> getBoxList() { |
| | | public List<BoxInfoReceiver> getBoxList() { |
| | | //请求云盒列表 |
| | | TyHttpCommonReceiver<List<BoxReceiver>> boxListReveiver = tyClient.getBoxList(tyConfiguration.getAccessToken().convertFromDTO()); |
| | | return boxListReveiver.getContent(); |
| | | try { |
| | | TyHttpCommonReceiver<List<BoxInfoReceiver>> boxListReveiver = tyClient.getBoxList(tyConfiguration.getAccessToken().convertFromDTO()); |
| | | return boxListReveiver.getContent(); |
| | | } catch (Exception e) { |
| | | log.error("获取云盒列表失败:{}", e.getMessage()); |
| | | return new ArrayList<>(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取直播地址 |
| | | * |
| | | * @return BoxStreamUrlReceiver |
| | | */ |
| | | @Override |
| | | public BoxStreamUrlReceiver getBoxLiveUrl(String boxSn) { |
| | | |
| | | TyHttpCommonReceiver<BoxStreamUrlReceiver> boxLiveUrl = tyClient.getBoxLiveUrl(boxSn, tyConfiguration.getAccessToken().convertFromDTO()); |
| | | return boxLiveUrl.getContent(); |
| | | } |
| | | |
| | | /** |
| | | * 获取飞行历史 |
| | | * |
| | | * @return List<BoxHistoryReceiver> |
| | | */ |
| | | @Override |
| | | public List<BoxHistoryReceiver> getBoxHistory(BoxHistoryDTO boxHistoryDTO) { |
| | | TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(boxHistoryDTO, tyConfiguration.getAccessToken().convertFromDTO()); |
| | | return boxHistory.getContent(); |
| | | } |
| | | |
| | | /** |
| | | * 获取盒子图片 |
| | | * |
| | | * @return List<BoxPhotosReceiver> |
| | | */ |
| | | @Override |
| | | public List<BoxPhotosReceiver> getBoxPhotos(BoxPhotosDTO boxPhotosDTO) { |
| | | TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(boxPhotosDTO, tyConfiguration.getAccessToken().convertFromDTO()); |
| | | return boxPhotos.getContent(); |
| | | } |
| | | |
| | | /** |
| | | * 修改云盒设置 |
| | | */ |
| | | @Override |
| | | public Boolean updateBoxSettings(BoxSettingsDTO boxSettingsDTO) { |
| | | TyHttpCommonReceiver<?> result = tyClient.updateBoxSettings(boxSettingsDTO, tyConfiguration.getAccessToken().convertFromDTO()); |
| | | return result.getState() == 1; |
| | | } |
| | | |
| | | /** |
| | | * 注册天宇平台 |
| | | */ |
| | | @Override |
| | | public void registerMessage() { |
| | | AccessTokenReceiver tyToken = tyConfiguration.getAccessToken(); |
| | | RegisterCommand registerMessage = new RegisterCommand(tyToken.getCompanyId(), tyToken.getAccessToken().getBytes()); |
| | | this.sendMessage(tyConfiguration.getIpPort(), registerMessage); |
| | | } |
| | | |
| | | /** |
| | | * 无人机控制订阅 |
| | | */ |
| | | public void uavControlSubscribe(String boxSn) { |
| | | SubscribeCommand subscribeCommand = new SubscribeCommand(boxSn); |
| | | this.sendMessage(tyConfiguration.getIpPort(), subscribeCommand); |
| | | } |
| | | |
| | | /** |
| | | * 发送消息 |
| | | */ |
| | | public void sendMessage(String key, BaseCommand msg) { |
| | | try { |
| | | ChannelFuture future = TyNettyTcpClient.channels.get(key).getChannelFuture(); |
| | | Channel channel = future.channel(); |
| | | if (channel.isActive()) { |
| | | InetSocketAddress ipSocket = (InetSocketAddress) channel.remoteAddress(); |
| | | String host = ipSocket.getHostString(); |
| | | int port = ipSocket.getPort(); |
| | | // 创建 ByteBuf 并编码消息 |
| | | ByteBuf buffer = Unpooled.buffer(); |
| | | msg.encode(buffer); // 确保对消息进行编码 |
| | | channel.writeAndFlush(buffer); // 发送编码后的数据 |
| | | log.debug("向天宇服务器【{}:{}】发送数据,命令码:{}", host, port, String.format("0x%02X", msg.getCmdCode() & 0xFF)); |
| | | } else { |
| | | log.error("与天宇服务器链接断开,无法发送数据!"); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("发送消息异常:{}", e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 云台控制基于角度 |
| | | */ |
| | | @Override |
| | | public void controlAngle(String boxSn) { |
| | | ControlAngleCommand controlAngleCommand = new ControlAngleCommand(boxSn.getBytes(), (byte) 0x00, (byte) 0x00, (byte) 0x05); |
| | | this.sendMessage(tyConfiguration.getIpPort(), controlAngleCommand); |
| | | } |
| | | |
| | | @Override |
| | | public void processMessage(String key, BaseCommand tyCommand) { |
| | | byte cmdCode = tyCommand.getCmdCode(); |
| | | switch (cmdCode) { |
| | | case 0x01: |
| | | // 处理心跳消息 |
| | | RegisterReplyCommand registerReplyCommand = (RegisterReplyCommand) tyCommand; |
| | | log.info("收到注册消息-->处理注册消息{}", registerReplyCommand.getSuccess()); |
| | | if (registerReplyCommand.getSuccess() != 1) { |
| | | // 注册失败,重新注册 |
| | | log.info("注册失败,重新注册"); |
| | | registerMessage(); |
| | | } |
| | | break; |
| | | case 0x02: |
| | | // 处理注册消息 |
| | | HeartbeatReplyCommand heartbeatReplyCommand = (HeartbeatReplyCommand) tyCommand; |
| | | log.info("收到心跳消息-->处理心跳消息{}", heartbeatReplyCommand.getTimestamp()); |
| | | break; |
| | | case 0x03: |
| | | // 处理订阅消息 |
| | | SubscribeCommand subscribeCommand = (SubscribeCommand) tyCommand; |
| | | log.info("收到订阅消息-->处理订阅消息{}", subscribeCommand.getBoxSn()); |
| | | break; |
| | | case 0x04: |
| | | // 处理取消订阅消息 |
| | | subscribeCommand = (SubscribeCommand) tyCommand; |
| | | log.info("收到取消订阅消息-->处理取消订阅消息{}", subscribeCommand.getBoxSn()); |
| | | break; |
| | | case (byte) 0xA8: |
| | | // 处理无人机状态消息 |
| | | log.info("收到无人机状态消息-->无人机状态消息"); |
| | | break; |
| | | case (byte) 0xA9: |
| | | // 处理无人机遥测消息 |
| | | log.info("收到无人机遥测消息-->无人机遥测消息"); |
| | | break; |
| | | default: |
| | | // 处理其他消息 |
| | | } |
| | | } |
| | | |
| | | @Scheduled(fixedRate = 5000) |
| | | public void sendHeartBeat() { |
| | | long timestamp = System.currentTimeMillis(); |
| | | log.debug("定时向天宇发送⼼跳,时间戳{}", timestamp); |
| | | HeartbeatCommand heartbeatMessage = new HeartbeatCommand(timestamp); |
| | | this.sendMessage(tyConfiguration.getIpPort(), heartbeatMessage); |
| | | } |
| | | } |