跳转至

EVCC 小程序 MQTT 上报接口文档

最后更新:

协议版本:1

按 EVCC v3.2.14 源码核对,更新日期:2026-10-08

当前能力:车辆属性与 EVCC 变量只读上报,不支持 MQTT 远程写车或执行动作

1. 功能与边界

“小程序”卡片位于 EVCC 服务页的远程控制区域,是否显示由当前车型的云端适配配置决定。它把用户选择的车辆属性和 EVCC 变量发布到 MQTT Broker,供小程序服务端、家庭自动化平台或用户自己的程序展示和存储。

当前链路具有以下特点:

  • 连接成功后立即发布设备元信息和一份完整快照;
  • 属性或变量变化时实时增量发布;
  • 按固定间隔再次发布完整快照和心跳,作为丢包后的兜底;
  • 车辆属性可来自 VHAL、APVP、AIDL、CAPI、AdaptAPI、SOA、Geely AIDL 或 Geely CAPI;
  • 变量与自动化、公式、Lua 共用同一套 EVCC 变量系统;
  • 只发布数据,不订阅控制 topic,capabilities.write 固定为 false;
  • 普通属性仍按原有属性 ID topic 上报;VHAL 和 Geely 上报项可指定一个区域,MQTT 协议保持 v1 不变。

因此,服务端不得把预留的写入 topic 当作已经实现的控制接口,也不应仅凭收到某条状态值就推断 EVCC 具备反向控制能力。

2. EVCC 端配置

2.1 预设配置

预设配置适合官方小程序或按车型统一接入:

  1. 打开服务页“小程序”卡片;
  2. 保持“预设配置”;
  3. 填写 MQTT 用户名和密码;
  4. 按页面显示的引导在小程序侧完成绑定;
  5. 打开卡片开关,观察状态是否变为已连接;
  6. 需要车机启动后自动连接时,再打开“开机自动启动”。

预设模式中的以下项目由车型适配配置提供:

配置项 云端 Key 说明
默认模式 service.mini_program_default_mode preset 或 custom,未配置时为 preset
Broker 地址 service.mini_program_broker_host 预设模式必须有有效地址
上报项 service.mini_program_report_items 为空时回退到 EVCC 内置属性列表
引导文案 service.mini_program_guide_text 可用于说明小程序绑定步骤

预设模式的全量兜底间隔固定为 60 秒。Broker 使用 tcp:// 或 mqtt:// 前缀时默认端口为 1883,其他情况默认按 TLS 使用 8883。

2.2 自定义配置

自定义模式允许填写:

  • Broker 主机或 URL;
  • 端口;
  • MQTT 用户名和密码;
  • 全量兜底间隔;
  • 上报项列表;
  • 是否上传定位;
  • 是否开机自动启动。

自定义间隔最短为 10 秒。自定义上报项不会自动继承预设列表;没有保存过自定义项时列表保持空白,必须填写至少一个合法属性或变量才能启动。页面中的“恢复默认”可重新填入默认项,但保存后的列表仍属于本机自定义配置。

2.3 Broker 地址格式

支持以下写法:

ssl://mqtt.example.com
mqtts://mqtt.example.com
tcp://192.168.1.10
mqtt://192.168.1.10
mqtt.example.com
mqtt.example.com:8883

规则:

  • ssl:// 与 mqtts:// 使用 TLS;
  • tcp:// 与 mqtt:// 使用明文 TCP;
  • 没写 scheme 时默认使用 TLS;
  • 地址自身已经带 :端口 时,以地址内端口为准;
  • 自定义模式选择明文 TCP 时,应同时把端口设置为 Broker 的明文端口,通常为 1883。

2.4 用户名限制

用户名同时用于 MQTT 登录和 topic 路径,必须满足:

  • 去除首尾空格后不能为空;
  • 不含空白字符或控制字符;
  • 不含 /、+、#。

密码能否为空由 Broker 策略决定;官方预设服务通常会同时发放用户名和密码。

3. 上报项语法

上报项支持换行、空格、英文逗号或中文逗号分隔,重复项按首次出现顺序去重。

3.1 车辆属性

属性 ID 可写十进制或带 0x 前缀的十六进制:

557849089
0x2140A001
392168201/1

属性 ID/区域 ID 用于指定一个 VHAL 或 Geely 区域,两个数字均支持十进制或 0x 前缀十六进制。自定义模式可在“选择属性区域”中查看当前 VHAL 已知区域并选择;Geely 区域可直接填写。预设配置中的旧纯 ID 无需修改,云端上报项也可使用相同写法。

未写区域的旧项先尝试区域 0;若不可读,再按 VHAL 配置和已收到的区域列表选择一个可读区域,并在本次连接中固定该选择。显式指定区域时只读取及监听该 VHAL 区域。同一属性 ID 最终仍只有一个 evcc/<user>/<propertyId>/state topic;需要指定哪个区域时应在 EVCC 上报项中明确选择,服务端不能从 topic 反推出区域。同一 ID 填写多个不同区域会被视为冲突,保留首次指定的区域并计入无效项。

已有属性源未占用该 ID 时,Geely 纯数字上报项按目录匹配来源、通道和请求区域;只有唯一且可读的候选才会读取和订阅,ID 位数不参与判断。例如 24576 可自动匹配 Geely AIDL 的 signal 通道、请求区域 1,定时和实时上报仍使用 24576/state。数值 0 是有效数据;接口返回的区域元数据不替代请求区域。订阅由小程序独立持有,无需打开属性页,关闭小程序上报后释放。

同一 Geely ID 有多个区域时,可填写 24576/1;来源或通道仍有歧义时,应填写完整引用,例如 geely_aidl:signal:0x6000/1,其 topic 为 evcc/<user>/geely_aidl:signal:0x6000/1/state,接收端需订阅该 topic。歧义、写入专用、未连接或无法读取的项目不会填入假值,计入心跳的 missingCount。完整引用按原生身份匹配,不受属性显示名称变化影响。

3.2 EVCC 变量

以下四种写法等价:

$bpm
${music_state}
var:trip_fuel_last
variable:gps_available

变量名必须符合 EVCC 变量命名规则。可上报:

  • 用户创建的自定义变量;
  • 时间、日期等预设变量;
  • GPS 变量;
  • $bpm 和 $music_state 等音乐变量。

变量 topic 中只使用规范化后的变量名,不保留 $、${} 或 var: 前缀。

3.3 定位开关

“上传定位”默认关闭。打开后,EVCC 会在有效上报项中自动加入:

$gps_lng
$gps_lat

这两个变量由独立开关管理,即使用户把它们手动写进列表,保存时也会从普通列表中剥离。关闭定位上传后不会再发布它们。GPS 变量读取系统最近一次定位缓存,不主动发起定位;无定位缓存时该项会被记为缺失。

3.4 内置默认属性列表

车型云端没有提供上报项时,预设模式回退到以下内置十进制 ID:

561024570
561025079
561024448
561024549
557849089
561023639
557874774
561024172
561025056
561025057
559947198
561024651
561024565

这些只是通用默认值,不保证每个车型都存在。接入方应以 meta.items 为当前设备的实际配置清单,并结合心跳中的 missingCount 判断数据可用性。

4. MQTT 连接约定

项目 当前值
MQTT 客户端 Eclipse Paho 异步客户端
Clean Session true
连接超时 15 秒
Keep Alive 30 秒
自动重连 开启
Client ID evcc_mini_<username>_<deviceId> 清洗后最长 80 字符
遗嘱 topic evcc/<username>/status
遗嘱内容 offline,QoS 1,retain
订阅 无;当前版本只发布

每次首次连接或自动重连成功后,EVCC 都会重新发布 online、meta 和完整快照。

5. Topic 总表

基础前缀:

evcc/<MQTT用户名>/
Topic Payload QoS Retain 时机
evcc/<user>/status online / offline 1 是 连接、主动停止、遗嘱
evcc/<user>/meta JSON 1 是 每次连接成功
evcc/<user>/<propertyId>/state 原始字符串 0 否 完整快照或属性变化
evcc/<user>/var/<name>/state 字符串 0 否 完整快照或变量变化
evcc/<user>/heartbeat JSON 0 否 每次完整快照结束

属性 topic 始终使用十进制 ID,即使配置时填写的是十六进制。变量 topic 使用不带前缀的变量名。

当前没有以下已实现能力:

evcc/<user>/+/set
evcc/<user>/command/#

服务端不要向这类 topic 发布控制请求并期待 EVCC 执行。

6. Payload 说明

6.1 status

在线:

online

离线:

offline

状态为保留消息。正常停止时 EVCC 主动发布 offline;连接异常中断时由 Broker 发布遗嘱。服务端仍应结合最后心跳时间判断在线状态,不能只依赖 retain 状态。

6.2 meta

示例:

{
  "protocol": 1,
  "ts": 1786953600000,
  "model": "FS12-A1",
  "brand": "GEELYGALAXY",
  "deviceModel": "GEELYGALAXY FS12-A1",
  "evccDeviceId": "ABC-1234",
  "vin": "",
  "appVersion": "2.9.61",
  "intervalSec": 60,
  "properties": [557849089, 561024570],
  "variables": ["bpm", "music_state"],
  "items": [
    {
      "type": "property",
      "key": "557849089",
      "topic": "557849089/state"
    },
    {
      "type": "variable",
      "key": "bpm",
      "topic": "var/bpm/state"
    }
  ],
  "capabilities": {
    "write": false,
    "variables": true,
    "realtime": true
  }
}

字段:

字段 类型 说明
protocol int MQTT 数据协议版本,当前为 1
ts long 元信息生成时间,Unix 毫秒
model string Android Build.MODEL
brand string Android Build.BRAND
deviceModel string 品牌与型号拼接后的展示值
evccDeviceId string EVCC 设备 ID,读取失败时可能为空
vin string 当前可获取的 VIN,未获取时为空
appVersion string EVCC 版本名
intervalSec int 周期完整快照间隔
properties int[] 配置中的车辆属性 ID
variables string[] 配置中的变量名
items object[] 属性与变量的统一清单
items[].type string property 或 variable
items[].key string 十进制属性 ID 或变量名
items[].topic string 相对 evcc/<user>/ 的状态 topic
capabilities.write boolean 当前固定为 false
capabilities.variables boolean 当前为 true
capabilities.realtime boolean 当前为 true

接入方应按 items 构建展示列表,不要把 properties 当作唯一数据源;后者不包含变量。

6.3 属性状态

Topic:

evcc/<user>/<十进制属性ID>/state

Payload 是 UTF-8 原始字符串,不是 JSON 包装:

52
1, 2, 3

车辆属性底层常见的展示后缀会在上报前去掉,例如 1 (READY) 会发布为 1。服务端应把 payload 先当字符串保存;只有确认某个属性的类型后再转成数字或布尔值。

6.4 变量状态

Topic:

evcc/<user>/var/<变量名>/state

Payload 同样是 UTF-8 字符串:

128
playing

bpm 无音乐或未匹配时为 0;music_state 可能为 playing、paused_or_stopped 或 none。变量的完整定义见《EVCC 公式与变量系统参考手册》。

6.5 heartbeat

示例:

{
  "ts": 1786953600123,
  "seq": 12,
  "propertyCount": 2,
  "variableCount": 2,
  "itemCount": 4,
  "publishedCount": 3,
  "missingCount": 1
}
字段 类型 说明
ts long 心跳生成时间,Unix 毫秒
seq long 本次 EVCC MQTT 运行期间递增的心跳序号;重启连接进程后可重新开始
propertyCount int 配置的属性数量
variableCount int 配置的变量数量
itemCount int 两者之和
publishedCount int 本轮完整快照成功取得并尝试发布的项目数
missingCount int 本轮未取到值的项目数

publishedCount + missingCount 正常应等于 itemCount。心跳只在完整快照后发布,不会为每次实时变化单独发布。

7. 发布时序与去重

7.1 首次连接

sequenceDiagram
    participant E as EVCC
    participant B as MQTT Broker
    participant S as 小程序服务端

    E->>B: CONNECT + LWT offline
    E->>B: status=online (QoS1, retain)
    E->>B: meta JSON (QoS1, retain)
    loop 每个可读属性和变量
        E->>B: state payload (QoS0, non-retain)
    end
    E->>B: heartbeat JSON (QoS0, non-retain)
    B-->>S: 转发已订阅消息

7.2 实时变化

  • 五个车辆属性源的变化事件都会被监听;
  • 自定义变量变化时立即入队,预设/动态变量还会每 1 秒补查;
  • 变化先等待约 500 毫秒合并;
  • 同一项目最快每 1 秒发布一次;
  • 实时路径发现 payload 与上次完全相同时不重复发布;
  • 显式选择区域的 VHAL 项只接收对应区域变化;旧纯 ID 项在自动选区后也保持该区域;
  • 多次快速变化只保留等待队列中的最新值。

7.3 周期完整快照

  • 预设模式固定每 60 秒执行;
  • 自定义模式按用户设置执行,最短 10 秒;
  • 每轮重新读取所有配置项;
  • 带区域的 VHAL 项按所选区域读取;旧纯 ID 项在区域 0 失败时尝试已知区域;
  • 完整快照会强制再次发布可读值,即使值没有变化;
  • 若 MQTT 先于 VHAL 就绪,VHAL 连接后会重新发布一次快照;
  • 每发布 10 项会短暂让出执行,避免一次性占满连接线程;
  • 完成后发布一次心跳。

8. 属性和变量的读取口径

8.1 属性主动读取优先级

未显式指定区域的属性,优先读取 VHAL 区域 0;若已知该 VHAL 属性存在非零区域,则继续尝试这些区域。仍不可读时,再沿用其他来源的区域 0 读取顺序:

APVP -> AIDL -> CAPI -> AdaptAPI -> SOA

显式写成 属性 ID/区域 ID 的上报项仅从 VHAL 读取;其他纯 ID 上报项保持原有来源优先级。

APVP 项会按配置 ID 建立订阅,停止 MQTT 后解除该订阅。

8.2 变量读取

变量通过当前自动化引擎的 VariableManager 读取;自动化服务尚未运行时会使用只读回退实例。变量值会先经过变量系统替换,因此用户变量可以引用其他变量或表达式。

找不到变量时不发布空字符串,而是把该项计入本轮 missingCount。

9. 服务端接入建议

9.1 账号和 ACL

建议每个用户使用独立 MQTT 凭据,并至少限制:

允许客户端发布:evcc/<username>/#
允许小程序服务订阅:evcc/<username>/#
禁止客户端发布到其他 username 前缀

不要仅用可猜测的用户名作为身份验证;Broker 仍需校验密码或更强的凭据。用户名会出现在 topic 中,不应包含手机号、身份证号等不必要的敏感信息。

9.2 数据模型

推荐按以下键保存最后状态:

(username, itemType, itemKey) -> value, receivedAt

以最新 meta.items 作为当前项目集合。收到新的 meta 后,可将不再出现的旧项目标记为停用,不要继续把旧缓存当作本机仍在上报的数据。

9.3 在线判断

建议组合判断:

  1. retained status 为 online;
  2. 最近一次心跳不超过 2~3 × intervalSec;
  3. 必要时结合 Broker 会话状态。

只依赖 status=online 可能受 Broker 遗嘱延迟或异常网络影响;只依赖非保留心跳又会让新订阅者在下一轮心跳前无法判断状态。

9.4 消息顺序

属性和心跳使用 QoS 0,不保证必达;不同 topic 之间也不应假设严格顺序。heartbeat.seq 只标识完整快照轮次,不能作为所有实时状态消息的全局序号。

10. 常见问题

10.1 卡片没有显示

  • 确认当前车型云端配置允许显示小程序功能;
  • 等待车型配置同步完成后重新进入服务页;
  • 如果云端明确隐藏,该入口不会在本机强制出现。

10.2 提示配置不完整

检查:

  • Broker 地址是否为空;
  • 用户名是否为空或包含 /、+、#、空格;
  • 自定义模式是否至少有一个合法上报项;
  • 端口是否与 TLS / 明文协议匹配。

10.3 已连接但没有某个属性

  • 该车型可能没有这个属性 ID;
  • 对应属性源可能未连接或未启用;
  • 属性可能是多区域属性;在自定义上报项中确认 属性 ID/区域 ID 是否选中了实际可读区域;
  • 查看心跳 missingCount 是否增加;
  • 在 EVCC 属性页先确认该 ID 能否读到值。

10.4 变量没有更新

  • 确认变量名没有包含 $ 之外的非法字符;
  • 自定义变量必须已被创建;
  • 动态变量正常最多约 1 秒后被补查;
  • $bpm 在无音乐或未匹配时按设计为 0;
  • $music_state 是文本状态,不是布尔值。

10.5 偶尔缺一条实时消息

实时值为 QoS 0,网络中断时允许丢失;周期完整快照会再次发布当前值。小程序服务端不应把单条增量消息当作唯一事实来源。

11. 兼容与变更约束

协议 v1 的接入方应:

  • 忽略 meta 中未知字段;
  • 以 capabilities 判断能力,不猜测写入支持;
  • 把状态 payload 当字符串,再按具体项目解释;
  • 接受 vin、设备 ID 或某些属性暂时为空;
  • 接受 meta.items 同时包含属性与变量;
  • 不依赖 heartbeat.seq 跨重连持续递增;
  • 不依赖属性 topic 的 retain;
  • 不把同一属性 ID 的来源或区域当作可从 topic 反推的信息。

若后续新增远程控制,应使用新的已签名/鉴权协议并提升能力声明,不能只增加一个公开 set topic。

12. 源码索引

内容 文件
配置模式、默认项、解析规则 MiniProgramMqttConfig.kt
MQTT 连接、topic 与 payload MiniProgramMqttBridge.kt
属性与变量读取 MiniProgramPropertyHelper.kt
启停与休眠恢复 MiniProgramMqttManager.kt

相关文档:

Geely 只读上报项

报告项可填写限定引用,例如 geely_capi:sensor:0x100100/0。该项通过原有主题前缀和用户段下的 <完整引用>/state 发布,保留来源、通道和区域。原有数字 ID 主题保持不变;Geely 限定项不会写入同号数字主题。该扩展不增加 MQTT 车辆控制权限。