简介《OCPP1.6J学习质料》面向充电桩设备厂商、充电网络运营与协议对接开发人员也适合需要理解开放充电点协议的技术学习者用于系统梳理OCPP 1.6J的术语体系、文档结构与消息交互规范。压缩包仅含1个PDF文件约3.84MB为开放充电点协议1.6第2版最终版文档目录覆盖范围说明、术语与缩略语、导言、功能配置文件、操作一般视图、本地授权与离线行为、事务相关消息、连接器编号及ID Tokens等章节便于按协议模块查阅。已有879人学习文档可帮助读者理解远程启停充电、状态上报、计费支付、加密通信与远程软件更新等核心能力并掌握TCP/IP连接初始化、认证、心跳保持及命令响应格式为设备开发、平台联调和现场排错提供较完整的标准依据。1. 先别被缩写吓到OCPP 1.6J 到底是什么很多人第一次看到 OCPP 1.6J会以为它是某个充电桩型号或者一套后台软件的名字。其实可以把它想成充电桩和中央管理系统之间的“普通话”桩要告诉后台“我上线了、这把枪插上了、开始放电了”后台也要能说“先别充、把功率降一点、给我发个心跳”。OCPP 1.6J 就是这套对话规则里用 JSON 传递消息的那一版约定。搞懂它你看充电桩日志时就不会只看到一堆英文动作名而能判断一次充电到底卡在授权、启动交易还是计量上报。2. 为什么需要 OCPP 1.6J充电桩和后台为什么不能各说各话2.1 一个充电站里其实有两套语言充电桩内部有自己的“设备语言”。继电器怎么吸合、电表怎么采样、急停信号怎么传、连接器锁怎么控制这些往往由硬件板和嵌入式程序处理普通运营人员既看不见也不太需要天天盯着。真正影响业务的是另一套“业务语言”这把枪现在能不能用、用户刷卡后要不要放行、这次充电该记到哪个账户、电表走了多少度、后台要不要远程把功率压下来。如果没有统一协议每个充电桩厂家都用私有格式和后台对话运营平台每接一批新桩就要重写一套适配充电桩厂家每进一个平台也要重复对接。最后的结果很像一群人说不同方言硬件都能通电业务却接不起来。OCPP 1.6J 的价值不是让充电桩“更高级”而是把授权、启动交易、上报状态、远程控制这些高频动作约定成双方都认识的消息名和字段名。打个比方物流公司发快递时不会每次自己发明面单格式而是按统一面单填收件人、电话、重量、目的地。OCPP 1.6J 里的BootNotification、Authorize、StartTransaction就像这些固定栏目字段填什么、什么时候发、对方怎么回都有约定。这样一家后台面对多个厂家的桩至少能先在业务层说同一种话。2.2 它到底解决了哪几件麻烦事第一件是“上线身份”。充电桩通电后不能直接闷头工作它要先告诉中央系统自己是谁、型号是什么、固件版本是多少这就是BootNotification要干的事。中央系统收到后会判断认不认这台桩并回一个心跳间隔和当前时间。没有这一步后台不知道新设备从哪来也没法给它安排后续策略。第二件是“授权与交易”。用户刷卡、扫码或输入码桩把idTag发出去问一句“这个人能不能充”对应Authorize。允许后桩本地启动交易发StartTransaction中央系统回一个transactionId这次充电就有了业务身份。结束时发StopTransaction把结束电表读数、时间、结束原因带上。计费系统拿这些信息才能把一次充电和一笔账单对上。第三件是“状态可见”。枪有没有插好、连接器是空闲还是充电中、门是不是被打开、急停有没有按下这些通过StatusNotification上报。桩活着没有、网络通不通用Heartbeat维持。固件升级进行到哪一步用FirmwareStatusNotification。这些消息看起来琐碎但真到排障时缺一条状态就可能让现场人员只能猜。第四件是“远程运维”。后台可以下发ChangeConfiguration改配置Reset复位UpdateFirmware升级固件UnlockConnector解锁连接器RemoteStartTransaction和RemoteStopTransaction远程启停。对分布很散的充电网络来说这些能力能减少大量现场跑动。这里最容易踩坑的地方是远程指令不是发出去就完事桩要回CALLRESULT后台还要看返回状态是接受、拒绝还是排期执行。2.3 为什么偏偏是“1.6J”这个组合OCPP 1.6 是协议版本1.6J 里的 J 常被理解成 JSON 绑定。更准确地说1.6J 的重点在于消息用 JSON 承载、走 WebSocket 长连接而不是把 1.6 的全部内容推倒重来。它保留了 1.6 里的功能配置文件和消息定义只是把传输层的表达方式换成更贴近现代 Web 开发习惯的 JSON。这对开发者很实际。JSON 字段名可读抓一段消息就能看出是在授权还是在启动交易WebSocket 是双向长连接中央系统不必等桩来轮询也能主动下发远程启停、改配置、触发上报。相比之下早期基于 SOAP/XML 的绑定更重报文更大调试时一层层标签看下来容易眼花。1.6J 不是“另一个完全不同的协议”更像是 1.6 这套业务规则的一种轻量表达方式。开放也是关键。协议文档把消息名、字段、方向、状态值写出来不同厂家按同一套名字实现后台才有可能复用同一套业务逻辑。这里的“开放”不等于随便改恰恰相反字段大小写、枚举值、必填项都要守约定。否则名字都叫StartTransaction一个厂家把时间写成当地时间另一个写成 UTC后台对账时就会翻车。协议的存在感往往就在这些看似死板的约定里。3. 这份 OCPP 1.6J 学习资料里有什么从功能配置文件到消息字典3.1 目录不是摆设它其实是一条学习路线这份资料对应的是 OCPP 1.6 第 2 版最终版文档目录从范围、术语和约定、导言一路排到充电点发起的操作、中央系统发起的操作和具体消息定义。刚接触的人容易从第 6 章消息字段开始硬啃结果看到Authorize.req、BootNotification.conf这类名字就迷路。更稳的顺序是先看导言里的操作一般视图知道谁先说话、谁后回应再回头看消息字典。目录里“功能配置文件”这一节很值得先看。它告诉你这套协议不是要求每个桩把所有功能都做全而是把能力拆成若干配置文件。某款桩可能只做核心功能另一款桩支持预约和智能充电。后台对接时先问清楚对方支持哪些配置文件比一上来就假设“OCPP 1.6J 应该什么都能干”要靠谱。“术语和约定”也不能跳。充电点、中央系统、连接器、交易、idTag、预约、时区、时间表示、仪表计量数据这些词在后面的消息里反复出现。比如connectorId不是随便一个编号connectorId为 0 时常表示充电点主控制器1 以上才是具体枪口。再比如时间字段文档专门把时区和时间表示拎出来讲说明它不是随手填本地时间就完事。3.2 功能配置文件把“可选能力”说清楚资料里的功能配置文件大致把能力分成核心、固件管理、本地授权列表管理、预约、智能充电、远程触发等几块。核心配置文件是底座包含启动通知、心跳、授权、交易启停、状态通知、计量值这些大部分桩都要有的动作。固件管理负责升级通知和升级状态本地授权列表管理负责在桩离线时也能用本地名单放行预约负责提前占住某个连接器智能充电负责下发功率计划远程触发负责让后台要求桩补发某类消息。这种拆法解决了一个现实问题不是所有充电桩都有同样的硬件和能力。小区里的慢充桩可能不需要复杂预约公交场站的大功率桩可能更关心智能充电和复合计划。后台如果按“全功能”去对接遇到精简型桩就会不断收到“不支持”的回应。先对齐功能配置文件再谈消息细节能省掉很多无效联调。这里也有一个容易忽略的点配置文件是能力声明不是营销标签。桩说支持智能充电不代表它能凭空提高电网容量只代表它能接收充电配置文件并按约定执行功率限制或调度。桩说支持本地授权列表也不代表名单会自动同步仍然要靠SendLocalList下发、靠GetLocalListVersion查版本。把能力声明和实际配置分开看后面排查“为什么功能没生效”时才有方向。3.3 消息字典每个动作都有请求和回应第 6 章的消息目录像一本字典列出Authorize.req、Authorize.conf、BootNotification.req、BootNotification.conf这样的成对定义。.req是发起方发出去的请求.conf是接收方回来的回应。看消息时不要只看请求字段回应里的状态值同样决定业务走向。比如授权回应里的idTagInfo.status可能是接受、拒绝、过期、并发等桩要根据它决定放不放行。以BootNotification.req为例常见字段会包含充电点厂商、型号、序列号、固件版本、ICCID、IMSI、电表序列号、电表类型等。中央系统的BootNotification.conf会回当前时间、心跳间隔和注册状态。注册状态如果是接受桩按心跳间隔维持连接如果是拒绝桩通常要等一段时间再重试。这个细节在联调时很关键有的桩一上线就疯狂重连往往是把拒绝状态当成了临时失败。消息字典的读法可以抓三条线谁发起、带什么关键字段、回应里哪个状态会影响下一步。StartTransaction.req带连接器编号、idTag、起始电表读数、时间回应带transactionId和授权状态。StopTransaction.req带交易编号、结束电表读数、时间、结束原因可能还带交易期间的计量数据。把这些字段和一次真实充电对上消息就不再是干巴巴的表格。3.4 术语、时区和计量数据为什么不能略过这份资料把“本地授权和离线行为”“交易与能量传输周期的关系”“连接器编号”“ID Tokens”“Parent idTag”“预约”“厂商特定数据传输”“智能充电”“时区”“时间表示”“仪表计量数据”单独列出来说明这些不是边角料。离线行为决定网络断了以后桩还能不能靠本地名单放行连接器编号决定后台控制的到底是整台桩还是某把枪时间表示决定账单和日志能不能对齐计量数据决定计费采样是不是可信。尤其是时间。OCPP 消息里的时间通常按 UTC 的 ISO8601 表达后台展示给用户时再换成本地时区。如果桩把本地时间直接塞进timestamp后台又按 UTC 解析账单上就可能出现几个小时的偏移。这种问题不玄学就是约定没守住。学习资料里专门讲时区等于提前告诉你时间字段不是格式对了就行基准也要对。仪表计量数据也类似。MeterValues上报的是采样值可能包含电量、功率、电流、电压等不等于最终账单。最终账单还要结合交易起止、费率、授权账户来算。把MeterValues当成账单或者把StartTransaction的起始读数当成唯一依据都会在对账时出问题。资料把这些概念分开列是为了让读的人知道每个消息在业务链里的位置。4. 消息怎么走OCPP 1.6J 的两种发起方向和一次充电交易4.1 先看懂消息信封CALL、CALLRESULT 和 CALLERROROCPP 1.6J 的消息不是直接扔一个业务对象过去而是包在一个数组信封里。第一个元素是消息类型2 表示请求3 表示成功回应4 表示错误回应。第二个元素是唯一消息编号用来把请求和回应配对。第三个元素开始才是动作名和负载。这个设计很像寄快递时外面贴一张运单运单号不变里面的东西才知道该配给哪一单。// OCPP 1.6J 的 CALL 消息充电点请求启动一次交易 const call [ 2, // 消息类型2 表示 CALL msg-1001, // 唯一消息编号用来配对请求与回应 StartTransaction, // 动作名 { connectorId: 1, // 连接器编号1 表示某把枪 idTag: RFID-0001, // 用户授权标识 meterStart: 1200, // 起始电表读数 timestamp: 2025-01-01T10:00:00Z // UTC 时间带 Z } ]; // 中央系统若接受会返回 CALLRESULT消息类型为 3编号必须相同 const result [ 3, msg-1001, { transactionId: 90001, // 中央系统分配的交易编号 idTagInfo: { status: Accepted } // 授权状态 } ];这段示例里2和3是消息类型msg-1001是配对编号StartTransaction是动作名。connectorId指明哪把枪idTag是用户身份meterStart是起始读数timestamp用 UTC 时间。回应里的transactionId是后续StopTransaction和计量上报要带的交易身份status决定这次授权是否被接受。真实报文还会有更多可选字段但这条主线不变请求带业务参数回应带结果和后续要用的编号。如果中央系统处理失败会回消息类型 4 的CALLERROR里面包含错误码、错误描述和错误详情。桩不能把错误回应当成成功回应继续往下走否则就会出现“后台明明拒了桩还在充电”的怪现象。联调时看到类型 4先看错误码和描述再对照消息定义查字段比盲目重发有效。4.2 充电点发起的操作桩主动开口的场景充电点发起的操作基本围绕“我发生了什么”展开。上线要发BootNotification证明自己是谁保持连接要发Heartbeat用户要充电先发Authorize交易开始发StartTransaction结束发StopTransaction枪口状态变化发StatusNotification计量采样发MeterValues诊断和固件升级过程分别发DiagnosticsStatusNotification和FirmwareStatusNotification厂商自定义扩展走DataTransfer。这些消息的顺序不是死的但业务上有前后依赖。没有BootNotification被接受后台可能不认这台桩没有Authorize的接受状态桩通常不该启动交易没有StartTransaction返回的交易编号后续计量和停止交易就少了主线。现场排障时先看桩有没有上线再看授权有没有过再看交易有没有开最后看计量有没有持续上报这条链比一上来翻全部日志清楚。StatusNotification值得单独说。它不只报“充电中”还会报空闲、准备中、预约、不可用、故障等状态。不同状态对应不同连接器可用性。后台如果只看交易表不看状态通知就可能把一把故障枪派给用户。桩如果状态上报不及时后台展示的“空闲”也可能是过期信息。状态消息看似简单实际是运营可视化的地基。4.3 中央系统发起的操作后台主动下手的场景中央系统发起的操作围绕“我要你做什么”展开。远程启动和停止交易用RemoteStartTransaction、RemoteStopTransaction预约用ReserveNow和CancelReservation改配置用ChangeConfiguration查配置用GetConfiguration复位用Reset解锁用UnlockConnector升级固件用UpdateFirmware诊断用GetDiagnostics本地授权列表用SendLocalList和GetLocalListVersion智能充电用SetChargingProfile、ClearChargingProfile、GetCompositeSchedule补发消息用TriggerMessage厂商扩展同样可以走DataTransfer。这些指令有一个共同点后台发请求桩要回结果。结果可能是接受也可能是拒绝、不支持、排期执行。比如ChangeAvailability把某把枪改成不可用桩回接受不代表立刻断开正在充电的车具体行为还要看协议约定和桩实现。再比如Reset分软复位和硬复位正在充电时硬复位可能影响交易后台不能把它当普通重启按钮乱按。方向典型消息主要用途充电点发起BootNotification、Heartbeat、Authorize、StartTransaction、MeterValues、StopTransaction上报身份、保活、授权、交易与计量中央系统发起RemoteStartTransaction、RemoteStopTransaction、ChangeConfiguration、Reset、UpdateFirmware、SetChargingProfile远程控制、配置、运维与功率调度这张表只列主线不表示消息只能单向使用。DataTransfer两个方向都能发用来承载厂商特定数据。看资料时把方向记成“谁主动开口”比死背消息列表更容易迁移到实际日志。4.4 一次普通充电的消息流长什么样假设某用户把车插到 1 号枪刷了一张本地卡。桩先发Authorize中央系统回接受桩发StartTransaction中央系统回transactionId充电过程中桩按策略发MeterValues用户拔枪后桩发StopTransaction再发StatusNotification把枪口状态改回空闲。中间如果后台想限制功率会发SetChargingProfile如果网络断了桩可能靠本地授权列表继续放行等恢复后再补状态。这条流里StartTransaction和StopTransaction是交易主线MeterValues是计量采样StatusNotification是设备状态Heartbeat是连接保活。它们经常出现在同一段日志里但职责不同。把这几类消息混在一起看就容易出现“心跳正常所以交易一定正常”的误判。心跳只能说明连接还活着不能说明授权过了、枪插好了、电表在走。提示排查充电失败时先按“上线、授权、启动交易、计量、停止交易”的顺序看消息不要一上来就翻全部字段。5. 容易踩坑的易混概念OCPP 1.6J、1.6、JSON 与智能充电的区别5.1 OCPP 1.6J 和 OCPP 1.6 是一回事吗易混点很多人把 1.6J 当成 1.6 的“另一个小版本”以为 1.6J 的所有消息都和 1.6 不同。为什么混名字只差一个字母资料标题又常把两者写在一起。怎么区分1.6 是协议版本1.6J 强调 JSON over WebSocket 这种传输绑定。业务动作、功能配置文件、消息语义大体沿用 1.6 的约定差异主要在承载方式。看对接文档时先确认对方说的是“1.6 的 SOAP 绑定”还是“1.6J 的 JSON 绑定”再谈字段。这个区别在实际联调里很要命。后台按 1.6J 的 JSON 消息准备桩却只支持另一种绑定双方消息名一样也接不上。反过来看到ocpp1.6这个 WebSocket 子协议标识也不要以为它等于“所有 1.6 功能都自动支持”。子协议说明承载版本功能还要看桩声明的配置文件和具体实现。5.2 用了 JSON 就等于用了 OCPP 1.6J 吗易混点看到报文是 JSON就认为这是 OCPP 1.6J。为什么混1.6J 确实用 JSONJSON 又太常见。怎么区分JSON 只是数据格式OCPP 1.6J 还规定了消息信封、动作名、字段名、方向、状态值和交互顺序。你自己写一个 JSON 发过去字段名对不上、消息类型不是 2/3/4、唯一编号不配对对方不会把它当 OCPP 消息处理。更实际的说法是JSON 让消息可读但可读不等于合规。StartTransaction的字段拼错一个大小写或者时间没按 UTC 写后台可能直接回错误。学习资料里的消息字典就是用来对字段的不是用来欣赏 JSON 排版的。5.3 智能充电就是“充电更快”吗易混点把智能充电理解成快充、超充或者“后台一开就充得更猛”。为什么混“智能”两个字听起来像优化速度。怎么区分在 OCPP 1.6J 里智能充电更多是功率管理和负荷调度。中央系统通过SetChargingProfile下发充电配置文件桩按计划限制或调整功率目的是配合电网容量、分时电价、场站总负荷而不是无条件拉满。充电配置文件里会涉及配置文件编号、堆叠层级、用途、计划类型和时间段。后台可以用它做“这个时段最多 30 千瓦”“这辆车优先、那辆车排队”这类策略。桩支持智能充电不等于它自己能发电也不等于所有车都能立刻快充。把智能充电当成“提速按钮”在现场容易做出错误预期。5.4 心跳、状态通知、仪表值是一类消息吗易混点都叫“上报”就以为可以互相替代。为什么混它们都由充电点发给中央系统日志里又经常挨着出现。怎么区分Heartbeat管连接保活证明桩还在StatusNotification管连接器或设备状态告诉后台枪口可用不可用MeterValues管计量采样告诉后台电量、功率等读数。三者职责不同缺一条都不能用另一条补。比如后台显示枪口“空闲”可能是StatusNotification报的也可能是交易结束后推断的但用户能不能启动还要看授权和连接器可用性。心跳正常只说明网络没断不代表枪没故障。计量值正常只说明电表在采样不代表交易编号一定对。把这三类消息分开看排障时才不会把“连接正常”误当成“业务正常”。5.5 本地授权列表和中央授权是一回事吗易混点以为桩能授权就等于后台授权一定通。为什么混两者都叫“授权”结果都表现为“放行充电”。怎么区分Authorize是桩把 idTag 发给中央系统问结果本地授权列表是桩自己存一份名单网络断了也能按名单放行。后台可以用SendLocalList下发名单用GetLocalListVersion查版本用ClearCache清授权缓存。离线行为是这份资料专门讲的一节原因就在这里。网络不稳时桩不能因为连不上后台就完全罢工但也不能无限放行。本地名单的版本、有效期、增删策略都要和后台对齐。把本地授权当成“后台授权的缓存”不够准确它更像应急名单什么时候用、用到什么程度需要业务规则兜底。6. 什么时候该用这份 OCPP 1.6J 资料边界、场景和一个笨办法6.1 适合把它放在手边的三类场景第一类是对接充电桩后台的开发者。你拿到一段日志里面有BootNotification.conf、StartTransaction.req、MeterValues.req想知道每个字段在业务里起什么作用这份资料按消息字典查最快。第二类是充电桩侧的嵌入式或协议实现人员。你要确认StatusNotification有哪些状态、StopTransaction的结束原因怎么填、connectorId为 0 代表什么目录能直接定位。第三类是运营或测试人员。你不需要写代码但要看懂“为什么这把枪一直显示准备中”“为什么远程启动没反应”按消息流对照比问人更稳。6.2 别硬套的边界这份资料不是充电桩硬件维修手册也不负责告诉你某个厂家的板子怎么接线。它讲的是通信约定不是电气安全规范。它也不是计费系统的完整设计文档MeterValues能给出计量采样但费率、账单、结算规则还要业务系统自己定。遇到具体厂家的私有扩展先看DataTransfer和对方文档不要硬往标准字段里塞。适合不适合查消息字段、方向、状态值代替硬件维修手册对齐后台与桩的联调顺序代替计费结算规则理解远程控制、预约、智能充电的边界判断某款桩实际功率能力我自己的笨办法是每次遇到陌生消息先不急着看全部字段只问三件事——谁发的、回应里哪个状态会影响下一步、这条消息在交易链的哪个位置。栽过一次跟头之后我每次联调都强制走一遍“上线、授权、启动、计量、停止”的顺序再看远程指令省下不少在日志里瞎翻的时间。这份 OCPP 1.6J 资料适合放在手边当查阅手册完整目录和消息定义在下载处取用按章节翻比背概念更省事。希望帮到你。本文还有配套的精品资源点击获取