feat(pybot): bot4cj 的 Python 迁移版(.mt 解析 + 硬件驱动 + 插件系统)

- parser: FSM 解析器与仓颉版逐语义对齐,修 S01/S02/S04/Q05
- robot/hardvars: 六类硬件变量工厂,修 r.cj:911 重名 FIXME、Q07 倒序释放
- plugin: Python 插件替代 Lua 桥接,修 S07 三级路径查找
- hd: i2c(每fd锁 Q03/S06)/spi/servo/kalman/mpu6050(S05/Q06)/speaker(S03 实声)
- modules: PCA9685 与 Lua 版逐字节对齐;ADS1115 重写(experimental);ADS1256 空桩
- tests: 42 项 pytest 全绿(Mock 总线 journal 断言)
- CLI: --dry-run / --test roundtrip / --verbose;运行时零第三方依赖
This commit is contained in:
qing committed 2026-08-09 18:57:03 +00:00
1 parent 85eaa2114e
commit bba7ee3eb4
31 files changed
+2155

No files matched your search

+42
View File
@@ -0,0 +1,42 @@
"""SPI 总线插件 —— 与 bot4cj/modules/SPI.lua 逐语义对齐
@SPI 块元数据:name / path / spi_mode / bits / speed / delay
build 打开并配置 spidev;call 返回 {"fd": fd}(供其他块引用展开);
destroy 关闭。模块级全局 _fd 即设备私有状态
(pybot 每设备加载独立模块实例,与 Lua 每设备独立状态机等价)。
"""
import logging
from pybot.hd import spi
log = logging.getLogger("pybot.modules.SPI")
_fd = -1 # 全局文件句柄(对应 SPI.lua 的 fd)
def build(ctx):
global _fd
for key in ("path", "spi_mode", "bits", "speed", "delay"):
if key not in ctx:
return {"result": "ERR", "message": f"Invalid Arguments: {key}"}
log.info("SPI build parameters: %s", ctx)
_fd = spi.open_dev(ctx["path"])
if _fd <= 0:
return {"result": "ERR", "message": "Failed to open SPI file"}
spi.setup(_fd, int(str(ctx["spi_mode"]), 0),
int(ctx["bits"]), int(ctx["speed"]))
return {"result": "OK", "fd": _fd}
def call(ctx):
return {"fd": _fd}
def destroy(ctx):
global _fd
log.info("SPI destroy, fd=%d", _fd)
if _fd > 0:
spi.close_dev(_fd)
_fd = -1
return {"result": "OK"}