跳转至

变量与动作

最后更新:

变量

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。