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 预设配置¶
预设配置适合官方小程序或按车型统一接入:
- 打开服务页“小程序”卡片;
- 保持“预设配置”;
- 填写 MQTT 用户名和密码;
- 按页面显示的引导在小程序侧完成绑定;
- 打开卡片开关,观察状态是否变为已连接;
- 需要车机启动后自动连接时,再打开“开机自动启动”。
预设模式中的以下项目由车型适配配置提供:
| 配置项 | 云端 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 前缀的十六进制:
属性 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 变量¶
以下四种写法等价:
变量名必须符合 EVCC 变量命名规则。可上报:
- 用户创建的自定义变量;
- 时间、日期等预设变量;
- GPS 变量;
$bpm和$music_state等音乐变量。
变量 topic 中只使用规范化后的变量名,不保留 $、${} 或 var: 前缀。
3.3 定位开关¶
“上传定位”默认关闭。打开后,EVCC 会在有效上报项中自动加入:
这两个变量由独立开关管理,即使用户把它们手动写进列表,保存时也会从普通列表中剥离。关闭定位上传后不会再发布它们。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 总表¶
基础前缀:
| 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 使用不带前缀的变量名。
当前没有以下已实现能力:
服务端不要向这类 topic 发布控制请求并期待 EVCC 执行。
6. Payload 说明¶
6.1 status¶
在线:
离线:
状态为保留消息。正常停止时 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:
Payload 是 UTF-8 原始字符串,不是 JSON 包装:
车辆属性底层常见的展示后缀会在上报前去掉,例如 1 (READY) 会发布为 1。服务端应把 payload 先当字符串保存;只有确认某个属性的类型后再转成数字或布尔值。
6.4 变量状态¶
Topic:
Payload 同样是 UTF-8 字符串:
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 读取顺序:
显式写成 属性 ID/区域 ID 的上报项仅从 VHAL 读取;其他纯 ID 上报项保持原有来源优先级。
APVP 项会按配置 ID 建立订阅,停止 MQTT 后解除该订阅。
8.2 变量读取¶
变量通过当前自动化引擎的 VariableManager 读取;自动化服务尚未运行时会使用只读回退实例。变量值会先经过变量系统替换,因此用户变量可以引用其他变量或表达式。
找不到变量时不发布空字符串,而是把该项计入本轮 missingCount。
9. 服务端接入建议¶
9.1 账号和 ACL¶
建议每个用户使用独立 MQTT 凭据,并至少限制:
不要仅用可猜测的用户名作为身份验证;Broker 仍需校验密码或更强的凭据。用户名会出现在 topic 中,不应包含手机号、身份证号等不必要的敏感信息。
9.2 数据模型¶
推荐按以下键保存最后状态:
以最新 meta.items 作为当前项目集合。收到新的 meta 后,可将不再出现的旧项目标记为停用,不要继续把旧缓存当作本机仍在上报的数据。
9.3 在线判断¶
建议组合判断:
- retained
status为online; - 最近一次心跳不超过
2~3 × intervalSec; - 必要时结合 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 车辆控制权限。