使用 meta 的 NEEO 驱动程序
meta (jac459/meta) 是一个 Node.js 引擎,它读取 active/ 文件夹中的 JSON 设备文件,并将每个文件转换为一个 NEEO SDK 驱动程序,注册到本地 NEEO Brain。你用 JSON 描述设备;你不需要编写 JavaScript(除了少量 DYNAMIK 表达式)。
语言:使用用户的语言进行交流。JSON 键、引擎关键字、按钮名称和日志字符串需严格遵循本文档(英文)。
范围:仅涉及收购前的 NEEO SDK、本地 Brain 和 meta。忽略 Control4 相关内容和 NEEO 云服务(已关闭)。
基本原则(切勿跳过)
- 切勿发明 JSON 键或命令类型。 如果某个特性不在参考资料中,请如实告知并提供替代方案:配套服务(Node-RED + MQTT 或本地小型 REST 桥接,参见
references/companion-services.md)、cli命令或隐藏按钮链。 - 纯 JSON:无注释、无尾随逗号、使用双引号。使用
python3 -m json.tool file.json和python3 scripts/check_driver.py file.json进行验证。 - 命令类型区分大小写:
http-get、http-rest、http-post、http-get-soap、static、cli、repl、webSocket、socketIO、jsontcp、mqtt、wol、mDNS、android。 - 每当添加可见组件时,请递增
version。Brain 只会添加组件;重命名或移除组件需要从 NEEO 应用中删除并重新添加设备(食谱和快捷方式必须重做)。即使版本号递增,对于已安装的设备也可能不足够:请检查 Brain(references/debugging.md)。 - 标签、开关、滑块、图像和传感器的名称(键)仅限字母和数字。 空格或符号会破坏传感器链接(Brain 中出现
"sensor": null),并且当该组件用作快捷方式时,遥控器会在同步时崩溃。显示的label文本则没有限制。按钮名称可包含空格,但应避免+和重音符号(例如DISNEY PLUS,标签Disney+)。 - 切勿将
""写入绑定到标签的变量:在 meta v1.2.0 上,标签从文本返回""会导致 meta 停止。请写入" "(或一个可读的备用值)。建议养成习惯,即使初始化标签变量也使用" "。 - 在到达标签之前,对每个外部文本进行净化:
"->',\->/,控制字符 -> 空格,$->$(全角)。在驱动程序中和在源头处同时进行。 - 监听器通过
ListenerOn守卫和每个可见控件中连接隐藏的__LISTEN按钮在每个会话开始时启动。 切勿仅依赖POWER ON,也切勿在mqtt监听器上调用__CLEANUP(references/listeners-and-state.md)。 - 事件优于轮询(
webSocket、socketIO、mqtt)。如果必须轮询,pooltime应 >=3000。 $Result始终是字符串,失败时为"undefined":每个JSON.parse都需要进行防护。按钮获取标量值(ok);目录操作馈送器获取["ok"]。- 变量名称:切勿使用一个名称作为另一个名称的前缀;
$Var后跟字母时会被解读为另一个不同的变量。 - 安全性:
DYNAMIK和cli在 meta 主机上执行代码。不应在打算共享的驱动程序中硬编码机密信息;meta 绝不能以 root/admin 身份运行。 - 不可逆更改需要同意:添加可见组件(例如
DIGIT 0-9)无法在不重新安装设备的情况下撤消。请先征得同意。 - 分开交付物:meta 驱动程序是一个 JSON 对象(以
{开头,名称中不含-flow,放在active/中);Node-RED 流程是一个 JSON 列表(以[开头,始终命名为*-flow.json,导入到 Node-RED 中)。 - 在
template中,dynamicname和dynamicid是必填项;dynamicid必须稳定(使用 MAC 地址或硬件 ID,而非 DHCP IP)。
工作流程
- 收集所需信息(每次最多问 3 个有针对性的问题):确切的设备型号;其控制协议或 API(HTTP/REST、WebSocket、原始 TCP、MQTT、仅 IR、Android TV……);固定 IP 或可变 IP 及稳定 ID(MAC);必须控制的内容和必须显示的状态;meta 版本及 meta 运行位置(使用 pm2 的 Pi、Docker……);是否有 MQTT 代理和 Node-RED。当存在官方 API 文档时,查找该设备的官方 API 文档。
- 选择 NEEO 类型(
references/driver-anatomy.md,类型和已识别按钮部分)和发现模式(references/discovery.md):静态单设备、用户输入 IP、mDNS 或集线器。 - 从
assets/中的骨架开始:skeleton-static.json(一个设备,固定地址)或skeleton-register-ip.json(用户输入 IP)。重用references/patterns.md中经过验证的模式。 - 确定逻辑所在位置。 简单的 HTTP 或 WebSocket 设备:所有逻辑放在驱动程序中。二进制或有状态协议(原始 TCP、持久会话、配对、突发状态):在其间放置配套服务,使用快速的 HTTP 命令,并将状态推送为保留的 MQTT 消息(
references/companion-services.md)。 - 交付前检查:
python3 -m json.tool driver.json然后python3 scripts/check_driver.py driver.json(检查名称、空标签值、类型、版本、守卫、轮询……);- 当驱动程序有监听器时,运行
node scripts/simulate_guard.js driver.json(跨会话计数__INITIALISE/__CLEANUP); - 在 Node 中使用真实的替换规则评估棘手的
DYNAMIK表达式(references/logic-and-commands.md); - 重新阅读
references/pitfalls.md。
- 按以下顺序交付:摘要(设备、协议、NEEO 类型、发现模式、涵盖/未涵盖的内容);完整的已验证 JSON 文件并明确文件名;部署步骤(复制到
active/,重启 meta,在 NEEO 应用中添加设备,创建食谱可见性和快捷方式);测试计划(要尝试的按钮、预期结果、要查找的日志行);未在真实设备上验证的假设;下次迭代。对于多文件项目(驱动程序 + 流程 + 服务):操作顺序、每个交付物中的版本标记以及如何检查已安装的版本。始终说明哪些内容未在真实设备上进行测试。
参考文件映射(仅读取任务所需的内容)
| 文件 | 何时阅读 |
|---|---|
references/meta-engine.md | 架构、安装、文件夹、重启、日志级别、meta 公开的 MQTT 主题、Docker/NAS 托管、已知 meta v1.2.0 缺陷 |
references/driver-anatomy.md | 顶级键、NEEO 设备类型和已识别按钮名称、变量、$ 替换、DYNAMIK、UI 组件 |
references/logic-and-commands.md | evalwrite、evaldo、evalnext、特殊按钮、每种命令类型、queryresult / JSONPath |
references/listeners-and-state.md | 监听器、ListenerOn 守卫、MQTT 监听器行为、突发状态源、实例重建 |
references/discovery.md | discover、register、template、initcommandset、mDNS、IP 输入、集线器、配对 |
references/directories.md | 列表、馈送器、item* 字段、操作、多级导航 |
references/patterns.md | 经过验证的配方:音量、电源、状态栏、持久化、链、循环、回退路径、应用启动器、艺术品图像 |
references/pitfalls.md | 交付前必须重新阅读 |
references/debugging.md | 阅读 meta、Mosquitto 和 Brain 数据、日志特征、隔离链接、沙盒测试 |
references/companion-services.md | Node-RED 和 MQTT 桥接、本地 REST 桥接、Apple TV / pyatv 经验教训 |
references/community-drivers.md | 可供模仿的参考驱动程序、SDK 与 meta 的映射、来源 |
参考资料中使用的证据标签
[code v1.2.0] 从 meta 源代码(Release 分支)中读取;[observed] 在真实驱动程序或真实安装中观察到;[to verify] 尚未测试的推论。当某个行为很重要且没有标签时,请检查 meta 的代码(git clone --depth 1 --branch Release https://github.com/jac459/meta)而非猜测,并说明你采取了哪种方式。