OCPP 是什么
OCPP——开放充电点协议(Open Charge Point Protocol)——是充电桩(Charge Point)与后端管理系统(中央系统管理软件,即 CSMS)之间通信的行业标准。1.6 版是当下现场部署最广的版本。
协议跑在 WebSocket 上。充电桩永远是 WebSocket 客户端,CSMS 是服务端。消息是 JSON(也就是 -J 变体,实际上大家用的都是它)。
消息格式
每一条 OCPP 消息都是一个结构固定的 JSON 数组:
[MessageTypeId, UniqueId, Action, Payload]- MessageTypeId:2 = Call(请求),3 = CallResult(响应),4 = CallError
- UniqueId:你自己生成的字符串,用来把请求和响应对上
- Action:操作名(例如 “BootNotification”)
- Payload:消息体,一个 JSON 对象
一次典型的 BootNotification 往返是这样:
// 充电桩 → CSMS
[2, "19223201", "BootNotification", {
"chargePointModel": "SingleSocketCharger",
"chargePointVendor": "VendorX"
}]// CSMS → 充电桩
[3, "19223201", {
"currentTime": "2026-03-05T10:00:00Z",
"interval": 300,
"status": "Accepted"
}]核心消息流程
启动序列
充电桩开机后,必须先发 BootNotification,并在收到 Accepted 之前什么都不做。如果 CSMS 返回 Pending 或 Rejected,充电桩应当退避,并按响应里给出的间隔重试。
BootNotification 被接受之后,充电桩为每个接口各发一条 StatusNotification,然后按 CSMS 指定的间隔开始发 Heartbeat。
授权
启动一笔交易之前,充电桩通常需要先给用户授权。它发出带 idTag(RFID 卡号)的 Authorize,CSMS 回一个 AuthorizationStatus。要紧的几个状态是:
- Accepted:允许这笔交易
- Blocked:卡被冻结,不要启动
- Expired:卡已过期
- Invalid:未知的卡
- ConcurrentTx:这张卡在别处已有一笔进行中的交易
交易流程
StartTransaction → [CSMS 分配 transactionId]
→ StatusNotification (Charging)
→ MeterValues(周期性,可选)
→ StopTransaction → [CSMS 关闭交易]
→ StatusNotification (Available)StartTransaction 返回的 transactionId,必须出现在 StopTransaction 和本次会话期间所有的 MeterValues 里。
远程指令
CSMS 可以向充电桩下发指令。需要实现的关键几条:
- RemoteStartTransaction / RemoteStopTransaction:启动或停止一次会话
- Reset:Soft(优雅)或 Hard(立即)重启
- ChangeAvailability:把某个接口投入或退出服务
- GetConfiguration / ChangeConfiguration:读写配置项
- UnlockConnector:物理上释放线缆
常见的实现错误
1. 不理会 BootNotification 返回 Pending 时的回压
有些充电桩无视 Pending 响应,立刻开始发 Heartbeat。规范写得很清楚:等到 Accepted 再说。
2. 用了过期的 transactionId
永远使用 CSMS 在 StartTransaction.CallResult 里分配的那个 transactionId。绝不要复用上一次会话的 ID。
3. StopTransaction 之后不发 StatusNotification
一笔交易结束后,接口状态应当回到 Available(或者 Preparing、Faulted,取决于实际状态)。漏掉这一步,CSMS 手上留的就是一个过期的接口状态。
4. 无视心跳间隔
CSMS 会在 BootNotification 的响应里告诉你多久发一次 Heartbeat。用那个值,不要用写死的值。
测试你的实现
这正是 TestPilot 派上用场的地方。它模拟一个 CSMS,驱动你的充电桩走完上面这些流程,并在每一步校验消息结构和时序。跑第一遍,你就能抓出大部分一致性问题。