|
|
|
|
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)}"
|
|
|
|
|
)
|