跳转至

小程序 MQTT 接入

最后更新:

小程序 MQTT 是 EVCC 的另一条集成链路,用于把用户选定的车辆属性和 EVCC 变量发布到 MQTT Broker。它与 EvccApi 的 Binder 协议、授权和生命周期彼此独立。

本页用于选择方案和快速接入;所有 Topic、Payload、配置字段和服务端处理规则见 完整协议参考。

当前是只读上报

MQTT 协议版本当前为 1,EVCC 只发布状态,不订阅控制 Topic;运行时 meta.capabilities.write 固定为 false。不要向预留的 set 或 command Topic 发送车辆控制, 也不要把 EvccApi 的写入权限理解为 MQTT 写入权限。

什么时候选择 MQTT

需求 小程序 MQTT EvccApi
运行位置 Broker、服务端、家庭自动化平台 同一车机上的 Android 应用
传输 MQTT/TCP 或 MQTT/TLS Android Binder
当前写入能力 无 经用户分类授权后可用
数据模型 Topic + UTF-8 字符串 类型化 Parcelable
属性选择 按 ID 配置,不能指定来源或区域 ID/名称、AUTO/显式来源、可选区域
增量连续性 QoS 0,靠周期快照兜底 会话事件序号与缺口重同步
身份与授权 Broker 凭据和 ACL 包名、UID、签名证书和 EVCC 授权

需要远端展示或留存少量只读状态时选择 MQTT;需要车机 App 内精确解析、初始化、监听、写入或动作时 选择 EvccApi。两条链路可以同时使用,但不能互相代替权限检查。

EVCC 端配置

入口位于服务页的“小程序”卡片;该卡片是否显示取决于车型适配。EVCC 提供两种模式:

  • 预设配置:Broker、默认上报项和引导由适配配置提供,用户填写分配到的凭据。
  • 自定义配置:用户填写 Broker、端口、凭据、完整快照间隔和上报项。

自定义完整快照间隔最短为 10 秒。支持 ssl://、mqtts://、tcp://、mqtt:// 或不带 scheme 的主机;不带 scheme 时默认使用 TLS。生产部署应优先使用 TLS。

MQTT 用户名同时进入 Topic 路径,不能为空,也不能包含空白、控制字符、/、+ 或 #。不要把 手机号、证件号等不必要的个人信息用作用户名。

上报项

车辆属性使用十进制或带 0x 前缀的十六进制 ID:

557849089
0x2140A001

变量支持以下等价写法,最终 Topic 中只保留规范变量名:

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

当前 MQTT 属性项不能指定来源和区域。周期快照使用区域 0 主动读取;同一 ID 存在多个区域值时, 不要依赖一个 Topic 区分区域。属性读取按 EVCC 的来源优先级寻找首个可用值,接收方也不能从 Topic 反推出实际来源。

定位上报需要用户单独开启。定位变量来自系统已有的最近位置缓存,可能缺失或过期;服务端应将位置、 VIN、设备 ID 和车辆状态视为敏感数据,按最小保存期限和最小访问范围处理。

Topic 与 Payload

基础前缀:

evcc/<MQTT用户名>/
Topic Payload QoS Retain
status online / offline 1 是
meta 设备、协议、项目清单和能力 JSON 1 是
<十进制属性ID>/state 属性原始字符串 0 否
var/<变量名>/state 变量字符串 0 否
heartbeat 本轮完整快照统计 JSON 0 否

例如:

evcc/demo-user/557849089/state
evcc/demo-user/var/music_state/state

状态 Payload 不是 JSON 包装。先以 UTF-8 字符串存储,只有在业务明确知道某一项类型后再转换数字或 布尔值。不要依赖展示后缀,也不要把缺少消息解释为数值 0。

meta 的关键结构:

{
  "protocol": 1,
  "intervalSec": 60,
  "items": [
    {"type": "property", "key": "557849089", "topic": "557849089/state"},
    {"type": "variable", "key": "music_state", "topic": "var/music_state/state"}
  ],
  "capabilities": {
    "write": false,
    "variables": true,
    "realtime": true
  }
}

接入方应以最新 meta.items 替换当前项目目录,而不是只读取兼容字段 properties 或把旧项目永久 保留。必须忽略未知 JSON 字段,并根据 protocol 与 capabilities 判断兼容性。

发布生命周期

每次首次连接或自动重连成功后,EVCC 依次发布在线状态、meta、一轮完整状态和 heartbeat。运行中:

  • 属性或变量变化会产生实时增量;快速变化会被合并和去重。
  • 状态增量使用 QoS 0,允许在网络中断时丢失。
  • EVCC 会按配置间隔重新发布完整快照,作为增量丢失后的兜底。
  • heartbeat.seq 只表示当前 MQTT 运行期间的完整快照轮次,重连后可以重新开始;它不是所有 Topic 的全局事件序号。
  • retained status=online 也可能因异常链路而滞后,必须结合最近心跳判断在线。

推荐把在线判定设置为:retain 状态为在线,并且最近一次心跳不超过 2~3 × intervalSec。不同 Topic 之间没有严格顺序保证,服务端处理必须幂等。

服务端接入 Recipe

  1. 为每台设备或用户分配不可猜测的独立凭据。
  2. Broker ACL 只允许 EVCC 客户端发布自己的 evcc/<username>/#,只允许业务端订阅授权前缀。
  3. 业务端订阅整个前缀;收到 meta 时原子替换项目目录。
  4. 按 (username, itemType, itemKey) 保存最后值和接收时间。
  5. 收到状态 Topic 时只更新对应项目,不假设与 heartbeat 的先后顺序。
  6. 用 heartbeat 的计数和时间判断快照是否完整、设备是否新鲜;QoS 0 丢失时等待下一轮快照。
  7. 收到新 meta 后,将已移除项目标记停用,不继续展示旧缓存为当前状态。

兼容和权威顺序

本页是从既有 MQTT 专题手册提炼的公共接入说明。运行时信息的权威顺序是:

  1. 当前连接收到的 meta.protocol、meta.capabilities 和 meta.items;
  2. 当前 EVCC 版本提供的用户界面与发布行为;
  3. 本页的协议说明和示例。

旧手册曾按较早 EVCC 版本核对,因此客户端必须忽略未知字段、接受部分值暂时缺失,并且永远不能仅凭 文档预留字段推断写入能力。如果未来提供 MQTT 控制,必须通过新的明确协议版本、能力声明和鉴权设计 开放。