变量与动作¶
最后更新:
变量¶
EvccApi 与自动化、Lua 共用 EVCC 的进程级变量状态。读取变量不会为了 API 调用启动整套自动化引擎。
| 方法 | 行为 |
|---|---|
queryVariables() |
返回当前可见的自定义变量和内置变量 |
readVariable(name) |
读取一个变量 |
replaceVariableSubscriptions(names) |
原子替换监听集合 |
writeVariable(request) |
写入或预检查一个可写变量 |
deleteVariable(name) |
删除一个可删除变量 |
变量名必须匹配 [A-Za-z_][A-Za-z0-9_]{0,127};内置只读变量不能写入或删除。变量记录通过
mutable 明确这一点。值使用 EvccValue,不要在客户端把所有类型都强行转为数字。
公开 API 额外实施持久化资源配额:最多 512 个用户变量、用户变量名称和值合计最多 2 MiB、同一 UID 每分钟最多写入或删除 120 次。单值仍受 16 KiB 字符和 64 KiB UTF-8 数据双重上限约束。自动化或 Lua 已有数据不会被 API 自动删除;如果历史数据已经超过公开配额,EvccApi 只允许更新为不增大占用的值。 这些限制用于防止第三方持续写入拖慢 EVCC 启动或耗尽私有存储,高频状态应保存在第三方自身进程中。
client.replaceVariableSubscriptions(listOf("power_state", "my_mode"))
client.writeVariable(
EvccVariableWriteRequest(
requestId = UUID.randomUUID().toString(),
name = "my_mode",
value = EvccValue.ofString("eco"),
validateOnly = false,
)
)
内置变量¶
queryVariables() 与按名读取都会包含当前公开的内置变量,这一点与 Lua 的 var.list() 只列自定义
变量不同。当前内置名称全部只读:
- 时间:
time、date、datetime、timestamp、hour、minute。 - 定位:
gps_available、gps_lat、gps_lng、gps_lon、gps_long、gps_altitude、gps_accuracy、gps_speed、gps_bearing、gps_provider、gps_time、gps_age_ms、latitude、longitude。 - 音乐:
bpm、music_state。
只有应用把某个内置名称放进 replaceVariableSubscriptions() 时,EvccApi 才维护该会话的动态监听。
时间和最近定位值按约 1 秒检查一次,相同值不会重复回调,因此它不是高精度时钟或主动 GPS 采样 API;
定位变量读取系统已有的最近位置,不会替第三方开启持续定位。音乐变量会跟随共享变量运行时的变化,并
同样以初始快照建立基线。
动作¶
executeAction(EvccActionRequest) 使用稳定动作 ID 和 JSON 参数:
val check = client.executeAction(
EvccActionRequest(
requestId = UUID.randomUUID().toString(),
actionId = "...",
argumentsJson = "{}",
validateOnly = true,
)
)
- 先通过
queryCapabilities()判断当前版本、车型和权限是否支持对应能力。 validateOnly只校验权限、动作存在性和参数,不执行车辆控制。- 安全动作需要
action.safe,高权限动作需要action.privileged;系统设置还需要system.settings。 - 动作成功只表示 EVCC 接受并完成了对应调用,不应推断车辆硬件一定产生预期物理效果;必要时读取 相关属性确认。
- 不要把未经信任的网页、云端文本或用户粘贴 JSON 直接转为车辆动作。
当前 1.0 动作目录以 queryCapabilities() 的结果为准:
| 动作 ID | 参数 | 权限 |
|---|---|---|
app.launch |
packageName |
action.safe |
home.show |
{} |
action.safe |
toast.show |
text |
action.safe |
automation.trigger |
ruleId,且目标自动化当前可运行 |
action.privileged |
system.settings 是为经过审核的系统设置类动作保留的独立权限类别;1.0 不提供任意设置键的通用动作。
需要 Shell 的系统写入使用另外两项独立权限和车机端逐次确认,不能用动作权限替代。
与 Lua API 的能力映射¶
EvccApi 对标的是 Lua 可用的 EVCC 能力边界,不是在第三方进程中再嵌入一套 Lua 运行时。映射如下:
| Lua 能力 | EvccApi 1.0 | 说明 |
|---|---|---|
property.read/write/info/list/on_change |
属性解析、读写、目录与订阅 | 五种车辆属性源统一为类型化模型;支持 AUTO、批量、稳定分页、来源状态和预检查 |
var.read/write/list/delete/on_change |
变量读写、查询、删除与订阅 | 与自动化/Lua 共用同一进程级变量状态;内置变量只读 |
shell.exec |
异步 Shell + 取消 | 采用更严格的公开接口黑名单、独立授权、输出/并发限制和系统写入确认 |
toast.show |
toast.show |
受 action.safe 控制 |
| 启动应用、返回桌面 | app.launch、home.show |
受 action.safe 控制 |
| 触发自动化 | automation.trigger |
受 action.privileged 控制;不开放任意广播代理,避免第三方借用 EVCC 身份绕过接收方权限 |
Lua 属性中的 settings: / sysprop: |
不作为任意属性键开放 | 只允许经审核动作,或在 Shell 双重权限/确认和永久黑名单内执行 |
http.* |
不提供 EVCC 网络代理 | 第三方应用应自行声明网络权限并使用自己的 HTTP 客户端,避免借用 EVCC 身份和信任域 |
sleep()、定时触发 |
不提供服务端常驻计时器 | 在第三方应用自己的协程、任务或生命周期中实现 |
storage.* |
不访问 Lua 私有存储 | 使用第三方应用自身沙箱;共享业务状态使用 EvccApi 变量 |
log.* / print() |
不提供任意日志注入 | 客户端记录自己的日志;EVCC 按 requestId 留存受限、脱敏审计信息 |
trigger.*、widget.*、float_btn.*、脚本生命周期 |
不直接导出 | 这些属于 EVCC 内 Lua/界面运行时;外部应用使用 Binder 回调和自己的 Android 生命周期 |
EvccApi 还补充了 Lua 单次脚本调用不具备的协议能力:按签名细分授权、能力发现、来源候选和代次、 初始化状态、批量非事务结果、事件序号/缺口重同步、稳定目录快照以及独立 Demo/Raw AIDL 调试链路。 不能映射的 Lua 能力属于明确的信任域或生命周期边界,不应通过 Shell 绕过。
能力 ID 与动作 ID 不同
queryCapabilities() 返回的能力 ID 带有 action. 前缀,例如 action.app.launch;传给
EvccActionRequest.actionId 的执行 ID 不带这个前缀,例如 app.launch。能力 ID 用于判断当前
会话是否可用,动作 ID 才是实际请求参数。
所有同步 Binder 调用都应离开主线程。为每个请求设置唯一 requestId,便于 Demo 控制台和 EVCC
审计日志对应问题。
API 1.1 音乐能力¶
music_state/bpm 内置变量继续保留;完整歌曲、歌词、封面与音乐命令请使用 API 1.1 的音乐接口,不要通过通用 action.safe 绕过 music.control。