from fastapi import APIRouter, HTTPException, status from app.core.device.manager import device_manager from app.core.dispatcher import dispatcher from app.schemas.plnk import PLNKRequest, PLNKResponse from app.utils.log import get_logger logger = get_logger(__name__) router = APIRouter() @router.post("/devices/{device_id}/send-plnk", response_model=PLNKResponse, summary="发送PLNK协议数据") async def send_plnk_data(device_id: str, plnk_request: PLNKRequest): """向指定设备发送PLNK协议数据""" try: # 检查设备是否存在 device = await device_manager.get_device(device_id) if not device: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"设备 {device_id} 不存在" ) # 检查协议是否为PLNK if device.protocol_type != 'plnk': raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"设备 {device_id} 不是PLNK协议,当前协议: {device.protocol_type}" ) # 发送PLNK数据 result = await dispatcher.execute_operation( device_id=device_id, protocol_type=device.protocol_type, operation="send_plnk_data", data=plnk_request.data, timeout=plnk_request.timeout, wait_response=plnk_request.wait_response ) return result except HTTPException: raise except Exception as e: logger.error(f"PLNK数据发送失败: {device_id}, 错误: {e}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"PLNK数据发送失败: {str(e)}" ) @router.get("/devices/{device_id}/plnk-status", summary="获取PLNK连接状态") async def get_plnk_connection_status(device_id: str): """获取PLNK连接状态""" try: # 检查设备是否存在 device = await device_manager.get_device(device_id) if not device: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"设备 {device_id} 不存在" ) # 检查协议是否为PLNK if device.protocol_type != 'plnk': raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"设备 {device_id} 不是PLNK协议,当前协议: {device.protocol_type}" ) # 获取连接状态 result = await dispatcher.execute_operation( device_id=device_id, protocol_type=device.protocol_type, operation="get_connection_status" ) return result except HTTPException: raise except Exception as e: logger.error(f"获取PLNK连接状态失败: {device_id}, 错误: {e}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"获取PLNK连接状态失败: {str(e)}" ) @router.get("/devices/{device_id}/test-plnk", summary="测试PLNK连接") async def test_plnk_connection(device_id: str): """测试PLNK连接状态""" try: # 检查设备是否存在 device = await device_manager.get_device(device_id) if not device: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"设备 {device_id} 不存在" ) # 检查协议是否为PLNK if device.protocol_type != 'plnk': raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"设备 {device_id} 不是PLNK协议,当前协议: {device.protocol_type}" ) # 测试连接 result = await dispatcher.execute_operation( device_id=device_id, protocol_type=device.protocol_type, operation="test_connection" ) return { "device_id": device_id, "connected": result, "message": "PLNK连接正常" if result else "PLNK连接失败" } except HTTPException: raise except Exception as e: logger.error(f"PLNK连接测试失败: {device_id}, 错误: {e}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"PLNK连接测试失败: {str(e)}" ) @router.post("/devices/{device_id}/send-hex", summary="发送十六进制数据") async def send_hex_data(device_id: str, hex_data: str, timeout: int = 30): """向指定设备发送十六进制数据(通用接口)""" try: # 检查设备是否存在 device = await device_manager.get_device(device_id) if not device: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"设备 {device_id} 不存在" ) # 根据协议类型选择不同的发送方式 if device.protocol_type == 'plnk': result = await dispatcher.execute_operation( device_id=device_id, protocol_type=device.protocol_type, operation="send_plnk_data", data=hex_data, timeout=timeout, wait_response=True ) elif device.protocol_type == 'at': # 对于AT协议,将十六进制转换为ASCII try: ascii_data = bytes.fromhex(hex_data.replace(' ', '')).decode('ascii', errors='ignore') result = await dispatcher.execute_operation( device_id=device_id, protocol_type=device.protocol_type, operation="send_at_command", command=ascii_data, timeout=timeout, wait_response=True ) except ValueError: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="无效的十六进制数据" ) else: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"协议 {device.protocol_type} 不支持十六进制数据发送" ) return result except HTTPException: raise except Exception as e: logger.error(f"十六进制数据发送失败: {device_id}, 错误: {e}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"十六进制数据发送失败: {str(e)}" )