9ceb218f80
Co-authored-by: Cursor <cursoragent@cursor.com>
93 lines
5.8 KiB
C
93 lines
5.8 KiB
C
/**
|
||
* @file BS_ocpp_mv_offline_bridge.h
|
||
* @brief OCPP 离线 MeterValues 桥接层声明:连接应用逻辑与 `ocpp_mv_offline_flash_impl`(SPI Flash + FRAM)
|
||
*
|
||
* @details
|
||
* - **落盘**:TCP 未连接或已连接但未登录 CSMS 时,在充电过程中周期性把测量快照写入 Flash;FRAM 映射键为 **订单开始充电时间** `StartChargeTime` 经 `xDate2Seconds` 得到的 **32 位秒值**(写入 Flash 模块的 `u32_tx_sn_lo`;第二参恒 0,与 FRAM 行 `u32_tx_sn_hi` 约定一致,非 64 位拆分),并与枪号共同区分会话(离线时设备流水号常为空,故不用设备流水号做键)。\n
|
||
* - **FRAM/SPI 管理块**:由 `BS_ocpp_ctrl.c` 的 **`v_ocpp_init_data`** 调用 `v_ocpp_mv_offline_init()` 从 EEPROM 装载;每次全量 OCPP 初始化会再次执行(与 FRAM 内容一致,可幂等重入)。\n
|
||
* - **补发(未结)**:未结算订单在联网且已取得平台 `transactionId` 后,由 `u8_ocpp_mv_offline_unsettled_step` 按序逐条补发 MeterValues,\n
|
||
* 全部完成后再由 `BS_ocpp_ctrl` 发送 `StopTransaction`。\n
|
||
* - **补发(在线会话)**:Remote 在线起充 → 充电中离线 → 再上线且 **同一 transactionId** 仍有效时,由 `u8_ocpp_mv_offline_session_replay_step` 补发离线窗口内落盘的 MV,\n
|
||
* 再发在线周期 MV / `StopTransaction`。\n
|
||
* - 本头文件仅在 `BS_OCPP_EN` 打开时提供 API,避免无 OCPP 工程误链。
|
||
*/
|
||
#ifndef BS_OCPP_MV_OFFLINE_BRIDGE_H
|
||
#define BS_OCPP_MV_OFFLINE_BRIDGE_H
|
||
|
||
#include "publicdata/type.h"
|
||
#include "meter_calculate/meter_calculate_impl.h"
|
||
|
||
#if BS_OCPP_EN
|
||
|
||
#include "flash_file_mgr/ocpp_mv_offline_flash_impl.h"
|
||
#include "bs_ocpp_json_data.h"
|
||
|
||
/**
|
||
* @fn MeterValues_mag_offline_replay
|
||
* @brief 由离线快照组 MeterValues PDU(补发;与在线 `MeterValues_mag` 共用 `j_get_ocpp_json` / 测量项配置)
|
||
*/
|
||
cJSON *MeterValues_mag_offline_replay(int gunNo, int transactionId, const S_OCPP_MV_OFFLINE_MV *mv);
|
||
|
||
/**
|
||
* @fn v_ocpp_mv_offline_bridge_private_logic
|
||
* @brief 未联网或未登录周期逻辑:充电中按配置间隔采样并写入离线 MV 池
|
||
* @param[in] bs_id 平台/任务侧 OCPP 实例 id,与 `v_ocpp_private_logic(U8_T bs_flag)` 入参一致(当前实现内未使用,保留接口扩展)
|
||
* @details
|
||
* - 调用方:`v_ocpp_private_logic` 在 **TCP 未连接** 或 **已连接未登录** 分支末尾调用。\n
|
||
* - 每枪独立节流:间隔取自 `s_ocpp_flash_cfg_data.s_ocpp_config_data.u16_MeterValueSampleInterval`(为 0 时用默认 60s)。\n
|
||
* - 仅当 `u8_bs_get_flow_state(枪)==2`(充电中)且当前枪订单日志中 **开始充电时间** `StartChargeTime` 有效时落盘;\n
|
||
* 键为 `xDate2Seconds(StartChargeTime)` 的 **单路 U32**(`u8_ocpp_mv_offline_mv_save` 第一参;第二参恒 0)。\n
|
||
* @note 与在线 `send_mag(..., OCPP_MeterValues, ...)` 互斥由上层网络状态保证;双枪各自写入 Flash 半区(见 `ocpp_mv_offline_flash_impl.h`)。
|
||
*/
|
||
void v_ocpp_mv_offline_bridge_private_logic(U8_T bs_id);
|
||
|
||
/** 在线 MeterValues 发送失败时立即落盘一条离线 MV(忽略采样间隔节流) */
|
||
void v_ocpp_mv_offline_snap_gun_now(U8_T gun);
|
||
|
||
/** 该枪进入新一笔充电会话时调用:清 FRAM 映射槽、复位落盘节流 */
|
||
void v_ocpp_mv_offline_on_charge_start(U8_T gun);
|
||
|
||
/**
|
||
* @fn v_ocpp_mv_offline_unsettled_abort
|
||
* @brief 强制中止「未结订单离线 MV 补发」状态机
|
||
* @details
|
||
* - 在 `v_safe_free_unsettled_order_data` 释放未结订单内存前调用,避免静态序号与已释放的 `S_LOG_DATA` 不一致。\n
|
||
* - 不清 Flash、不删 FRAM 映射行(映射删除仅在补发完成或读失败跳过路径中处理)。
|
||
*/
|
||
void v_ocpp_mv_offline_unsettled_abort(void);
|
||
|
||
/** 未结订单在 Flash 中是否有待补发的离线 MeterValues(按 StartChargeTime 映射键) */
|
||
U8_T u8_ocpp_mv_offline_map_pending_for_log(const S_LOG_DATA *log);
|
||
|
||
/**
|
||
* @fn u8_ocpp_mv_offline_unsettled_step
|
||
* @brief 未结补单:在已有平台 transactionId 的前提下,尝试发送下一条离线缓存的 MeterValues
|
||
* @param[in] log 当前内存中的未结算订单副本指针(与 `private_ocpp_data->s_unsettled_order_data` 相同语义)
|
||
* @return
|
||
* - **1**:本周期已发出一条 MV、或读/校验失败已跳过序号、或 WebSocket 发送失败需下周期重试同一序号;\n
|
||
* 调用方 **不得** 发送 `StopTransaction`,**不得** `free` 该订单。\n
|
||
* - **0**:Flash/FRAM 中无本单映射、或已全部补发完毕并已 `map_remove`、或参数/键不合法;\n
|
||
* 调用方可继续发送 `StopTransaction` 并释放订单(与现有未结流程一致)。
|
||
* @details
|
||
* - 映射键:与落盘相同,由 `log->StartChargeTime` 经 `xDate2Seconds` 得到同一 **U32**;与 `u8_ocpp_mv_offline_mv_save` 写入 `u32_tx_sn_lo` 时一致。\n
|
||
* - JSON 中 `transactionId`:使用 `atoi(log->u8_preTradeNo)`(**含 0**);仅 0xFF/空占位时不补发。\n
|
||
* - 每调用最多 **1 条** WS 报文,避免单次周期阻塞过长。
|
||
*/
|
||
U8_T u8_ocpp_mv_offline_unsettled_step(S_LOG_DATA *log);
|
||
|
||
/** 中止「在线会话内」离线 MV 补发状态机(新一笔充电开始时会自动调用) */
|
||
void v_ocpp_mv_offline_session_replay_abort(void);
|
||
|
||
/** 当前枪是否存在待补发的离线 MV(已有 txId,FRAM 映射非空) */
|
||
U8_T u8_ocpp_mv_offline_session_replay_pending(U8_T gun);
|
||
|
||
/**
|
||
* @brief 在线起充后会话内补发:用当前订单 `preTradeNo` 作 transactionId,逐条上送 Flash 中本笔充电的 MV
|
||
* @return 1 本周期已发或需重试;0 无待补发或已完成(调用方可继续 StopTx / 周期 MV)
|
||
*/
|
||
U8_T u8_ocpp_mv_offline_session_replay_step(U8_T gun);
|
||
|
||
#endif /* BS_OCPP_EN */
|
||
|
||
#endif /* BS_OCPP_MV_OFFLINE_BRIDGE_H */
|