121 lines
3.9 KiB
Markdown
121 lines
3.9 KiB
Markdown
# miot_x
|
||
|
||
`miot_x` 是一个基于 Bun + TypeScript 的米家极客版工作流编排实验项目。目标是用 TypeScript 代码描述简单工作流,再编译、校验并打包成米家极客版可导入的 `.bak` 备份文件。
|
||
|
||
## 当前范围
|
||
|
||
第一版只验证“编程化开发工作流”的可行性,不做纯文本 DSL,也不做完整 MIoT 元数据智能解析。
|
||
|
||
当前支持:
|
||
|
||
- 设备属性触发和事件触发,生成 `deviceInput`
|
||
- 设备属性读取条件,生成 `deviceGet`
|
||
- 设备属性写入和动作调用,生成 `deviceOutput`
|
||
- 多触发合并,生成 `signalOr`
|
||
- 简单逻辑组合,生成 `logicAnd`、`logicOr`、`logicNot`
|
||
- 延时动作,生成 `delay`
|
||
- 注释节点,生成 `nop`
|
||
- `.bak` 解包、打包、合并和校验
|
||
|
||
当前不支持:
|
||
|
||
- 纯文本 DSL 或自定义 parser
|
||
- 中文能力名自动匹配,例如 `light.power.on()`
|
||
- 主动连接中枢网关或复现 websocket 会话
|
||
- 自动删除旧规则、旧变量或自动清理孤儿变量
|
||
- 完整覆盖米家极客版所有节点类型
|
||
|
||
## 项目结构
|
||
|
||
```text
|
||
src/
|
||
index.ts # public API
|
||
builder.ts # TypeScript 规则 builder
|
||
graph.ts # Graph IR 与节点 ID
|
||
nodes.ts # 米家节点模板
|
||
compiler.ts # 规则编译与备份合并
|
||
validate.ts # 结构、连接、设备和能力参数校验
|
||
backup.ts # .bak 解包与打包
|
||
cli.ts # 命令入口
|
||
examples/rules/
|
||
index.ts # 最小规则示例
|
||
*.test.ts # Bun 测试
|
||
resources/
|
||
devices.json # 设备清单
|
||
*.bak # 真实备份样本
|
||
```
|
||
|
||
## 编写规则
|
||
|
||
规则直接使用 TypeScript:
|
||
|
||
```ts
|
||
import { defineDevices, defineRule } from "../../src/index.ts";
|
||
|
||
const devices = defineDevices({
|
||
corridorLight: {
|
||
did: "group.1815373077765824512",
|
||
urn: "urn:miot-spec-v2:device:light:0000A001:mijia-group3:3:0000C802",
|
||
name: "走廊筒灯",
|
||
},
|
||
corridorMotion: {
|
||
did: "blt.3.1htiptpdgco00",
|
||
urn: "urn:miot-spec-v2:device:motion-sensor:0000A014:xiaomi-pir1:2",
|
||
name: "走廊人体传感器",
|
||
},
|
||
});
|
||
|
||
export default defineRule("走廊有人开灯", ({ device, on }) =>
|
||
on(device(devices.corridorMotion).event({ siid: 2, eiid: 1008 }))
|
||
.do(device(devices.corridorLight).set({ siid: 2, piid: 1, value: true })),
|
||
);
|
||
```
|
||
|
||
第一版要求显式填写 `did`、`urn`、`siid`、`piid`、`eiid`、`aiid` 等 MIoT 参数。后续可以在此基础上增加语义别名。
|
||
|
||
## 打包命令
|
||
|
||
预览编译结果,不写出文件:
|
||
|
||
```bash
|
||
bun run pack -- --rules examples/rules/index.ts --devices resources/devices.json --input "resources/备份2026_4_26 19_17_42.bak" --dry-run
|
||
```
|
||
|
||
输出新的 `.bak` 文件:
|
||
|
||
```bash
|
||
bun run pack -- --rules examples/rules/index.ts --devices resources/devices.json --input "resources/备份2026_4_26 19_17_42.bak" --output dist/miot.bak
|
||
```
|
||
|
||
默认策略是追加新规则。显式替换可使用:
|
||
|
||
```bash
|
||
bun run pack -- --rules examples/rules/index.ts --input old.bak --output new.bak --replace-id 1728570847554
|
||
bun run pack -- --rules examples/rules/index.ts --input old.bak --output new.bak --replace-name 走廊开关灯
|
||
```
|
||
|
||
## 校验策略
|
||
|
||
工具在写出最终 `.bak` 前会检查:
|
||
|
||
- 顶层 `version`、`rules`、`variables.global`
|
||
- 规则 `id` 与 `cfg.id`
|
||
- 节点 `id/type/props/inputs/outputs/cfg`
|
||
- 节点 ID 是否只包含 `0-9a-zA-Z`
|
||
- 连接是否为 `目标节点ID.目标端口名`
|
||
- 连接目标节点和端口是否存在
|
||
- 设备 `did` 是否存在于 `devices.json`
|
||
- `deviceInput`、`deviceGet`、`deviceOutput` 的基础字段和操作符约束
|
||
|
||
## 测试
|
||
|
||
```bash
|
||
bun test
|
||
```
|
||
|
||
测试覆盖真实备份解包统计、备份打包往返、规则编译输出、备份合并和常见校验错误。
|
||
|
||
## 导入验证建议
|
||
|
||
先使用示例规则生成一个新备份文件,在米家极客版中导入并确认画布可以打开。确认简单规则能运行后,再对真实工作流进行替换。原始备份文件应始终保留,便于导入失败时回退。
|