Files
tcad-bodeplot/dea/mcu.py
T

74 lines
2.0 KiB
Python
Executable File

import re
from fastapi import HTTPException
from .config import MCU_BAUD_RATE, MCU_SERIAL_PORT, MCU_WRITE_TIMEOUT
from .schemas import MCUWriteParams
MCU_CMD_PATTERN = re.compile(r"^bodeplot=-?\d+,-?\d+,-?\d+,-?\d+,-?\d+$")
def _serial_module():
try:
import serial
except ImportError as exc:
raise HTTPException(status_code=500, detail="MCU 串口功能需要安裝 pyserial") from exc
return serial
def write_mcu_command_response(params: MCUWriteParams):
cmd = params.command.strip()
if not MCU_CMD_PATTERN.fullmatch(cmd):
raise HTTPException(status_code=400, detail="MCU 指令格式錯誤")
target_port = (params.port or MCU_SERIAL_PORT).strip()
if not target_port:
raise HTTPException(status_code=400, detail="MCU 串口不可為空")
serial = _serial_module()
payload = (cmd + "\r\n").encode("ascii", errors="strict")
try:
with serial.Serial(
port=target_port,
baudrate=MCU_BAUD_RATE,
timeout=MCU_WRITE_TIMEOUT,
write_timeout=MCU_WRITE_TIMEOUT,
) as ser:
written = ser.write(payload)
ser.flush()
except serial.SerialException as exc:
raise HTTPException(status_code=500, detail=f"MCU 串口傳送失敗: {str(exc)}") from exc
return {
"status": "ok",
"command": cmd,
"port": target_port,
"baudrate": MCU_BAUD_RATE,
"bytes_written": int(written),
}
def list_mcu_ports_response():
_serial_module()
try:
from serial.tools import list_ports
except ImportError as exc:
raise HTTPException(status_code=500, detail="MCU 串口清單功能需要安裝 pyserial") from exc
ports = [
{
"device": port.device,
"description": port.description or "",
"hwid": port.hwid or "",
}
for port in list_ports.comports()
]
return {
"default_port": MCU_SERIAL_PORT,
"baudrate": MCU_BAUD_RATE,
"ports": ports,
}