定位:本页把「桩→平台数据采集」链路在 server-cdz(
module/pile,M3 桩协议网关)的实现事实收拢为设计口径,并给出与桩(厂商/固件/存量)的兼容边界——是 M3 后续接线(D1-2 后置项)、真实桩联调(D1-3)、新桩企/新固件接入评审的共同参考。分工:协议帧权威 = [[detailed-design/pile-detailed-design]](§一 帧 / §四 指令 / §八 时序 / §十 兼容红线);消息侧权威 = [[detailed-design/mq-message-contracts]](U/D 队列);本页只讲采集链路组成、每帧落到哪个业务、兼容开关与残余风险,口径与编号沿用前两者(R-1~R-5 / U1~U6 / D1~D7 / E-8 / E-13 等编号原样引用)。
代码基线:server-cdz
com.gridvo.cdz.module.pile.*(下文代码引用即此前缀,行号为当前实现);版本基线 = 云快充 2.0(0x68)帧型(非 1.x68...16+XOR型,同 pile-detailed-design §「版本基线声明」)。
PileCommand 按 legacy Message.java 常量全量登记 53 码(含平台应答码与占位,PileCommand.java:8-23);pile-detailed-design §四「47 指令总表」为合并口径(行内合并 15/17/1B/1D/21、23/25 等 + 应答码 02/04/06/0A/40 未单列)——两口径差异在枚举 javadoc 标注,注册表 53 码为新平台协议码空间真源。CORE 12 条(上行 7 + 下行 5,负载 DTO+编解码已实现)/ ACK_LATER(接线后置,含平台应答码)/ SWALLOW_NOOP(23/25 吞报文)/ DISCARD_SILENT(未接线 25 条(合并口径,含 0x12)静默丢弃 + 按码计数埋点 = 固件越界探测器)。Netty TCP,cdz.pile.* 全参数 @ConfigurationProperties(端口默认 9998,F-5 修复落点,PileNettyServer.java:26-33):
IdleStateHandler(readerIdleSeconds=60, 0, 0)
→ PileReadIdleHandler(READER_IDLE → 断连置离线)
→ PileFrameDecoder(PileHexFramer 拆包 + CRC 裁决 R-2/R-3 + R-1 补丁)
→ PileServerHandler(状态机 + 指令分发)
出站 PileFrameEncoder(组帧落线,任意位置注册即可)
0x68 | LEN(1B, =4+len(Data)) | SerialNum(2B 小端) | EncryptFlag(1B, 预留恒 0 仅透传回显) | CmdCode(1B) | Data | CRC16-Modbus(2B 小端);LEN≤255 → Data≤251B、整帧≤259B。桩 TCP → 拆包/CRC 裁决 → 状态机(UNREGISTERED --01 登录成功--> ONLINE;60s 读空闲/断开/异常 → OFFLINE;
重复登录幂等;无登出指令,"登出"= TCP 断开)
→ 按 PileCommandRegistry 分发(CORE 解码负载;23/25 吞;ACK_LATER/DISCARD 丢弃计数)
→ 事件化(PileSessionListener)→ PileGatewayEvents 转四类消费方:
① PileOnlineStateService is_online/update_time 定向更新 + 02 登录应答(档案命中 00/未命中 01,未命中仍注册=宽容)
② PileRealtimeStateService 13 → connector「遥测允许列」写回 + 枪四态→设备 7 态内存快照
③ OrderPileService 33/35/19/3B → 订单状态机推进;13 → 充电会话遥测快照(C 端 realtime 3s 轮询直读)
④ PileGatewayAlertSink monitor 告警引擎(PileAlertEngineImpl;上线/心跳/13 遥测/离线四事件)
is_online=false(非轮询)。| 码 | 指令 | Data 要点 | 落点(server-cdz) | MQ 批次后置(mq-contracts) |
|---|---|---|---|---|
| 01 | 登录认证 | 桩号 7B BCD + 桩类型(0直流/1交流) + 枪数 + 协议版本×10 + 程序版本 8B ASCII + 网络类型 + SIM BCD(20 位) + 运营商(固定 30B,LoginPayload) | handleLogin → bindPileNo → onOnline(02 应答下发) | 登录 RPC(02 直发,无上行队列) |
| 03 | 心跳 | 桩号 + 枪号 1B + 枪状态 1B(仅 00 正常/01 故障,共 9B;四态在 13 帧勿混) | handleHeartbeat(续约 + 04 应答) | CHARGING_PILE_HEART_BEAT_QUEUE(U1) |
| 13 | 实时监测(主采集) | 16B 流水号 + 桩号[16..23) + 60B 负载(§四);多枪批量帧由 R-1 拆成多条独立 13 帧 | onRealtime → ①遥测写回 ②会话快照 ③告警 | CHARGING_PILE_REAL_TIME_MONITOR_DATA_QUEUE(U2) |
| 19 | 充电结束 | BMS SOC/电压/温度 + 累计时间 + 输出能量 + 充电机编号 | onChargeEnd → OrderPileService(IN_PROGRESS→BILLING) | CHARGING_PILE_REMOTE_STOP_CHARGING_QUEUE(U3) |
| 33 | 远程启机回复 | 16B 流水号 + 桩号[16..23) + 枪号 + 结果(00败/01成) + 原因(00无/01设备不匹配/02枪已充电/03故障/04离线/05未插枪);未插枪 60s 内可补送成功(E-13) | onRemoteStartReply → OrderPileService(PENDING→IN_PROGRESS/START_FAILED;PENDING 不因 33 失败立即关闭) | CHARGING_PILE_REMOTE_START_COMMAND_QUEUE(U4) |
| 35 | 远程停机回复 | 桩号开头 + 枪号 + 结果(00败/01成) + 原因(00无/01设备不匹配/02枪未充电/03其他)(无 16B 流水号,共 10B) | onRemoteStopReply → OrderPileService(IN_PROGRESS→BILLING) | CHARGING_PILE_REMOTE_SHUTDOWN_QUEUE(U5) |
| 3B | 交易记录 | 16B 流水号 + 四费率×单价/电量/计损/金额 + 电表起止 + VIN + 交易标识 + 停止原因 | onTransactionRecord → OrderPileService(计量登记/对账参照,桩报总额不直入结算)→ 40 回执 | TRANSACTION_RECORDS_QUEUE(U6) |
| 方向 | 码 | 内容 | 实现 |
|---|---|---|---|
| ↓ | 02 登录应答 | Data=桩号 7B + 结果(00 成功/01 失败);serial 回显登录帧(E-8) | PileGatewayEvents.onOnline(writeAck 即时下发;未命中设备档案 01 但会话仍注册=宽容策略,生产加固待 D1-3) |
| ↓ | 04 心跳应答 | Data=桩号 + 枪号回显 + heartbeatResp 恒 00 | onHeartbeat |
| ↓ | 40 交易确认 | Data=16B 流水号 echo + 00 受理/01 非法账单 | onTransactionRecord(受理与否由订单桥返回;无订单桥按受理回执避免桩重传) |
| ↓ | 34 远程启机 | 桩号 + 16B 流水号 + 逻辑卡号 8B + 物理卡号 8B + 余额(分 4B 小端) | OrderPileService.startCharge(MQ D1 等价动作,MQ 批次后置) |
| ↓ | 36 远程停机 | 桩号 + 枪号 | OrderPileService.stopCharge(MQ D2 等价动作) |
| ↓ | 56/58/92 校时/计费模型设置/远程重启 | codec 就绪(TimeSync/BillingModelSet/RemoteRestart payload) | 下发入口 D1-2 后置(远程操作页接线;MQ D4/D3/D5) |
下行组帧要求 Data 已含 7B BCD 桩号前缀(PileFrameCodec.java:23 注释);应答帧 serial 一律回显当前上行帧(E-8),即时下发、不参与 idle 重发语义(PileGatewayEvents.java:294-312);下行写失败走 SessionRegistry 退避重试(F-2),设备离线返回 Optional 由业务降级(F-1)。
| 字段 | 换算 | 备注 |
|---|---|---|
| transactionSerialNo | 16B 流水号(32 位 hex;全 0 = 未交易哨兵) | 会话回联键 |
| gunState | 00 离线 / 01 故障 / 02 空闲 / 03 充电 | 与心跳两态语义不同 |
| outputVoltage / outputCurrent | 原始 LE ÷10(0.1V / 0.1A) | |
| 枪线温度 / 电池最高温度 | 原始 −50 ℃ | |
| SOC | 原值 0-100 | 交流桩恒 0 |
| 累计/剩余充电时间 | LE 2B,单位 min | |
| chargeDegree / lossChargeDegree / chargedAmount | LE 4B ÷10⁴(kWh / 元) | 未设计损比例时计损度数=充电度数 |
| hardwareFailure | LE 2B 13bit 位图:bit1 急停 / bit2 无整流模块 / bit3 出风口过热 / bit4 交流防雷 / bit5 DC20 断连 / bit6 绝缘检测断连 / bit7 电度表断连 / bit8 读卡器断连 / bit9 RC10 断连 / bit10 风扇调速板故障 / bit11 直流熔断器故障 / bit12 高压接触器故障 / bit13 门打开(1=故障) | failureBit(n) 便捷断言 |
business_equipment_connector.work_status(7 态权威 = 充电模块 Redis 实时态派生)、insert_gun_status(状态源 = 充电模块 Redis 写回)——采集服务禁写这两列。business_equipment.is_online/update_time(equipment_code 优先、serial_number 兜底;未命中仅告警不抛异常,F-1 降级,PileOnlineStateServiceImpl.java:61-85)。40055825050010 / 40058825050011(双枪直流;dev 口径 connector_code = 40055825050010-01/-02)——legacy 生产实际接入过的两台,固件怪癖见 §5.2。| 编号 | 桩固件问题 | 处置 | 实现落点(server-cdz) | 状态 |
|---|---|---|---|---|
| R-1 | 存量两桩批量帧(13/25)声明 LEN 大于实际发送长度、帧尾缺 0,按声明截帧即错位 | 声明窗口内第二 0x68 为真实边界 → 截真实内容尾补 0 → CRC 以 6789 替代豁免 | PileHexFramer.applyLegacyLengthPatch(:226-245);配置 codec-patches(默认 40055825050010:13,25、40058825050011:13,25) | ✅ 已外置配置;精确边界待真实桩日志回放校准(D1-3) |
| R-2 | 固件 CRC 算错/字节序不分 | 默认不放行:清单外 CRC 失败即丢弃+计数;仅 crc-tolerance-piles 白名单放行并告警计数 | PileHexFramer.feed CRC 分支(:179-192);默认白名单 = 上述两桩 | ✅ 已实现(G1 定稿);白名单载体待迁 business_equipment.crc_tolerance(该列当前不存在,禁止引用) |
| R-3 | CRC 字节序写反 | 正序/逆序都收 | PileFrameCodec.verifyCrc(:73-77)+ PileCrc16 | ✅ 已实现 |
| R-4 | 数据域含 0x68 即错位(无转义 + 字符串找头的固有缺陷) | 保留 hex 找头方案 + LEN 交叉校验 + 双守卫;不引入转义(协议层改动=不兼容) | PileHexFramer 守卫与重同步(:105-155) | ✅ 已实现 |
| R-5 | 登录帧带协议版本×10 但旧系统无按版本分发 | 登记版本号入 business_equipment.protocol_version,为未来分版本预留(本期不分发) | LoginPayload.protocolVersionX10 已解析;登记列未建(EquipmentDO 现仅 firmwareVersion) | ⚠️ 解析就绪、落库待建 |
桩号+枪号2位、桩号-枪号2位} 精确匹配(两拼写并存待统一,PileRealtimeStateServiceImpl.java:112-137)。RemoteControlOfStartupOnTheOperationPlatform.java:36 未 reverseOrder ⇒ 大端 4B,与文档「帧内 4B 小端分」相出入;新实现按文档小端——真实桩对账前存在「断存量桩 vs 一直收错」双向风险,须实测定论。business_equipment.crc_tolerance(迁移后删配置,禁止双源)。模拟真实充电桩物理行为(人+桩互动测试载体,命令表 PileSimulatorConsole.java:34-52):plug/unplug(插拔枪 + E-13 补送触发)、start-ok/start-fail/late-ok(33 回复策略与 60s 补送)、full(充满自停自发 19+3B)、fault <hex>(13 故障位图注入)、gun-state 0-3、hb-off/hb-on(停心跳 → 60s 断连离线路径)、rt-off/rt-on(停 13 → C 端 realtime stale 观察窗)、drop-35(测平台超窗重发)、no-tx(测结算兜底)、crc <n>(上行 CRC 篡改 → R-2 裁决)、power/step/volt/curr(遥测数值注入);启动 flag 另支持 --auto-full / --fault-hex / --crc-after / --drop35-on / --hb-off-after-login / --daemon / --plug-after(无人值守脚本化)。
B 建档(桩 40055825050010 + 2 枪)→ PileSimulator 登录网关 9998 → C 端 start(34 下发)→ 模拟器 33 应答 + 13 遥测(真数据回联 currentPower/degree/amount)→ stop(36)→ 19/3B → 订单状态 1→2→5→6 → 守卫(枪忙 40901 / 活跃单 40903)→ DB 释放 5→6。
6789 豁免路径生效;| 项 | 现状 | 目标 | 关联 |
|---|---|---|---|
| MQ 接线 | 无(内存直连) | mq-contracts U/D 队列接入(U1/U2/U3/U4/U5/U6、D1~D7) | [[detailed-design/mq-message-contracts]] |
| Redis 实时态 / 会话 | 无(本实例内存快照) | Redis 实时态 + PG 规范化(er-charging §四);会话持久化 | [[er/er-charging]] |
| CRC 白名单落库 | 配置承载(cdz.pile.crc-tolerance-piles) | business_equipment.crc_tolerance | [[design-conventions]] §十 G1 |
| 协议版本登记 | 解析就绪(LoginPayload.protocolVersionX10) | business_equipment.protocol_version | pile-detailed-design §十 R-5 |
| 校价/运维下行 | codec 就绪 | 56/58/92 下发入口(远程操作页接线);05/09/0A/06 校价闭环 | [[pages/charging/remote-operation]] |