简电云 | OCPP 1.6充电桩平台接入OCMF签名计量数据的实现方案

简介: OCMF(开放充电计量格式)为OCPP 1.6平台提供可验证的签名计量数据,通过数字签名保障电表读数、时间、用户及设备身份的真实性与完整性,支撑账单审计与争议处理,实现“可信计量”落地。

在充电平台中,OCPP 1.6 解决的是充电设备与中心系统之间的通信问题,但“收到一个电量值”并不等于“能够证明该电量值没有被修改”。当计量数据需要用于账单核验、争议处理或审计时,还需要一条从计量设备到验证端的完整证据链。

OCMF(Open Charge Metering Format)提供了一种可读的签名计量数据格式。它把表计读数、时间、用户标识、设备身份和交易阶段组织成 JSON 数据,再由计量侧对原始数据进行数字签名。OCPP 1.6 则可以利用 SignedData 格式承载这段数据。

本文以 OCMF 1.0.1 Draft 为参考,说明如何在现有 OCPP 1.6 平台中完成 OCMF 数据的接入、存储、校验和业务关联。文中的设计重点是工程实现,不替代具体地区的计量法规、型式批准或合规认证要求。

一、先明确两个协议的职责

OCPP 1.6 和 OCMF 处在不同层次:

  • OCPP 1.6 负责设备与平台之间的消息交互,包括启动交易、上传采样值和结束交易;
  • OCMF 负责描述可验证的计量记录,并通过数字签名证明记录在签名后未被修改;
  • TLS 保护数据传输过程,OCMF 签名保护计量数据本身,两者不能相互替代。

平台接入时应保留两条数据链。普通的 Raw 数值用于实时功率曲线、告警和运营统计;SignedData 用于账单证据、离线验签和争议复核。不要因为已接入签名数据,就删除原有的普通采样值。

二、OCMF 数据结构

一条 OCMF 记录由三个部分组成,使用竖线分隔:

OCMF|<待签名数据 JSON>|<签名信息 JSON>

下面是一条经过简化的示例。签名值仅用于展示结构,不代表真实计算结果。

OCMF|{"FV":"1.0","GI":"MeterGateway","GS":"GW00001","PG":"T1001","MS":"METER00001","IS":true,"IL":"TRUSTED","IF":["OCPP_AUTH_TLS"],"IT":"ISO14443","ID":"04A1B2C3D4E5F6","CT":"CBIDC","CI":"CP001 1","RD":[{"TM":"2026-09-16T10:30:00,000+0800 S","TX":"B","RV":1256.32,"RI":"1-0:1.8.0","RU":"kWh","RT":"AC","EF":"","ST":"G"}]}|{"SA":"ECDSA-secp256r1-SHA256","SE":"hex","SM":"application/x-der","SD":"3045..."}

常用字段可以分为六组:

分组 字段 含义
格式与设备 FVGIGSGV 格式版本、签名网关标识、序列号和软件版本
分页 PG 记录序号,T 表示交易上下文,F 表示非交易计量上下文
表计 MVMMMSMF 表计厂商、型号、序列号和固件版本
用户关联 ISILIFITID 用户是否关联、可信级别、关联方式、标识类型和标识值
充电点 CTCI 充电点标识类型和标识值
读数 RD 一个或多个带时间、交易阶段、数值、单位和状态的读数

RD 数组中的关键字段包括:

  • TM:ISO 8601 风格的时间和时间状态,状态 S 表示已同步,U 表示未知或未同步;
  • TX:交易阶段,B 为开始,C 为充电中,E 为结束,T 为费率切换,X 为发生异常;
  • RV:读数值;
  • RI:OBIS 标识,例如有功输入电能;
  • RU:单位,通常为 WhkWh
  • EF:不可用于结算的量,例如 E 表示能量异常,t 表示时间异常;
  • ST:表计状态,G 表示正常,其他值可表示超时、断开、被替换或读数错误等状态。

OCMF 允许同一签名记录包含多个读数,也允许后续读数省略与前一读数相同的部分字段。因此,平台展示数据时可以做字段继承,但验签时必须使用设备上传的原始文本。

三、OCPP 1.6 的承载方式

OCPP 1.6 的 MeterValuesStopTransaction 都可以携带 MeterValue,其中 SampledValue.format 支持 RawSignedData。接入 OCMF 时,推荐在同一采样时刻同时上传普通值和签名值。

1. 交易开始

StartTransaction.req 只有整数类型的 meterStart,不能直接承载 OCMF 字符串。设备应先完成开始读数并保留 OCMF 记录,在收到平台返回的 transactionId 后,立即通过 MeterValues.req 补传交易开始记录。

[
  2,
  "msg-1002",
  "MeterValues",
  {
   
    "connectorId": 1,
    "transactionId": 78231,
    "meterValue": [
      {
   
        "timestamp": "2026-09-16T02:30:00.000Z",
        "sampledValue": [
          {
   
            "value": "1256320",
            "context": "Transaction.Begin",
            "format": "Raw",
            "measurand": "Energy.Active.Import.Register",
            "unit": "Wh"
          },
          {
   
            "value": "OCMF|{...}|{...}",
            "context": "Transaction.Begin",
            "format": "SignedData",
            "measurand": "Energy.Active.Import.Register",
            "unit": "kWh"
          }
        ]
      }
    ]
  }
]

2. 交易过程

周期采样、费率切换或异常事件通过 MeterValues.req 上送。普通运营曲线可以保持较短周期;签名记录则根据计量要求在交易开始、结束、费率切换和必要的中间节点生成。

配置项可按业务要求设置。例如,15 分钟对齐采样可以使用:

ClockAlignedDataInterval = 900
MeterValuesAlignedData = Energy.Active.Import.Register

这只是常见配置,不应把 15 分钟固定写入平台逻辑。实际间隔需要根据计费规则、设备能力和当地要求确定。

3. 交易结束

结束记录优先放入 StopTransaction.req.transactionData,同时保留 meterStop 供原有业务逻辑使用。平台应允许签名数据与停止消息异步到达:设备断网重传时,消息顺序可能与理想流程不同。

[
  2,
  "msg-1088",
  "StopTransaction",
  {
   
    "transactionId": 78231,
    "timestamp": "2026-09-16T03:20:00.000Z",
    "meterStop": 1278450,
    "reason": "Local",
    "transactionData": [
      {
   
        "timestamp": "2026-09-16T03:20:00.000Z",
        "sampledValue": [
          {
   
            "value": "OCMF|{...}|{...}",
            "context": "Transaction.End",
            "format": "SignedData",
            "measurand": "Energy.Active.Import.Register",
            "unit": "kWh"
          }
        ]
      }
    ]
  }
]

四、平台总体设计

平台可以拆分为五个处理环节:

充电设备
  -> OCPP 接入层
  -> 原始报文与 OCMF 证据存储
  -> OCMF 解析及验签服务
  -> 交易关联与完整性检查
  -> 账单、审计和证据导出

OCPP 接入层

接入层完成 OCPP Schema 校验、设备身份认证、消息去重和应答。检测到 format=SignedData 后,只做长度限制和基础格式检查,然后把 value 原样交给证据存储。接入层不应对 OCMF 字符串执行格式化、转义还原后的二次拼接或 JSON 规范化。

原始证据存储

建议同时保留以下三类内容:

  1. 完整 OCPP 原始报文;
  2. SampledValue.value 提取的 OCMF 原始字符串;
  3. 解析结果、验签结果和所用公钥版本。

原始证据应采用只追加或具备防篡改能力的存储策略。数据库中的解析字段用于查询,不能替代原文。

验签服务

验签服务负责格式识别、字段校验、公钥检索、密码学验证和结果归档。建议使用成熟密码学库,不自行实现椭圆曲线运算。

交易完整性服务

单条签名验证成功,只能说明该条记录没有被修改。平台还必须检查一组记录是否构成完整交易,包括开始和结束标记、分页连续性、设备身份一致性、时间状态以及异常标志。

五、数据表设计

下面给出一组精简的数据模型,实际字段可按现有平台调整。

CREATE TABLE signed_meter_record (
    id                 BIGINT PRIMARY KEY,
    charge_point_id    VARCHAR(64) NOT NULL,
    connector_id       INT NOT NULL,
    transaction_id     BIGINT,
    ocpp_message_id    VARCHAR(64) NOT NULL,
    received_at        TIMESTAMP NOT NULL,
    ocmf_raw           TEXT NOT NULL,
    ocmf_sha256        CHAR(64) NOT NULL,
    format_version     VARCHAR(16),
    pagination         VARCHAR(64),
    gateway_serial     VARCHAR(128),
    meter_serial       VARCHAR(128),
    signature_algorithm VARCHAR(64),
    verify_status      VARCHAR(32) NOT NULL,
    verify_reason      VARCHAR(256),
    public_key_id      BIGINT,
    UNIQUE (charge_point_id, ocmf_sha256)
);
CREATE TABLE meter_public_key (
    id                 BIGINT PRIMARY KEY,
    identity_type      VARCHAR(32) NOT NULL,
    gateway_serial     VARCHAR(128),
    meter_serial       VARCHAR(128),
    charge_point_ref   VARCHAR(128),
    algorithm          VARCHAR(64) NOT NULL,
    public_key_data    TEXT NOT NULL,
    valid_from         TIMESTAMP NOT NULL,
    valid_to           TIMESTAMP,
    status             VARCHAR(16) NOT NULL
);

ocmf_sha256 主要用于幂等去重和证据定位,不等同于 OCMF 的签名验证结果。公钥表需要保留有效期和历史版本,否则设备换表或换密钥后将无法复核旧交易。

六、验签流程

第一步:保留原文并切分区段

确认字符串以 OCMF| 开头,并按协议边界分离待签名数据和签名信息。因为 OCMF 禁止在区段内部使用竖线,所以可以据此识别边界。应限制总长度、JSON 深度和数组大小,避免异常报文占用过多资源。

第二步:解析但不重建待签名内容

将待签名数据解析为对象,用于字段校验和业务查询;与此同时,记录它在原字符串中的精确字节范围。真正计算摘要时使用原始区段,不使用 JSON.stringify 或其他序列化结果。

下面的伪代码强调了这一点:

VerificationResult verify(String ocmfRaw) {
   
    OcmfSections sections = splitWithoutReformatting(ocmfRaw);

    OcmfPayload payload = jsonParser.parse(sections.payloadJson());
    OcmfSignature signature = jsonParser.parse(sections.signatureJson());
    validateRequiredFields(payload, signature);

    PublicKey key = keyRepository.findEffectiveKey(
        payload.gatewaySerial(),
        payload.meterSerial(),
        payload.chargePointIdentity(),
        payload.readingTime()
    );

    byte[] signedBytes = sections.payloadJson()
        .getBytes(StandardCharsets.UTF_8);

    return cryptoProvider.verify(
        signature.algorithmOrDefault(),
        key,
        signedBytes,
        decodeSignature(signature)
    );
}

具体签名输入范围应以设备实现所遵循的 OCMF 版本及互操作测试结果为准。平台上线前必须用设备厂商提供的正向和反向测试向量确认:少一个空格、改变字段顺序或改变数字表示后,验证应当失败。

第三步:选择算法并解码签名

OCMF 1.0.1 Draft 列出了多种 ECDSA 曲线和 SHA-256 组合。未提供 SA 时需要按对应版本的默认值处理;未提供 SE 时默认按十六进制解码;SM 的默认签名结构为 ASN.1 DER。

工程中常见的错误是把 DER 编码的 ECDSA 签名当成固定长度的 r || s。两者不是同一种编码,必须根据 SM 和设备约定正确解码。

第四步:定位公钥

公钥不应直接信任同一条待验证消息中的临时值。OCMF 草案要求公钥通过独立渠道与表计、签名网关或充电点建立关联。平台可以按以下组合查找:

  • 表计内置签名模块:使用 MS
  • 单枪网关:使用 GSMS
  • 一个网关管理多个充电点:使用 GS + MS
  • 已建立充电点映射:使用 CT + CI

导入公钥时需要校验来源、算法、启用时间和停用时间。任何人工替换都应留下审计记录。

第五步:验证交易完整性

密码学验签成功后,再执行交易级规则:

  • 第一条有效记录包含 TX=B
  • 最后一条有效记录包含 TX=E,或更具体的本地结束、远程结束、异常结束代码;
  • PG 在同一交易上下文中连续递增,不重复、不倒退;
  • 所有记录来自相同的签名源和表计;
  • 读数时间不倒退,时间状态满足计费要求;
  • 结束读数不小于开始读数,且差值与账单电量在允许精度内一致;
  • EFSTTX=X 出现时,交易进入人工复核或异常处理流程;
  • OCMF 内部身份、OCPP 连接和平台交易三者的映射一致。

只有“单条验签通过”和“交易完整性通过”同时成立,平台才能把记录标记为可用于后续结算核验。

七、状态与异常处理

建议把验签结果设计成明确的状态机,而不是一个布尔值:

状态 含义 建议处理
PENDING 等待解析或等待公钥 异步重试,不阻塞 OCPP 应答
VALID 签名与字段校验通过 继续交易完整性检查
INVALID_SIGNATURE 密码学验证失败 保留原文,禁止自动用于可信结算
KEY_NOT_FOUND 找不到有效公钥 检查设备资产和密钥登记
FORMAT_ERROR 结构或必填字段错误 记录设备、固件和错误位置
INCOMPLETE_CHAIN 开始、结束或分页不完整 等待迟到消息,超时后转异常
METER_ERROR 表计状态或错误标志异常 按业务规则复核或终止结算

OCPP 请求的接收结果和 OCMF 验签结果应分开处理。平台可以先正常响应 OCPP 消息,再异步验签;否则密码学计算、公钥服务抖动或批量补传可能拖慢设备通信线程。

八、幂等、补传与顺序问题

充电设备断网后可能重复发送同一条消息,也可能把结束记录先于某些中间记录送达。平台不应依赖数据库自增主键判断业务顺序。

推荐使用 chargePointId + SHA-256(ocmfRaw) 作为签名记录的幂等键,并保留 OCPP uniqueId 作为消息层追踪信息。交易内顺序以 PG 和读数时间共同判断。对于暂时缺少开始记录或公钥的交易,可以进入等待状态,在补传数据到达后重新执行完整性检查。

需要注意,PG 是签名源维护的连续计数,不一定等于 OCPP 的 transactionId。两者只能建立关联,不能互相替代。

九、安全与隐私设计

OCMF 可能包含 RFID UID、账户标识或其他用户关联信息。平台接入后应执行以下控制:

  • 原始证据仅向必要的服务账号开放;
  • 查询页面默认对 ID 脱敏,避免在日志中输出完整标识;
  • 密钥、验签记录和人工处理记录均纳入审计;
  • 设置原始报文大小、字段长度和解析深度上限;
  • 对验签服务进行资源隔离,避免构造报文影响 OCPP 主链路;
  • 按适用的数据保留要求设置归档与删除策略。

需要区分“脱敏展示”和“修改证据”。原始 OCMF 字符串不能被改写;脱敏只应发生在查询视图或导出副本中。

十、测试方案

上线前至少覆盖以下测试:

正常场景

  • 交易开始、中间采样和结束记录全部验签成功;
  • 同一 MeterValue 同时包含 RawSignedData
  • StopTransaction.transactionData 正常入库;
  • 十六进制和 Base64 签名按声明正确解码;
  • 设备换表或换密钥后,历史交易仍能使用旧公钥复核。

篡改场景

  • 修改一个读数数字;
  • 改变数字的小数位表示;
  • 增删空格或调整 JSON 字段顺序;
  • 替换表计序列号;
  • 使用错误公钥或失效公钥。

以上情况均应导致验签失败或明确的密钥错误,且原始数据仍可追溯。

链路异常场景

  • OCPP 消息重复发送;
  • 中间分页缺失或重复;
  • 结束消息先到、中间消息后到;
  • 平台重启后继续处理待验签记录;
  • 公钥服务暂时不可用;
  • 时间未同步、表计断开、读数错误或交易异常结束。

十一、分阶段落地建议

第一阶段先完成透明接入:识别 SignedData、原样存储 OCMF、建立设备和表计映射,不改变现有结算逻辑。

第二阶段接入公钥管理和异步验签,形成可查询的验证结果,同时通过影子模式比较 OCMF 电量与现有 meterStart/meterStop 的差异。

第三阶段加入交易完整性规则、异常工作流和证据导出。经过足够的设备互操作测试后,再决定哪些业务环节可以依赖验证结果自动执行。

结语

在 OCPP 1.6 平台中接入 OCMF,难点不在于增加一个 SignedData 字段,而在于保护原始字节、可靠管理公钥,并从多条记录中还原完整交易。一个稳健的实现应同时保留普通计量值与签名证据,把“消息接收成功”“单条签名有效”和“交易证据完整”设计成三个独立判断。

只要平台从一开始就坚持原文不可改写、公钥来源可信、分页连续可检查、异常状态可追溯,后续扩展账单核验、争议处理和审计能力时就不需要重新改造底层数据链路。

参考资料

  • Open Charge Alliance:《Open Charge Point Protocol 1.6》
  • SAFE / DKE:《Open Charge Metering Format,Version 1.0,Revision 1.0.1 Draft》
  • IEC 62056-6-1、IEC 62056-6-2:OBIS 相关标准
相关文章
|
7天前
|
人工智能 API 内存技术
刚刚 DeepSeek V4.1 Flash 开启内测,1 分钟教你用上!
刚刚 DeepSeek 内测群发布了 DeepSeek V4.1 Flash 中间版本内测的消息,这次的模型采用了新的结构,原生支持多模态、能力更强、速度更快、且成本更低。
1814 13
|
7天前
|
人工智能 自然语言处理 安全
阿里云千问办公 QwenWork详细介绍:产品核心能力、典型场景、价格及常见问题解答
千问办公是阿里云推出的一站式AI办公平台,主打"不止于对话,更注重交付",依托通义千问旗舰大模型,用户一句话即可完成数据分析、PPT生成、视频剪辑等复杂任务,直接输出可用成果。产品深度打通钉钉生态与企业OA,覆盖桌面端、网页端,提供企业标准版198元/人/月等多档订阅方案,新用户注册即赠2000积分,适配工程师、HR、财务等多职业办公场景,成为能动手干活的"全能AI同事"。
|
13天前
|
网络协议 Linux iOS开发
【2026实测】Wireshark下载+安装+汉化+使用教程(图文版,巨详细)
Wireshark 是一款免费开源的网络协议分析工具,可实时捕获、解析并可视化数据包,助你诊断网络故障、分析通信协议(如HTTP、DNS、TCP等)。支持Windows/macOS/Linux,含中文界面,新手入门便捷。(239字)
|
12天前
|
人工智能 运维 BI
阿里云千问办公QwenWork深度解析:基于Qwen3.8,六大核心能力重构企业全自动化工作流与计费选型指南
传统AI办公工具大多停留在对话问答、文档摘要、简单文案生成层面,只能完成单点碎片化任务,无法自主拆解复杂业务流程,很难串联多工具、多文档、外部业务系统完成端到端完整工作交付。很多企业在落地AI办公的时候,需要组合多款不同工具,来回切换界面,手动复制粘贴中间结果,智能化改造落地门槛居高不下。千问办公QwenWork是整合多款智能体产品能力打造的一体化企业办公智能体平台,底层基座依托Qwen3.8大模型,打通桌面端Agent、云端Agent、企业协同Agent三种运行形态,不再局限简单问答,接收业务目标之后自主拆解任务步骤,调用各类工具,处理文档、表格、浏览器自动化、数据查询,直接输出可交付的办公
1647 3
|
7天前
|
人工智能
千问办公官网入口:阿里AI办公QwenWork产品页和免费网页端链接
千问办公官网含两大入口:一是网页端(qwenwork.cn),即开即用,支持浏览器直接访问;二是阿里云产品页 https://t.aliyun.com/U/JNKJuO 提供免费/付费版详情、功能介绍及使用指南。
|
9天前
|
SQL 人工智能 前端开发
QoderWake 1.0 正式发布:从桌面里的 Agent,到工作现场的数字员工
QoderWake v1.0正式发布:企业级数字员工团队平台。支持“一句话建岗”,预置10类特训岗位;Waker常驻钉钉/飞书群,@即响应、自动协作、跨任务记忆;具备定时/事件/API多触发方式与统一任务看板;已沉淀27.6万条记忆、12.3万项技能,助力组织实现人机协同增效。
790 2
|
6天前
|
缓存 测试技术 API
DeepSeek V4.1 Flash 内测接入:改个模型名即可调用(附代码)
DeepSeek V4.1 Flash 内测不用申请,base_url 不变、改个模型名就能调,9/10 到期。本文讲清接入、计费限流与多模态注意点。
812 0
DeepSeek V4.1 Flash 内测接入:改个模型名即可调用(附代码)
|
14天前
|
缓存 数据可视化 开发工具
DeepSeek Harness 怎么更新?dsh 更新完整指南:更新本体(npx、npm、源码)与更新插件两种方式
DeepSeek Harness 的更新分两层:本体更新(npx 自动最新、npm update -g、源码 git pull)与插件更新(插件市场点更新、命令行覆盖安装)。本文按「准备 → 更新本体 → 更新插件 → 更新后检查」四步走,覆盖新手常见疑问。
1607 1
DeepSeek Harness 怎么更新?dsh 更新完整指南:更新本体(npx、npm、源码)与更新插件两种方式
|
21天前
|
人工智能 自然语言处理 安全
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
本文聚焦阿里云2026年推出的三款自研AI办公产品,清晰拆解千问办公、Qoder Teams、Qoder CN的差异化定位与能力边界:千问办公主打职场全场景提效,支持自然语言指令一键完成PPT生成、数据分析等高频办公任务;Qoder Teams面向程序员团队,深度整合AI代码生成、团队协同与企业知识库能力;Qoder CN则专为金融、政务等强合规场景打造,实现数据不出境与VPC私有化部署。文章同步给出分场景选型指南与最新活动定价,帮助不同类型的企业按需组合产品,实现业务岗、研发岗与强合规场景的AI能力全覆盖。
3989 5
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
|
12天前
|
人工智能 自然语言处理 安全
阿里云AI数智鉴密:AI 生成内容如何拿到一张"防篡改的身份证"
隐形水印 + C2PA签名:让AI生成内容“持证上岗”。
1156 0