Files

11 KiB
Raw Permalink Blame History

CCU–POS VTK 串口结算功能设计说明(草案)

版本:v0.1
协议参考:vtk-protocol-en-1.23.pdfVTK protocol 1.23


1. 应用场景概述

  • 角色

    • VMCVending Machine Controller:本项目中的 CCU 主控,负责充电控制、计量和向 POS 发起扣款 / 结算请求。
    • POS 终端:支持 VTK 协议的支付终端,完成银行卡 / 钱包扣款,并把结果回传给 CCU。
  • 业务流程(高层逻辑)

    1. 车主在充电桩侧操作“启动充电”(扫码 / 刷卡 / 远程指令等),CCU 准备启动充电流程。
    2. CCU 根据配置计算 预扣款金额(例如 50 元,可配置)。
    3. CCU 通过 串口上的 VTK 协议 向 POS 发送“预扣款请求”消息,请求冻结该金额。
    4. POS 完成预扣并返回“通过 / 拒绝 / 超时”等结果:
      • 通过:CCU 进入正常充电流程。
      • 拒绝:CCU 不启动充电,向用户提示相应原因。
    5. 充电完成(正常结束 / 故障结束 / 用户中止)后,CCU 计算 最终充电金额(按电量 / 时间 / 固定服务费等计费规则)。
    6. CCU 再次通过 VTK 协议向 POS 发送“结算请求”,携带最终金额以及会话标识。
    7. POS 根据最终金额完成扣款 / 退款(与预扣差额),返回结算结果。
    8. CCU 记录最终结算结果到本地订单 / 日志系统,并更新 UI / 平台状态。
  • 通信方式

    • 物理层:串口(UART,波特率等推荐按 VTK 文档默认值:115200 8N1,无流控
    • 链路层:可选择直接使用原始串口帧结构(1F 起始 + 长度 + 协议号 + TLV + CRC16)。
    • 应用层:严格遵循 VTK base protocol0x96FB/0x97FB)的 TLV 编码要求。

2. VTK 协议要点(与本项目相关部分)

2.1 基本帧格式(串口模式)

参考文档第 2 章,串口下消息帧结构:

  • Start1 字节,固定 0x1F
  • Length:2 字节,大端,表示“后续所有数据长度(不含 CRC16)”
  • Protocol discriminator2 字节,大端
    • 0x96FBVMC → POS
    • 0x97FBPOS → VMC
  • Application message0..65533 字节,BER TLVISO/IEC 8825-1
  • CRC162 字节,大端,CRC16-CCITT(初始值 0xFFFF),从 Start 到 TLV 最后一字节

2.2 TLV 参数

VTK base protocol 中应用消息是多个 TLV 参数的组合:

  • Tag:1~3 字节(此协议中基本为单字节 Tag,例如 0x01 Message name、0x04 Amount 等)
  • Length1~3 字节
  • Value:具体值(ASCII / Binary / UTF-8

本项目中 优先使用的 Tag(参考文档 3.1):

  • 0x01Message nameASCII 3)—— 如 "CDP", "CRD", "INF", "PRS" 等。
  • 0x03Operation numberASCII 数字,8 位)—— 可做一次充电会话的 ID。
  • 0x04Amount in minor currency unitASCII,金额的“最小货币单位”,例如分)。
  • 0x11:Local time(可选,用于时钟同步)。
  • 0x12System information(可选,用于 POS 侧展示桩信息)。

后续业务实现只需先支持必要的 Tag,留出扩展空间即可。


3. 业务消息与状态机设计(草案)

3.1 关键业务实体

  • ChargeSession(充电会话)

    • sessionId:对应 VTK 的 Operation numberTag 0x03)。
    • gunNo:枪号(0/1/...)。
    • preAuthAmount:预扣款金额(单位:分)。
    • finalAmount:最终金额(单位:分)。
    • stateIdle / PreAuthPending / PreAuthOk / Charging / SettlePending / Settled / Failed
  • VTKOperation

    • messageNameTag 0x01):例如 "CDP"(预扣款)、"CRD"(结算)等。
    • directionVMC→POSPOS→VMC
    • tlvList:一个 TLV 参数列表。

3.2 建议消息映射(可根据实际对接调整)

  • 预扣款请求CCU→POS

    • Message name (0x01)"CDP"(或自定义,如 "CHP"Charge PreAuth
    • Operation number (0x03):本次充电会话 ID(ASCII 数字)
    • Amount (0x04):预扣款金额,单位“分”,例如 5000 表示 50.00 元
  • 预扣款响应POS→CCU

    • Message name (0x01)"CDP"(同请求)
    • Operation number (0x03):与请求一致
    • Amount (0x04):实际冻结金额(可与请求相同)
    • 结果参数:可以使用 System information 或自定义扩展的 Simple data block0x0D)中定义结果码,例如:
      • 0Approved
      • 1Declined
      • 2Timeout
  • 结算请求CCU→POS

    • Message name (0x01)"CRD"Charge Debit / Refund
    • Operation number (0x03):与本会话相同
    • Amount (0x04):实际消费总金额(分)
  • 结算响应POS→CCU

    • Message name (0x01)"CRD"
    • Operation number (0x03):同请求
    • Amount (0x04):最终扣款金额
    • 结果码(同上)

3.3 CCU 侧状态机(简化)

  1. Idle

    • 等待用户操作(插枪、刷卡、平台下发启动命令)。
  2. PreAuthPending

    • 组包 VTK CDP 预扣款请求,通过串口发给 POS。
    • 等待响应(配置超时,例如 15s),期间可处理心跳 / 重发。
  3. PreAuthOk

    • 收到 POS 批准预扣款,更新内部状态,允许充电流程进入 Charging
  4. Charging

    • 现有充电流程不变(BMS/流控/计量)。
  5. SettlePending

    • 充电结束,计算 finalAmount,组包 VTK CRD 结算请求,发送给 POS。
    • 等待响应;失败可重试若干次或降级处理(仅记录本地订单,提示用户到平台查询)。
  6. Settled / Failed

    • Settled:记录成功订单,通知平台/界面。
    • Failed:记录失败原因(网络/卡拒绝/超时),可与平台对账或人工处理。

4. 模块划分与文件结构建议

CCU601E_RUN/app/pos_vtk 目录下建议创建如下模块(后续实现时使用):

  1. 基础协议层

    • vtk_frame.c / vtk_frame.h
      • 串口帧封装 / 解封装(1F 起始、长度、协议号、CRC16)。
      • CRC16-CCITT 实现(参考文档第 5 章)。
    • vtk_tlv.c / vtk_tlv.h
      • TLV 编码 / 解码(Tag/Length/Value)。
      • 提供便捷接口:addAsciiParam(tag, QString), getAsciiParam(tag, ...) 等。
  2. 业务协议层

    • vtk_pos_protocol.c / vtk_pos_protocol.h
      • 构造/解析 预扣款请求/响应结算请求/响应系统信息 等应用消息:
        • buildPreAuthRequest(session, preAuthAmount, QByteArray &outFrame)
        • parsePreAuthResponse(const QByteArray &frame, VtkResult &out)
        • buildSettleRequest(...) / parseSettleResponse(...)
  3. 会话与状态机层

    • pos_vtk_service.c / pos_vtk_service.h
      • 维护每把枪的 ChargeSession 状态:
        • posVtk_startPreAuth(gunNo, amount)
        • posVtk_onFrameReceived(frame) —— 调用基础解析,然后驱动状态机
        • posVtk_notifyChargeEnd(gunNo, finalAmount) —— 进入结算流程
      • 与现有 flowctrl_task/collect_task/meter_calculate/plat_comm_task 对接。
  4. 串口接入层

    • 若已有串口任务(如 uart_task),只需在串口接收回调中把 VTK 帧交给 vtk_frame 层解析。
    • 若没有,可在 app_initplat_comm_task 下新增 POS 串口任务:
      • 周期读取串口缓存、拼帧、调用 posVtk_onFrameReceived

5. 与现有 CCU 模块的集成点

  • 启动充电:在当前启动充电逻辑中(flowctrl / bms / collect),增加“调用 posVtk_startPreAuth”步骤,并根据其结果决定是否允许进入充电状态。
  • 停止充电:在充电任务或计量模块中,当确定实际消费金额后,调用 posVtk_notifyChargeEnd 进入结算流程。
  • 告警与 UI 提示
    • 预扣款失败:在 UI 或平台上显示“支付预授权失败,请重试或更换支付方式”。
    • 结算失败:记录订单异常状态,提示用户可联系运营方处理。

6. 后续实施步骤建议

  1. 确认业务映射:与 POS 提供方确认使用的 Message nameCDP/CRD/INF 等)、结果码格式以及参数集合。
  2. 实现基础协议层vtk_frame + vtk_tlv,并通过单元测试校验:
    • CRC 计算正确。
    • TLV 编解码对齐文档。
  3. 实现预扣款 / 结算消息构造与解析vtk_pos_protocol
  4. 实现 POS 会话状态机pos_vtk_service,并与现有充电流程打通(只改入口/出口逻辑,尽量不动核心 BMS/MDU 代码)。
  5. 集成串口任务:选定 UART 口,完成收发调试(先用日志工具验证 VTK 帧格式)。
  6. 与实际 POS 联调:根据联调结果调整错误码处理、超时重试策略等。

7. 示例报文

以下示例仅展示 TLV 内容和串口帧结构,CRC16 按实现自动计算,示例中不逐字列出。

7.1 预扣款请求(CDP

  • 业务参数:

    • Message name"CDP"Tag 0x01
    • Operation number"12345"Tag 0x03,十进制 ASCII
    • Amount"5000"Tag 0x04,表示 50.00 元)
  • TLV 区段(十六进制):

    • 01 03 43 44 50
      • Tag=0x01Len=0x03Value="CDP"
    • 03 05 31 32 33 34 35
      • Tag=0x03Len=0x05Value="12345"
    • 04 04 35 30 30 30
      • Tag=0x04Len=0x04Value="5000"
  • 串口帧结构:

    • 1F 起始字节
    • 00 LL Length2 字节,大端,= ProtocolDisc + TLV 长度)
    • 96 FB Protocol discriminatorVMC→POS
    • 01 03 43 44 50 03 05 31 32 33 34 35 04 04 35 30 30 30 TLV 数据
    • CC CC CRC16-CCITT(由代码计算)

7.2 结算请求(CRD

  • 参数示意:
    • Message name"CRD"0x01
    • Operation number:与预扣款相同 "12345"0x03
    • Amount:最终金额 "4200"0x04,表示 42.00 元)

TLV 结构与上例相同,仅值不同。

7.3 响应报文(POS→CCU

  • 假设 POS 对预扣款返回:
    • Message name"CDP"
    • Operation number"12345"
    • Amount"5000"
    • ResultTag 0x0DLength=1Value=0x00Approved

TLV 区段:

  • 01 03 43 44 50 CDP
  • 03 05 31 32 33 34 35 Operation number
  • 04 04 35 30 30 30 Amount
  • 0D 01 00 Simple data block,结果码=0

串口帧中的 Protocol discriminator 为 0x97FBPOS→VMC)。


说明:本文件为第一版设计草案和实现说明,后续在实际联调和业务确认过程中,可根据需要继续细化:

  • 完善错误码与 POS 侧状态码的映射
  • 增加更多业务消息(如 INF、PRS 等)
  • 完善异常流程(网络断开、POS 重启、CRC 错误等)的处理策略。