Initial commit: CCU621_M firmware project with BLE debug link support.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-08 17:28:36 +08:00
commit 9ceb218f80
1597 changed files with 724159 additions and 0 deletions
@@ -0,0 +1,200 @@
# IES 积成平台功能说明(CCU601E_D / plat_comm/ieszt
本文档描述 **积成智通 IESZT** 二进制协议在 E 工程中的落地方案、与 **PlatComm 联网任务** 的挂接关系,以及 **`S_BS_IES_CTRL_DATA`** 各字段含义。
上层任务状态机、双平台槽位、FTP 分时等见 **[《平台联网任务功能说明.md》](../平台联网任务功能说明.md)**。
---
## 1. 模块定位
| 项目 | 说明 |
|------|------|
| **目录** | `app/plat_comm/ieszt/` |
| **编译宏** | **`BS_IES_EN`**`public_define.h` |
| **PlatComm 槽位** | `MasterFuncArray` 名称 **`"ieszt"`**`plat_comm_task.c`);与 OCPP 并存时通常为槽位 **0**OCPP 为槽位 **1**(以 `PLAT_EN` 配置为准) |
| **全局数据** | **`s_bs_task_ctrl.s_ies_data`**`plat_comm_task.h`,类型 **`S_BS_IES_CTRL_DATA`** |
| **传输层** | 与 OCPP 共用 **`bs_connect_impl`**`u8_tcp_connect` / `v_bs_send` / `u16_bs_recv`**明文 TCP**,无 WebSocket |
| **当前阶段** | **登录/心跳** + **校时** + **费率** + **二维码 0x08/0x0A** |
---
## 2. 源文件与功能分区
**`BS_ocpp_ctrl.c`** 相同,`.c` 内用 **`#if 1 //公共` / `#if 1 //发送` / `#if 1 //接收` / `#if 1 //外部控制使用`** 折叠分区(便于 Keil 大纲跳转与整段屏蔽调试)。
| 文件 | `#if 1` 分区 | 内容 |
|------|----------------|------|
| **`bs_ies_ctrl.c`** | 公共 | `v_ies_timer_add``u8_ies_timer_ctrl`、定时器初值、`v_ies_reset_ctx``v_ies_on_login_ok` |
| | 发送 | `v_ies_logo_on``v_ies_send_ctrl` |
| | 接收 | `v_ies_recv_data``v_ies_recv_unpack` |
| | 外部控制使用 | `v_ies_init_data``v_ies_tcp_connect``v_ies_private_logic` |
| **`impl/bs_public_impl.c`** | — | **`u8_get_str_data` / `u8_set_str_data`**、**`u32_bs_get_sys_data` / `u8_set_sys_data`**(含 `E_STR_QR_DISPLAY``E_BS_GET_SYS_DATA_UNIX_TIMESTAMP` |
| **`bs_ies_interface.c`** | 公共 | 组帧头、CRC、`v_ies_finish_frame_and_send` |
| | 发送 | `v_ies_register_req``v_ies_heart_req``v_ies_fee_req``u8_ies_send_ack` |
| | 接收 | 登录/心跳/校时/费率/二维码;`v_ies_unpack_handle`(经 `bs_public_impl` 读写系统) |
| **`bs_ies_ctrl.h`** | — | 协议常量、`IES_SEND_TIMER``S_BS_IES_CTRL_DATA`、对外 API |
| **`bs_ies_interface.h`** | — | 报文层对外声明 |
移植路线图(阶段 3+)见 **`../IES积成平台移植方案.md`**。
---
## 3. 与 PlatComm 的挂接(对照联网任务文档 §4)
### 3.1 七回调映射
| PlatComm 回调 | IES 实现 | 说明 |
|---------------|----------|------|
| **`v_bs_data_init`** | `v_ies_init_data` | 清零 **`s_ies_data`**,写入 **`u8_bs_flag`** |
| **`v_bs_tcp_connect`** | `v_ies_tcp_connect` | 建链前清 **`u8_register_flag`**;内部 **`u8_tcp_connect(id)`** |
| **`v_bs_logon_connect`** | `v_ies_logo_on` | 周期发 **0x01****`u8_register_flag==1`** 时返回 1,置槽位 **`u8_log_on_flag`** |
| **`v_bs_recv_data`** | `v_ies_recv_data` | **`u16_bs_recv`** → **`v_ies_unpack_handle`** |
| **`v_bs_recv_unpack`** | `v_ies_recv_unpack` | 空实现(4G 外部分包预留) |
| **`v_bs_send_ctrl`** | `v_ies_send_ctrl` | 已登录后周期发 **0x03**、**0x05**(未获费率时) |
| **`v_bs_private_logic`** | `v_ies_private_logic` | **`u8_heart_outTime_cnt`** 超限 → **`v_set_bs_renew`** |
调度顺序与 **`v_plat_comm_network_round`** 一致,见 **[平台联网任务功能说明.md §4.3](../平台联网任务功能说明.md)**。
### 3.2 与 `S_BS_CTRL_DATA` 的分工
| 数据 | 位置 | 用途 |
|------|------|------|
| TCP/登录标志 | **`s_bs_ctrl[i].u8_TCP_connect_flag`** / **`u8_log_on_flag`** | PlatComm 通用状态机 |
| IES 协议态 | **`s_ies_data`** | 登录应答、心跳计数、**`s_timerCnt[]`** 周期定时、序列号等 |
| 槽位号 | **`s_ies_data.u8_bs_flag`** | 与 **`i`**、`E_STR_PILE_NO` 第三参数、`v_bs_send(id)` 一致 |
---
## 4. 运行态结构 `S_BS_IES_CTRL_DATA`
所有 IES 私有计时与计数集中在 **`s_bs_task_ctrl.s_ies_data`**`v_ies_reset_ctx` / `memset` 时一并清零)。
| 字段 | 类型 | 含义 |
|------|------|------|
| **`u8_bs_flag`** | U8 | PlatComm 槽位 **0/1**;对应 **`E_BS_GET_SYS_DATA_PLAT_EN`** 与桩编号 **`E_STR_PILE_NO`** 的 `u8_dataPara` |
| **`u8_register_out_cnt`** | U8 | 已发 **0x01**、仍未收到 **0x02** 的累计次数;超过 **`BS_IES_LOGIN_RETRY_MAX`** 触发 **`v_set_bs_renew`** |
| **`u8_heart_outTime_cnt`** | U8 | 已发 **0x03**、仍未收到 **0x04** 的连续次数;由 **`v_ies_heart_req`** 递增、**`v_ies_heart_ack`** 清零 |
| **`u8_register_flag`** | U8 | **1** = 平台登录成功(**0x02** 且结果字节为 0);为 1 时 **`v_ies_logo_on`** 返回 1 |
| **`u8_syn_time_flag`** | U8 | **1** = 已完成平台校时(登录成功或收到 **0x76** |
| **`u8_ask_fee_flag`** | U8 | **1** = 已获取/下发费率,不再周期发 **0x05** |
| **`u16_msgSerialNumber`** | U16 | 自发帧序列号(组帧头时 `s16_serialNum<=0` 自增) |
| **`ulong_restart_timer`** | ULONG | 最近一次 TCP 建链成功时刻(`get_current_seconds` |
| **`s_timerCnt[]`** | 数组 | 与 OCPP **`OCPP_DATA_CTRL.s_timerCnt`** 同结构:`u16_timerCnt` 每秒 +1`u16_timeNUM` 为周期(秒) |
| **`ack_ctrl[]`** | 指针数组 | 平台下行需应答帧的异步队列(**`IES_DATA_RECV_ACK`**,同 OCPP **`ack_ctrl`**);`v_ies_send_ctrl` 每轮上送一条 |
### 4.1 `IES_SEND_TIMER` 与默认周期(`v_ies_init_timer_period`
| 枚举 | 默认 `u16_timeNUM`(秒) | 说明 |
|------|-------------------------|------|
| **`IES_TIMER_LOGIN`** | `BS_IES_LOGIN_INTERVAL_S`20 | `v_ies_logo_on` 发 0x01 |
| **`IES_TIMER_HEART`** | `BS_IES_HEART_INTERVAL_S`20 | `v_ies_send_ctrl` 发 0x03 |
| **`IES_TIMER_FEE_MODULE`** | 30 | 登录后周期发 **0x05** 直至 **0x06****0x7D** 写入费率 |
| **`IES_TIMER_FREE_DATA_GUN1/2`** | 180 | 空闲实时 0x13 |
| **`IES_TIMER_CHG_DATA_GUN1/2`** | 30 | 充电实时 0x15 |
| **`IES_TIMER_METER_GUN1/2`** | 3600 | 电表 |
| **`IES_TIMER_TRADE_GUN1`** | 10 | 账单 |
内部接口(`bs_ies_ctrl.c`,与 OCPP 同名语义):**`v_ies_timer_add()`** 每秒递增;**`u8_ies_timer_ctrl(cmd, GET_FLAG/CLEAR_FALG)`** 查询到时或清零。
---
## 5. 登录与心跳流程
```text
[TCP 未连接]
v_ies_tcp_connect → u8_tcp_connect
(清 u8_register_flagCLEAR_FALG LOGIN/HEART 定时器)
[TCP 已连接,未登录]
v_ies_logo_on → v_ies_timer_add
IES_TIMER_LOGIN 到时 → v_ies_register_req
收到 0x02 且 [BODY]==0 → v_ies_on_login_ok(含首包心跳定时到点)
超时次数 > BS_IES_LOGIN_RETRY_MAX → v_set_bs_renew + v_ies_reset_ctx
[已登录,u8_log_on_flag==1]
v_ies_send_ctrl → v_ies_timer_add
IES_TIMER_HEART 到时 → v_ies_heart_req
u8_ask_fee_flag==0 且 IES_TIMER_FEE_MODULE 到时 → v_ies_fee_req
v_ies_recv_data → 0x04 → v_ies_heart_ack
→ 0x76 → v_ies_set_clk_syncv_bs_set_timeack 挂入 ack_ctrl
→ 0x7D → 解析费率 → v_bs_save_fee_data0x7E 挂入 ack_ctrl
v_ies_send_ctrl → ack_ctrl 非空 → u8_ies_send_ack → v_ies_free_ack_data
v_ies_private_logic → v_ies_timer_add
u8_heart_outTime_cnt > BS_IES_HEART_MISS_MAX → v_set_bs_renew
```
---
## 6. 0x68 帧与已实现命令
帧域下标见 **`bs_ies_ctrl.h`** 中 **`IES_FRM_OFF_*`**(与 A 工程 `u8_recvBuf[21/22/23]` 一致)。
| 类型码 | 方向 | 函数 |
|--------|------|------|
| **0x01** | 上行 | `v_ies_register_req` |
| **0x02** | 下行 | `v_ies_register_ack` |
| **0x03** | 上行 | `v_ies_heart_req` |
| **0x04** | 下行 | `v_ies_heart_ack` |
| **0x05** | 上行 | `v_ies_fee_req` |
| **0x06** | 下行 | `v_ies_fee_module_ack``v_bs_save_fee_data` |
| **0x07** | 上行 | `u8_ies_send_ack` 二维码下发应答 |
| **0x08** | 下行 | `v_ies_qr_dis``QRDisplay[]` + Flash |
| **0x09** | 上行 | `u8_ies_send_ack` 二维码召唤应答 |
| **0x0A** | 下行 | `v_ies_qr_call` |
| **0x75** | 上行 | `v_ies_clk_sync_ack` |
| **0x76** | 下行 | `v_ies_set_clk_sync``v_bs_set_time` |
| **0x7D** | 下行 | `v_ies_fee_cfg_req` |
| **0x7E** | 上行 | `v_ies_fee_cfg_ack` |
| 其它 | — | `v_ies_rx_cmd_handle` 打日志占位 |
---
## 7. 配置与联调要点
| 配置项 | 接口 | 说明 |
|--------|------|------|
| 平台使能 | **`E_BS_GET_SYS_DATA_PLAT_EN`** | 槽位 0/1 与 **`MasterFuncArray`** 下标一致 |
| 联网方式 | **`E_BS_GET_SYS_DATA_NET_TYPE`** | 0=4G1=网口;IES 与 OCPP 共用同一套 connect |
| 桩编号 | **`E_STR_PILE_NO`** + **`u8_bs_flag`** | 双平台时平台 A/B 各一套桩号 |
| 枪数 / 故障 | **`E_BS_GET_SYS_DATA_GUN_NUM`**、**`NOW_FAULT_ALARM_NUM`** | 登录帧、心跳帧组帧 |
**双平台 + 单 4G TCP**:产品与 **`PLAT_EN`** 需约定主平台;详见移植方案「风险」章节。
**FTP 升级中**`v_ies_recv_data`**`u8_updata_flag!=0` 且 4G** 时跳过收包(与 OCPP 策略一致,见联网任务文档 §4.4)。
---
## 8. 日志
| 宏 | 定义位置 | 说明 |
|----|----------|------|
| **`IES_PRINT_FLAG`** | `plat_comm_task.h` | 值 **0xFE**,与 **`OCPP_PRINT_FLAG`(0xFF)** 同类:不受 `u8_task_log_flag` 门控时默认输出 |
| **`IES_PRINTF_LOG`** | `bs_ies_ctrl.h` | `MYLOG_MSG(IES_PRINT_FLAG, …)`;**ieszt 目录内请用此宏,勿用 `Plat_Comm_LOG`** |
| 日志 | 含义 |
|------|------|
| `IES: init slot=` | `v_ies_init_data` |
| `IES: login req pile=` | 发出 0x01 |
| `IES: login ok` / `login fail` | 0x02 解析结果 |
| `IES: heartbeat tx cnt=` | 发出 0x03(含未应答计数) |
| `IES: heartbeat ack` | 收到 0x04 |
| `IES: clk sync` / `clk sync ack` | 0x76 校时 / 0x75 应答 |
| `IES: fee module req` / `fee model saved` | 0x05 请求 / 0x06·0x7D 落盘 |
| `IES: login timeout, renew` / `heartbeat miss, renew` | 触发 **`v_set_bs_renew`** |
---
## 9. 关联文档
| 文档 | 内容 |
|------|------|
| **[平台联网任务功能说明.md](../平台联网任务功能说明.md)** | PlatComm 任务、双槽状态机、FTP 分时、**`v_set_bs_renew`** |
| **[IES积成平台移植方案.md](../IES积成平台移植方案.md)** | A→E 分阶段移植清单 |
| **`4g_module/4G模块AT指令配置功能说明.md`** | 4G TCP/FTP 与 PlatComm 分时 |
| **`impl/bs_public_impl.h`** | **`E_STR_*`** / **`E_BS_GET_SYS_DATA_*`** 枚举 |
---
*文档版本:与 `plat_comm/ieszt` 源码同步;结构体字段变更时请同步更新 §4。*
+43
View File
@@ -0,0 +1,43 @@
# ieszt — 积成 IES 运营平台协议
规约依据:积成充电桩网络通信协议(V3.5 / V3.7 / V3.8,由 `BS_IES_TYPE` 选择)
## 编译开关
`public_define.h` 中设置:
```c
#define BS_IES_EN (1) // 使能积成 IES 运营协议(CCU621 默认)
```
协议版本在 `bs_ies_ctrl.h` 中配置:
```c
#define BS_IES_TYPE (2) // 1=山高3.82=积成3.7(默认),3=积成3.5
```
可与 `BS_IESYW_EN` 并存:平台 A 走 IES 运营(本目录),平台 B 走远程运维(`iesyw/`),共用 4G 模组 socketA/B 分发。
## 文件
| 文件 | 说明 |
| --- | --- |
| `bs_ies_ctrl.c/h` | 任务回调、登录/心跳、周期上送调度、接收解帧 |
| `bs_ies_interface.c/h` | 帧格式(0x68 起始)、帧类型码、组包/解包 |
## 主要帧类型
| 类型 | 说明 |
| --- | --- |
| 0x01/0x02 | 登录/应答 |
| 0x03/0x04 | 心跳/应答 |
| 0x05/0x06 | 计费模型请求/应答 |
| 0x07~0x0A | 二维码下发/召唤 |
| 0x11/0x13 | 充电中/非充电实时数据 |
| 0x15 | 故障告警 |
| 0x31 | 表底值上送 |
| 0x41~0x48 | 启停/账单结算 |
| 0x76 | 对时 |
| 0x7D/0x7E | 费率相关 |
详细说明见 [plat_comm模块说明.md](../plat_comm模块说明.md)。
+709
View File
@@ -0,0 +1,709 @@
#include "plat_comm/ieszt/bs_ies_ctrl.h"
#include "plat_comm/ieszt/bs_ies_interface.h"
#include "plat_comm/impl/bs_connect_impl.h"
#include "plat_comm/impl/bs_public_impl.h"
#if WH_GM5_EN
#include "plat_comm/4g_module/bs_wh_gm5.h"
#endif
#if (BS_IES_EN)
#define BS_TIME_1S 10 //1秒 发送周期1秒计数
S_BS_IES_CTRL_DATA *private_ies_data;
#endif
#if (BS_IES_EN) //内部控制函数
void v_ies_send(U8_T *u8_sendBuf, U32_T sendLen)
{
u8_sendBuf[sendLen] = u16_crc_checksum(&u8_sendBuf[3], sendLen-3); //和校验
sendLen ++;
//更新帧长度域
u8_sendBuf[1] = (sendLen-4)>>8;
u8_sendBuf[2] = sendLen-4;
v_bs_send(private_ies_data->id,u8_sendBuf,sendLen);
}
//发送周期计数累加 1秒加一
static void v_ies_timer_add()
{
U8_T i;
static ULONG time_old = 0;
ULONG time_ing = get_current_seconds(); //获取当前秒数
if(time_old != time_ing)
{
time_old = time_ing;
for (i = 0; i < IES_TIMERCNT_NUM; i++)
{
if(private_ies_data->s_timerCnt[i].u16_timerCnt < private_ies_data->s_timerCnt[i].u16_timeNUM)
{
private_ies_data->s_timerCnt[i].u16_timerCnt ++;
}
}
}
}
//获取发送周期计数到时标志
static U8_T u8_ies_timer_ctrl(IES_SEND_TIMER cmd ,FLAG_CTLR flag)
{
U8_T ret = 0;
if(flag == CLEAR_FALG) //清空对应计时计数
{
private_ies_data->s_timerCnt[(U8_T)cmd].u16_timerCnt = 0;
ret = 1;
}
else if(private_ies_data->s_timerCnt[(U8_T)cmd].u16_timeNUM != 0 &&
private_ies_data->s_timerCnt[(U8_T)cmd].u16_timerCnt >= private_ies_data->s_timerCnt[(U8_T)cmd].u16_timeNUM)
{
private_ies_data->s_timerCnt[(U8_T)cmd].u16_timerCnt = 0;
ret = 1;
}
return ret;
}
#endif
#if (BS_IES_EN) //发送相关
/**
* ************************************************************************
* @brief - 故障信息变化检查
*
*
* @return U8_T - 0未变化 1变化
*
* @author jiankalka
* @date 2025-09-20
* ************************************************************************
*/
static U8_T u8_cheak_fault()
{
static U8_T u8_old_fault_num=0;
U8_T u8_fault_num,ret = 0;
u8_fault_num = u32_bs_get_sys_data(0,E_BS_GET_SYS_DATA_NOW_FAULT_ALARM_NUM,0) +
u32_bs_get_sys_data(0,E_BS_GET_SYS_DATA_NOW_FAULT_ALARM_NUM,1); //获取故障 告警数量
if(u8_fault_num != u8_old_fault_num)
{
u8_old_fault_num = u8_fault_num;
ret = 1;
}
return ret;
}
/**
* ************************************************************************
* @brief - 抢连接变化检查
*
* @param[in] u8_gunNo - 抢号 0-N
*
* @return U8_T - 0未变化 1已经变化
*
* @author jiankalka
* @date 2025-09-20
* ************************************************************************
*/
static U8_T u8_cheak_gunlink(U8_T u8_gunNo)
{
static U8_T u8_old_gunLink[GUN_MAX_CNT] = {0};
U8_T u8_gunLink = u8_ies_get_gunLink_state(u8_gunNo); //获取枪连接状态 0未连接 1已连接
//u8_gunLink = (u8_gunLink == 0 ? 0 : 1);
if(u8_gunLink != u8_old_gunLink[u8_gunNo])
{
//printf("%d枪变位,原状态:%d,现状态:%d\n",u8_gunNo,u8_old_gunLink[u8_gunNo],u8_gunLink);
u8_old_gunLink[u8_gunNo] = u8_gunLink;
return 1;
}
return 0;
}
/**
* ************************************************************************
* @brief - 抢状态变化检查
*
* @param[in] u8_gunNo - 抢号 0-N
*
* @return U8_T - 0未变化 1已经变化
*
* @author jiankalka
* @date 2025-09-20
* ************************************************************************
*/
static U8_T u8_cheak_gunState(U8_T u8_gunNo)
{
static U8_T u8_old_gunState[GUN_MAX_CNT] = {0};
U8_T u8_gunState = u8_ies_get_gun_state(u8_gunNo); //获取枪状态 0未连接 1已连接
//u8_gunLink = (u8_gunLink == 0 ? 0 : 1);
if(u8_gunState != u8_old_gunState[u8_gunNo])
{
//printf("%d枪变位,原状态:%d,现状态:%d\n",u8_gunNo,u8_old_gunState[u8_gunNo],u8_gunState);
u8_old_gunState[u8_gunNo] = u8_gunState;
return 1;
}
return 0;
}
//发送控制
static void v_ies_send_mag_ctrl()
{
S_BS_CTRL_DATA *s_bs_ctrl = &s_bs_task_ctrl.s_bs_ctrl[private_ies_data->id]; //获取控制数据
U8_T i,u8_data; //临时变量 使用前注意赋值
U8_T u8_gunCnt = s_bs_task_ctrl.u8_gunCnt;
U8_T u8_get_flow_state[GUN_MAX_CNT];
static U8_T fee_flag = 0; //连接平台后直接请求一次计费模型标志
//检查心跳周期是否到位
if(u8_ies_timer_ctrl(IES_TIMER_Heartbeat,GET_FLAG) == 1)
{
v_ies_heart();
return;
}
//电表底值上送
for(i=0;i<u8_gunCnt;i++)
{
if(u8_ies_timer_ctrl((IES_SEND_TIMER)(IES_TIMER_MeterValues_GUN + i), GET_FLAG) == 1)
{
v_ies_meter_data(i);
return;
}
}
//主动上送
//桩主动请求充电
for(i=0;i<u8_gunCnt;i++)
{
if(private_ies_data->s_ctrl_flag[i].u8_charge_req == 1)
{
v_ies_start_req(i);
return;
}
}
//请求费率
if(fee_flag == 0 ||(private_ies_data->txFlag_askFeeMode == 0 &&
u8_ies_timer_ctrl(IES_TIMER_FEE_REQ,GET_FLAG) == 1))
{
v_ies_fee_req();
fee_flag = 1;
return;
}
//订单上送
for(i=0; i<u8_gunCnt; i++)
{
u8_data = 0;
if(s_bs_ctrl->s_gundata[i].txFlag_tradUpload == 1)
{
if( s_bs_ctrl->s_gundata[i].u8_tradUpload_cnt < 6) //充电中 只发6次
u8_data = 1;
}
else
s_bs_ctrl->s_gundata[i].u8_tradUpload_cnt = 0;
if(u8_data == 1 && u8_ies_timer_ctrl((IES_SEND_TIMER)(IES_TIMER_TRADE_INFO + i), GET_FLAG) == 1)
{
v_ies_bill_pack(i);
s_bs_ctrl->s_gundata[i].u8_tradUpload_cnt ++;
return;
}
}
//故障状态上送-有故障变化时上送,无故障变化时,3分钟上送一次
u8_data = u8_cheak_fault();
if(u8_data == 1 || u8_ies_timer_ctrl(IES_TIMER_FAULT_GUN ,GET_FLAG) == 1)
{
u8_ies_timer_ctrl(IES_TIMER_FAULT_GUN ,CLEAR_FALG); //清空计数
v_ies_fault_V35(i);
return;
}
//充电/空闲实时信息上报
for(i=0; i<u8_gunCnt; i++)
{
u8_get_flow_state[i] = u8_bs_get_flow_state(i); //获取终端状态 0 空闲 1开始充电 2充电中
if(u8_get_flow_state[i] == 2) //充电中
{
//当状态由变化时 前3帧按10秒发送--u8_real_state_cnt 0x00-0x0F 充电中计数 0x10-0x1F 非充电中计数
private_ies_data->s_ies_gun[i].u8_real_state_cnt &= 0x0F;
if(private_ies_data->s_ies_gun[i].u8_real_state_cnt < 3)
{
private_ies_data->s_timerCnt[IES_TIMER_REAL_WORK_GUN + i].u16_timeNUM = 10; //前3帧 10秒周期上送
}
else
{
private_ies_data->s_timerCnt[IES_TIMER_REAL_WORK_GUN + i].u16_timeNUM = private_ies_data->u16_work_info_period; //上送周期等于充电数据上送周期设置值
}
if(u8_ies_timer_ctrl((IES_SEND_TIMER)(IES_TIMER_REAL_WORK_GUN + i), GET_FLAG) == 1)
{
// printf("%d枪,充电中,u8_real_state_cnt=%02x\n",i,private_ies_data->s_ies_gun[i].u8_real_state_cnt);
v_ies_rtd_chging(i);
if(private_ies_data->s_ies_gun[i].u8_real_state_cnt < 3)
{
private_ies_data->s_ies_gun[i].u8_real_state_cnt ++;
}
return;
}
}
else
{
//当状态由变化时 前3帧按10秒发送--u8_real_state_cnt 0x00-0x0F 充电中计数 0x10-0x1F 非充电中计数
private_ies_data->s_ies_gun[i].u8_real_state_cnt &= 0xF0; //清除低位计数值
if(private_ies_data->s_ies_gun[i].u8_real_state_cnt < 0x30)
{
private_ies_data->s_timerCnt[IES_TIMER_REAL_WORK_GUN + i].u16_timeNUM = 3; //前3帧 3秒周期上送
}
else
{
private_ies_data->s_timerCnt[IES_TIMER_REAL_WORK_GUN + i].u16_timeNUM = private_ies_data->u16_free_info_period; //上送周期等于充电数据上送周期设置值
}
if(u8_ies_timer_ctrl((IES_SEND_TIMER)(IES_TIMER_REAL_WORK_GUN + i), GET_FLAG) == 1 //|| u8_cheak_gunlink(i)
|| u8_cheak_gunState(i)) //延时到时间上送、枪状态改变上送
{
//printf("%d枪,非充电中,u8_real_state_cnt=%02x\n",i,private_ies_data->s_ies_gun[i].u8_real_state_cnt);
v_ies_rtd_free(i);
if(private_ies_data->s_ies_gun[i].u8_real_state_cnt < 0x30)
{
private_ies_data->s_ies_gun[i].u8_real_state_cnt += 0x10;
}
return;
}
}
}
}
#endif
#if (BS_IES_EN) //接收
static void v_bs_rx_cmd_hanle(U8_T *u8_recvBuf) //具体报文解帧
{
U8_T u8_cmd = u8_recvBuf[22];
switch(u8_cmd)
{
case NT_LOGIN_ACK: //0x02 //登录注册应答
{
if(private_ies_data->u8_register_flag == 0)
{
v_ies_register_ack(u8_recvBuf);
}
break;
}
case NT_TICK_ACK: //0x04 //心跳应答
{
v_ies_heart_ack();
break;
}
case NT_FEE_MODULE_ACK: //0x06 //计费模型应答
{
v_ies_fee_ack(u8_recvBuf);
break;
}
case NT_MDU_DATA_ACK: //0x17 //充电桩整流模块数据应答
{
break;
}
case NT_START_CHG_ACK: //0x42 //平台确认桩主动申请启动充电
{
v_ies_rx_start(u8_recvBuf);
break;
}
case NT_REMOTE_START_REQ: //0x44 //平台远程控制启机
{
if(private_ies_data->txFlag_askFeeMode == 1) //未收到计费模型,不启动充电
{
Plat_Comm_LOG("private_ies_data->txFlag_askFeeMode=%d\n",private_ies_data->txFlag_askFeeMode);
v_ies_rmt_start(u8_recvBuf);
}
break;
}
case NT_REMOTE_STOP_REQ: //0x46 //平台远程停机
{
v_ies_rmt_stop(u8_recvBuf);
break;
}
case NT_BILL_UPLOAD_ACK: //0x48 //平台结算账单确认
{
v_ies_bill_upload_ack(u8_recvBuf);
break;
}
case NT_USERACNTINFO_ACK: //0x4A //平台回复查询用户账单信息(未用)
{
//v_bs_user_acntInfo_ack(u8_recvBuf);
break;
}
case NT_CARD_BILL_UPLOAD_ACK: //0x4C //平台刷卡结算订单应答
{
//v_bs_bill_card_ack(u8_recvBuf);
break;
}
case NT_WORK_PARA_CFG_REQ: //0x72 //平台设置工作参数
{
//v_bs_set_wkPara(u8_recvBuf);
break;
}
case NT_WORK_PARA_QUERY_REQ: //0x74 //平台查询工作参数
{
//v_bs_query_wkPara(u8_recvBuf);
break;
}
case NT_CLK_SYNC_REQ: //0x76 //平台对时
{
v_ies_set_clk_sync(u8_recvBuf);
break;
}
case NT_REMOTE_OPRT_REQ: //0x78 //平台远程操作
{
//v_bs_rmt_oprt(u8_recvBuf);
break;
}
case NT_FEE_CFG_REQ: //0x7D //平台设置计费模型
{
v_ies_set_fee(u8_recvBuf);
break;
}
case NT_UPDATE_AUTO: //0x90 //平台下发FTP升级命令
{
//v_ies_upgrade_data_auto(u8_recvBuf);
break;
}
case NT_QR_REQ_CALL: //0x0A 平台召唤二维码
{
v_ies_qr_call(u8_recvBuf);
break;
}
case NT_QR_REQ_DIS: //0x08 平台下发二维码
{
Plat_Comm_LOG("Receive platform QR code command\n");
// printf("收到平台下发二维码命令\n");
// for(int i=0;i < 100;i++)
// {
// printf("%.2x ",u8_recvBuf[i]);
// }
// printf("\n");
v_ies_qr_dis(u8_recvBuf);
break;
}
default:
break;
}
}
// static void v_bs_unpack_handle_ieszt(U8_T *u8_recvBuf, U16_T u16_rcvLen) //解帧函数
// {
// U8_T u8_crc;
// U16_T u16_rcvByteNum = 0; //解粘包指针
// U16_T u16_oneFrmLen = 0; //一完整帧理论总长度
// U16_T u16_dataLen = 0; //数据域长度
// U8_T upackBuf[BS_RECV_BUF_LEN] = {0}; //待解析帧缓存
// while(u16_rcvLen >= 23) //帧头长度=23
// {
// if(u8_recvBuf[u16_rcvByteNum] != NT_HEADER) //找帧头
// {
// u16_rcvByteNum++;
// u16_rcvLen--;
// continue;
// }
// u16_dataLen = (U16_T)((u8_recvBuf[u16_rcvByteNum+1]<<8) + u8_recvBuf[u16_rcvByteNum+2]);
// if(u16_dataLen >= 256)
// return;
// u16_oneFrmLen = u16_dataLen + 4;
// if(u16_oneFrmLen <= u16_rcvLen) //构成完整帧
// {
// memcpy(&upackBuf[0], &u8_recvBuf[u16_rcvByteNum], u16_oneFrmLen);
// //和校验
// u8_crc = u16_crc_checksum(&upackBuf[3], u16_oneFrmLen-4);
// if(u8_crc == upackBuf[u16_oneFrmLen-1])
// {
// v_bs_rx_cmd_hanle(upackBuf); //和校验通过,解析数据
// }
// u16_rcvByteNum += u16_oneFrmLen;
// u16_rcvLen -= u16_oneFrmLen;
// }
// else
// return;
// }
// }
static void v_bs_unpack_handle_ieszt(U8_T *u8_recvBuf, U16_T u16_rcvLen) //解帧函数
{
U8_T u8_crc;
U16_T u16_rcvByteNum = 0; //解粘包指针
U16_T u16_oneFrmLen = 0; //一完整帧理论总长度
U16_T u16_dataLen = 0; //数据域长度
U8_T upackBuf[BS_RECV_BUF_LEN] = {0}; //待解析帧缓存
static U8_T u8_save_buf[BS_RECV_BUF_LEN*2] = {0};
static U16_T u16_save_len = 0;
// 检查缓冲区是否溢出
if(u16_rcvLen + u16_save_len >= BS_RECV_BUF_LEN*2)
{
// 移除前四分之一数据以腾出空间
U16_T remove_len = u16_save_len / 4; // 计算要移除的长度
U16_T remain_len = u16_save_len - remove_len; // 剩余数据长度
if(remain_len > 0) {
// 将后面的数据向前移动,覆盖前四分之一
memmove(u8_save_buf, u8_save_buf + remove_len, remain_len);
}
u16_save_len = remain_len; // 更新保存的数据长度
}
// 将接收到的数据添加到缓存区中
if(u16_rcvLen > 0) {
memcpy(&u8_save_buf[u16_save_len], u8_recvBuf, u16_rcvLen);
u16_save_len += u16_rcvLen;
}
// 使用静态缓冲区数据进行解析
U16_T process_len = u16_save_len; // 当前要处理的数据长度
u16_rcvByteNum = 0; // 重置解析指针
while(process_len >= 23) //帧头长度=23
{
if(u8_save_buf[u16_rcvByteNum] != NT_HEADER) //找帧头
{
u16_rcvByteNum++;
process_len--;
continue;
}
u16_dataLen = (U16_T)((u8_save_buf[u16_rcvByteNum+1]<<8) + u8_save_buf[u16_rcvByteNum+2]);
if(u16_dataLen >= 256)
{
u16_rcvByteNum++;
process_len--;
continue; // 数据长度异常,跳过这个帧头
}
u16_oneFrmLen = u16_dataLen + 4;
if(u16_oneFrmLen <= process_len) //构成完整帧
{
memcpy(&upackBuf[0], &u8_save_buf[u16_rcvByteNum], u16_oneFrmLen);
//和校验
u8_crc = u16_crc_checksum(&upackBuf[3], u16_oneFrmLen-4);
if(u8_crc == upackBuf[u16_oneFrmLen-1])
{
v_bs_rx_cmd_hanle(upackBuf); //和校验通过,解析数据
}
u16_rcvByteNum += u16_oneFrmLen;
process_len -= u16_oneFrmLen;
}
else
break; // 数据不完整,等待下次接收更多数据
}
// 将处理完的数据从静态缓冲区中移除
if(u16_rcvByteNum > 0) // 有处理完的数据需要移除
{
// 计算剩余未处理数据的长度
U16_T remaining_len = u16_save_len - u16_rcvByteNum;
if(remaining_len > 0)
{
// 将未处理的数据向前移动,覆盖已处理的数据
memmove(u8_save_buf, u8_save_buf + u16_rcvByteNum, remaining_len);
}
// 更新静态缓冲区的数据长度
u16_save_len = remaining_len;
// 清空移动后空出的部分(可选,为了调试清晰)
if(remaining_len < BS_RECV_BUF_LEN*2) {
memset(u8_save_buf + remaining_len, 0, BS_RECV_BUF_LEN*2 - remaining_len);
}
}
}
#endif
#if (BS_IES_EN) //外部控制使用
/****************************************************
*函数名称: v_ies_init_data()
*功能说明: 程序运行前 参数初始化
*参数说明:
* 输入参数:
* 输出参数: 0失败 1成功
****************************************************/
void v_ies_init_data(U8_T bs_flag)
{
U8_T i;
private_ies_data = &s_bs_task_ctrl.s_ies_data; //指针数据初始化
memset(private_ies_data,0,sizeof(S_BS_IES_CTRL_DATA));
private_ies_data->id = bs_flag; //平台位置
// if (bs_flag == 0U) {
// s_bs_task_ctrl.s_bs_ctrl[bs_flag].u8_netType =
// (u32_bs_get_sys_data(0,E_BS_GET_SYS_DATA_NET_TYPE,bs_flag) == 1U) ? 0U : 1U;
// } else {
// s_bs_task_ctrl.s_bs_ctrl[bs_flag].u8_netType =
// (u32_bs_get_sys_data(0,E_BS_GET_SYS_DATA_NET_TYPE,bs_flag) == 1U) ? 0U : 1U;
// }
s_bs_task_ctrl.s_bs_ctrl[bs_flag].fd = -1;
s_bs_task_ctrl.s_bs_ctrl[bs_flag].ulong_restart_timer = get_current_seconds();
if(s_bs_task_ctrl.s_bs_ctrl[bs_flag].u8_netType == 0) //4G
{
v_bs_4G_data_init();
}
//周期发送控制初始化
private_ies_data->u16_work_info_period = 30; //工作实时状态 上送周期
private_ies_data->u16_free_info_period = 120; //空闲实时状态 上送周期
//周期发送控制初始化
private_ies_data->s_timerCnt[IES_TIMER_Register].u16_timeNUM = 20; //秒 登录帧上送周期
private_ies_data->s_timerCnt[IES_TIMER_Register].u16_timerCnt = 20; //确保立马执行登录帧
private_ies_data->s_timerCnt[IES_TIMER_Heartbeat].u16_timeNUM = 15; //秒 心跳帧上送周期
private_ies_data->s_timerCnt[IES_TIMER_FEE_REQ].u16_timeNUM = 60; //秒 费率请求
private_ies_data->s_timerCnt[IES_TIMER_FAULT_GUN].u16_timeNUM = 60*3; //秒 故障信息上报
for ( i = 0; i < GUN_MAX_CNT; i++)
{
private_ies_data->s_timerCnt[IES_TIMER_REAL_WORK_GUN + i].u16_timeNUM = 30; //秒 工作实时状态
private_ies_data->s_timerCnt[IES_TIMER_REAL_WORK_GUN + i].u16_timerCnt = 0xFFFF;
private_ies_data->s_timerCnt[IES_TIMER_TRADE_INFO + i].u16_timeNUM = 30; //秒 订单信息上送
private_ies_data->s_timerCnt[IES_TIMER_MeterValues_GUN + i].u16_timeNUM = 60*30; //秒 电表低值上送
}
}
/****************************************************
*函数名称: v_ies_tcp_connect()
*功能说明: TCP连接功能实现 - 配置4G模块
*参数说明:
* 输入参数:
* 输出参数: 0失败 1成功
****************************************************/
U8_T v_ies_tcp_connect(void)
{
return u8_tcp_connect(private_ies_data->id);
}
/****************************************************
*函数名称: v_ies_logo_on()
*功能说明: 平台桩信息登录 -
*参数说明:
* 输入参数:
* 输出参数: 0失败 1成功
****************************************************/
U8_T v_ies_logo_on(void)
{
v_ies_timer_add(); //计时计数+1
//检查登录周期是否到位
if(u8_ies_timer_ctrl(IES_TIMER_Register,GET_FLAG) == 1)
{
v_ies_register_req(); //登录帧
Plat_Comm_LOG("Send login platform packet, u8_register_flag:%d\n",private_ies_data->u8_register_flag);
if(private_ies_data->u8_register_out_cnt++ > 6) //两分钟登录帧未连接成功
{
v_set_bs_renew(private_ies_data->id); //设置主函数 联网重连
v_ies_init_data(private_ies_data->id); //设置 子函数参数重置 重走初始化过程
Plat_Comm_LOG("Login frame send timeout\n");
}
}
if(private_ies_data->u8_register_flag == 1)
{
private_ies_data->u8_register_out_cnt = 0;
return 1;
}
else
return 0;
}
/****************************************************
*函数名称: v_ies_recv_data()
*功能说明: 数据接收处理 - 控制任务周期调用 使用网口或者4G非分包功能时使用,需内部实现从串口获取数据
*参数说明:
* 输入参数:
* 输出参数:
****************************************************/
void v_ies_recv_data(void)
{
S16_T s16_recvLen = 0;
U8_T u8_recvBuf[BS_RECV_BUF_LEN] = {0};
s16_recvLen = u16_bs_recv(private_ies_data->id,u8_recvBuf,BS_RECV_BUF_LEN);
if(s16_recvLen > 0)
{
v_bs_unpack_handle_ieszt(&u8_recvBuf[0], s16_recvLen);
}
}
/**
* ************************************************************************
* @brief - 控制任务接收解析完数据后调用 4G 模块多包接收时使用-当4G使用多socket数据接收时,串口数据获取和分包功能由外部实现,函数传入参数为本平台的接收数据
*
* @param[in] id - 平台地址
* @param[in] recvBuf - 接收数据
* @param[in] u16_len - 接收数据长度
*
*
* @author jiankalka
* @date 2025-09-02
* ************************************************************************
*/
void v_ies_recv_unpack(U8_T id, U8_T *recvBuf,U16_T u16_len)
{
v_bs_unpack_handle_ieszt(recvBuf,u16_len);
}
/****************************************************
*函数名称: v_ies_send_ctrl()
*功能说明: 发送控制函数 -
*参数说明:
* 输入参数:
* 输出参数:
****************************************************/
void v_ies_send_ctrl(void)
{
v_ies_timer_add(); //计时计数+1
v_ies_send_mag_ctrl(); //发送控制
}
/****************************************************
*函数名称: v_ies_private_logic()
*功能说明: 私有协议逻辑控制 -
*参数说明:
* 输入参数:
* 输出参数:
****************************************************/
void v_ies_private_logic(U8_T bs_flag)
{
if(private_ies_data->u8_heart_outTime_cnt > 3) //发送三次心跳 未回复 则进行重连
{
v_set_bs_renew(private_ies_data->id); //设置主函数 联网重连
v_ies_init_data(private_ies_data->id); //设置 子函数参数重置 重走初始化过程
//轻质化群充测试过程中发现与平台连接超时后不重连
//检查发现iotx_linkkit_ctx_t结构体中is_opened,is_connected未复位,原因未知,为确保现场使用,此地暂时强制复位
//v_connected_resset();
Plat_Comm_LOG("Timeout reconnect\n");
}
}
#endif
+100
View File
@@ -0,0 +1,100 @@
/**
* @file bs_ies_ctrl.h
* @brief 积成 IES 平台协议控制层
*
* 定义 IES 协议私有数据结构、周期上送计时器及任务回调声明。
* 协议版本由 BS_IES_TYPE 选择(默认积成 3.7)。
*/
#ifndef BS_IES_CTRL_H
#define BS_IES_CTRL_H
#ifdef __cplusplus /*C++编译环境下兼容C语言*/
extern "C" {
#endif
/*------ Exported includes(头文件) ----------------------*/
#include "main.h"
#if (BS_IES_EN)
/*------ Exported macro(宏定义) -------------------------*/
#define IES_TIMERCNT_NUM (4 + 3*GUN_MAX_CNT) //计时计数
#define IES_ACK_STRUCT_NUM 5 //应答结构体数量
/*************************************
* 宏名称: BS_IES_TYPE
* 宏说明: 积成平台协议版本
* 设置说明:未定义:报错
* 1 山高平台 3.8 2积成 3.7 3积成 3.5
*
**************************************/
#define BS_IES_TYPE 2
/*------ Exported struct(结构体定义) --------------------*/
typedef enum{
IES_TIMER_Register = 0, //登录帧 0
IES_TIMER_Heartbeat, //心跳 1
IES_TIMER_FEE_REQ, //费率请求 2
IES_TIMER_FAULT_GUN, //充电故障告警上送3
IES_TIMER_REAL_WORK_GUN, //工作实时状态 数量跟随枪数量 - 包含工作状态和空闲状态两种 4
//IES_TIMER_FAULT_GUN = IES_TIMER_REAL_WORK_GUN+GUN_MAX_CNT, //充电故障告警上送, 4+20 24
IES_TIMER_MeterValues_GUN = IES_TIMER_REAL_WORK_GUN+GUN_MAX_CNT, //表底值上送, 25+20 45
IES_TIMER_TRADE_INFO = IES_TIMER_MeterValues_GUN+GUN_MAX_CNT, //订单信息上送 数量跟随枪数量 46+20 66
}IES_SEND_TIMER;
typedef struct
{
U8_T id; //平台位置 平台1还是平台2
U8_T u8_register_out_cnt; //登录帧超时计数
U8_T u8_heart_outTime_cnt; //心跳超时计时
U8_T u8_register_flag; //是否已注册/是否联网.0否1是
U8_T txFlag_askFeeMode; //请求费率
U8_T u8_time_flag; //校时标志
U8_T u8_heart_outTime; //心跳超时计时--
U16_T u16_msgSerialNumber; //帧序号
U16_T u16_work_info_period; //工作实时状态 上送周期
U16_T u16_free_info_period; //空闲实时状态 上送周期
struct
{
U8_T u8_MeterValues_type; //数据上送标志 0无动作 1空闲数据上送 2充电中数据上送 3交易开始数据上送 4交易停止数据上送
U8_T u8_charge_req; //充电请求标志 0 不请求充电 1 请求充电
}s_ctrl_flag[GUN_MAX_CNT]; //数据控制标志
struct
{
U8_T u8_real_state_cnt; //充电实时状态 上送计数
U16_T u16_charge_cnt; //充电次数
U32_T u32_charge_time; //充电时间
}s_ies_gun[GUN_MAX_CNT];
struct
{
U16_T u16_timerCnt; //周期发送计数
U16_T u16_timeNUM ; //计数周期值
}s_timerCnt[IES_TIMERCNT_NUM];
}S_BS_IES_CTRL_DATA;
/*------ Exported variables(变量定义) -------------------*/
/*------ Exported function prototypes (函数声明) -------*/
void v_ies_init_data(U8_T bs_flag);
U8_T v_ies_tcp_connect(void);
U8_T v_ies_logo_on(void);
void v_ies_recv_data(void);
void v_ies_send_ctrl(void);
void v_ies_private_logic(U8_T bs_flag);
void v_ies_recv_unpack(U8_T id, U8_T *recvBuf,U16_T u16_len);
void v_ies_send(U8_T *u8_sendBuf, U32_T sendLen);
#endif
#ifdef __cplusplus
}
#endif
#endif /* BS_IES_CTRL_H */
File diff suppressed because it is too large Load Diff
+336
View File
@@ -0,0 +1,336 @@
/**
* @file bs_ies_interface.h
* @brief 积成 IES 平台协议报文层
*
* 帧格式、帧类型码定义及组包/解包函数声明。
* 帧头 0x68,设备地址 16 字节 ASCII 桩编号。
*/
#ifndef BS_IES_INTERFACE_H
#define BS_IES_INTERFACE_H
#ifdef __cplusplus /*C++编译环境下兼容C语言*/
extern "C" {
#endif
/*------ Exported includes(头文件) ----------------------*/
#include "main.h"
#if (BS_IES_EN)
/*------ Exported macro(宏定义) -------------------------*/
/************积成通信协议帧结构*********************
* 帧起始域 1字节 0x68
* 帧长度域 2字节 从序列号域到帧数据域,高字节在前,低字节在后
* 序列号域 1字节 数据包发送顺序号,从0开始,应答帧则同询问包
* 设备地址 16字节 ASCII
* 加密方式 1字节 0不加密,1AES加密,登录帧和确认帧加密方式为0
* 数据对象 1字节 高2位:0直流1交流2交直流;低6位标识枪号,0代表充电机本体
* 帧类型码 1字节
* 帧数据域 N字节
* 校验和 1字节 序列号域到帧数据域
**************************************************/
#define NT_PTL_VERSION 37 //通信协议版本V3.5
#define NT_HEADER 0x68 //帧头
//数据对象
#if BS_TYPE_JIMO_EN //即墨平台使能,则桩类型为液冷充电桩。否则为直流桩
#define NT_DC_PILE 3 //直流桩 //#define NT_AC_PILE 1 //交流桩 //直流桩 0积成平台 3即墨平台
#else
#define NT_DC_PILE 0 //直流桩 //#define NT_AC_PILE 1 //交流桩 //直流桩 0积成平台 3即墨平台
#endif
#define NT_0B_MASK_H 0xC0 //高2位掩码
#define NT_0B_MASK_L 0x3F //低6位掩码
#define NT_ID_PILE 0 //充电桩本体
#define NT_ID_GUN1 1 //1号充电枪
#define NT_ID_GUN2 2 //2号充电枪
/************帧类型码宏定义************/
//登录心跳帧类型码数据定义
#define NT_LOGIN_REQ 0x01 //登录请求
#define NT_LOGIN_ACK 0x02 //登录应答
#define NT_TICK_REQ 0x03 //心跳请求
#define NT_TICK_ACK 0x04 //心跳应答
#define NT_FEE_MODULE_REQ 0x05 //计费模型请求
#define NT_FEE_MODULE_ACK 0x06 //计费模型应答
#define NT_QR_REQ_DIS_ACK 0x07 //二维码下发应答
#define NT_QR_REQ_DIS 0x08 //二维码下发
#define NT_QR_REQ_CALL_ACK 0x09 //二维码召唤应答
#define NT_QR_REQ_CALL 0x0A //二维码召唤帧
//实时数据帧类型码数据定义
#define NT_GUN_DATA_CHGING 0x11 //直流充电枪充电中实时数据
#define NT_GUN_DATA_FREE 0x13 //直流充电枪非充电中实时数据
#define NT_FAULT_DATA 0x15 //直流充电桩故障告警数据上传
#define NT_MDU_DATA_REQ 0x16 //运营平台整流模块数据读取 rectifier module整流模块
#define NT_MDU_DATA_ACK 0x17 //充电桩整流模块数据应答
//表底值上送
#define NET_METER_DATA 0x31 //表底值上送
//运营交互帧类型码数据定义
#define NT_START_CHG_REQ 0x41 //充电桩主动申请启动充电
#define NT_START_CHG_ACK 0x42 //平台确认启动充电
#define NT_REMOTE_START_ACK 0x43 //充电桩回复远程启机
#define NT_REMOTE_START_REQ 0x44 //平台远程控制启机
#define NT_REMOTE_STOP_ACK 0x45 //充电桩远程停机命令回复
#define NT_REMOTE_STOP_REQ 0x46 //平台远程停机
#define NT_BILL_UPLOAD 0x47 //充电结算帐单上传
#define NT_BILL_UPLOAD_ACK 0x48 //平台结算账单确认
#define NT_USERACNTINFO_REQ 0x49 //充电桩主动申请查询用户账户信息(未用)
#define NT_USERACNTINFO_ACK 0x4A //平台回复查询用户账单信息(未用)
#define NT_CARD_BILL_UPLOAD 0x4B //充电桩刷卡结算订单上传
#define NT_CARD_BILL_UPLOAD_ACK 0x4C //平台刷卡结算订单应答
//运营平台设置帧类型码数据定义
#define NT_WORK_PARA_CFG_ACK 0x71 //充电桩应答工作参数设置
#define NT_WORK_PARA_CFG_REQ 0x72 //平台设置工作参数
#define NT_WORK_PARA_QUERY_ACK 0x73 //充电桩应答工作参数查询
#define NT_WORK_PARA_QUERY_REQ 0x74 //平台查询工作参数
#define NT_CLK_SYNC_ACK 0x75 //充电桩应答平台对时
#define NT_CLK_SYNC_REQ 0x76 //平台对时
#define NT_REMOTE_OPRT_ACK 0x77 //充电桩应答平台远程操作
#define NT_REMOTE_OPRT_REQ 0x78 //平台远程操作
#define NT_LCD_SHOW_ACK 0x79 //充电桩应答平台触发液晶屏显示(用户电话)
#define NT_LCD_SHOW_REQ 0x7A //平台触发液晶屏显示内容
#define NT_UNLOCK_CARD_REQ 0x7B //充电桩请求解锁卡
#define NT_UNLOCK_CARD_ACK 0x7C //平台应答解锁卡请求
#define NT_FEE_CFG_REQ 0x7D //平台设置计费模型
#define NT_FEE_CFG_ACK 0x7E //充电桩应答模型设置
//远程升级数据定义
#define NT_UPGRADE_RQ 0x80 //平台发送远程升级指令
#define NT_UPGRADE_DATA_REQ 0x81 //桩向平台请求文件内容(多次执行,直至文件传输完毕)
#define NT_UPGRADE_DATA_ACK 0x82 //平台应答文件内容请求
#define NT_UPDATE_AUTO 0x90 //平台FTP升级请求
#define NT_UPDATE_AUTO_ACK 0x93 //充电桩主动上传FTP文件传输结果
/*------ Exported struct(结构体定义) --------------------*/
/*------ Exported variables(变量定义) -------------------*/
typedef enum /* 积成智通后台通信协议-订单上送-启机失败/停机原因 */
{
IESZT_NORMAL=0, //0正常
IESZT_STARTING_FAULT, //1启动中有报警
IESZT_INSU_FAIL, //2绝缘检测失败
IESZT_DY_SWCH_FAIL, //3控制辅源电压检测切换失败
IESZT_DY_FAIL, //4投辅源失败
IESZT_STARTING_BATVOLT_FAIL = 6, //6启动中,检测电池电压失败
IESZT_KM_ON_FAIL, //7合直流输出开关失败
IESZT_MDU_STAT_FAIL, //8模块启动失败
IESZT_CHGING_FAULT, //9充电中有报警
IESZT_CHGING_GUN_UNCNCT, //10充电中,检测到枪未连接到车上
IESZT_CHGING_DY_OFF, //11充电中未检测到辅源
IESZT_CHGING_BATVOLT_FAIL, //12充电中未检测到电池电压
IESZT_CARD, //13刷卡停机
IESZT_NO_BALANCE, //14余额不足
IESZT_BMS_ABNMAL, //15充电中BMS异常停机
IESZT_BMS_FULL, //16充电中BMS充满停机
IESZT_STARTING_UNDERPOWER, //17启动中,辅助桩功率不足
IESZT_BMS_DMD_VOLT_OVER, //18充电中,BMS需求电压越限
IESZT_CURR_OVER, //19充电中,过流
IESZT_GUN_TEMP_OVER, //20充电中,枪温过温
IESZT_BMS_TO, //21 BMS通信超时
IESZT_BMS_COMM_INTRPUT= 24, //24 BMS通信中断
IESZT_LH_KM_OFF, //25 充电中,联合开关未合
IESZT_LL_KM_ON, //26 充电中,边界联络开关未分
IESZT_APP_STOP, //27 APP停止充电
IESZT_K1K2_OFF, //28 K1/K2闭合失败
IESZT_LOCK_GUN_FAIL = 30, //30 锁枪失败
IESZT_OUT_VOLT_LOW = 33, //33 启机时,输出电压不达标
IESZT_INSU_TO, //34 绝缘检测超时
IESZT_BSM_STOP, //35 bsm终止
IESZT_TO= 37, //37 超时重试
IESZT_RELIEF_ON = 42, //42 启机过程中泄放继电器非法合
IESZT_MONEY_OK, //43 达到设定金额
IESZT_TIME_OK, //44 达到设定时长
IESZT_POWER_OK, //45 达到设定电量
IESZT_URGENCY = 50, //50 急停
IESZT_ACS, //51 门禁
IESZT_WATER, //52 水浸
IESZT_FS, //53 防雷
IESZT_OVER_TEMP, //54 环温过温
IESZT_UNDER_TEMP, //55 环温过低
IESZT_CARdREADER_COMM, //56 读卡器通信故障
IESZT_LCD_COMM, //57 LCD通信故障
IESZT_KM_ERRACT, //58 母联直流接触器拒动/误动
IESZT_KM_ADHESION, //59 母联直流接触器粘连
IESZT_WHM_COMM, //60 电表通信故障
IESZT_FUSE, //61 直流熔断器故障
IESZT_GUN_KM_ADHESION, //62 #号枪对应直流输出接触器黏连故障 - 空闲,应断开,但检测到为闭合
IESZT_MDU_COMM_DOWN, //63 所有模块通信中断
IESZT_PRE_CHGOT, //64 充电机预充超时
IESZT_bms_BHM_OT, //65 BHM报文接收超时
IESZT_BMS_BRM_OT, //66 BRM报文接收超时
IESZT_BMS_BRM_ERR, //67 BRM报文数据异常 - 报文数据长度错误,版本协议错误
IESZT_BMS_BCP_OT, //68 BCP报文接收超时
IESZT_BMS_BCP_ERR, //69 BCP报文数据异常 - 报文数据长度错误,电池当前电压越限
IESZT_BMS_BRO_00_OT, //70 BRO报文(0x00)接收超时
IESZT_BMS_BRO_AA_OT, //71 BRO报文(0xAA)接收超时
IESZT_BMS_BCS_OT, //72 BCS报文接收超时
IESZT_BMS_VOLTPARA_MISMTCH, //73 电池最高允许充电电压小于充电机最小输出电压
IESZT_BATV_OVER10, //74 绝缘检测前直流输出接触器外侧电压>=10V
IESZT_BATV_BMSV_OVER5, //75 启动充电前直流输出接触器外侧电压与通信报文电池电压相差》=-5%
IESZT_OUTV_BATV_1TO10, //76 预充电时输出电压不在电池电压-(1V~10V)范围内
IESZT_VIN_ERR, //77 vin清单使能,当前车vin不在清单内
IESZT_CHGCABINET_COMM_DOWN, //78 充电柜通信中断
IESZT_BMS_BCL_OT, //79 电池充电需求报文BCL接收超时
IESZT_BMS_BAT_BCS_OT, //80 电池充电总状态报文BCS接收超时
IESZT_BMS_BSM_OT, //81 动力蓄电池状态信息BSM接收超时
IESZT_BMS_BSM_OVERU, //82 BSM - 单体动力蓄电池电压过高
IESZT_BMS_BSM_BELOWU, //83 BSM - 单体动力蓄电池电压过低
IESZT_BMS_BSM_OVERSOC, //84 BSM - 整车动力蓄电池荷电状态SOC过高
IESZT_BMS_BSM_BELOWSOC, //85 BSM - 整车动力蓄电池荷电状态SOC过低
IESZT_BMS_BSM_OVERI, //86 BSM - 动力蓄电池充电过电流
IESZT_BMS_BSM_OVERT, //87 BSM - 动力蓄电池温度过高
IESZT_BMS_BSM_INSUERR, //88 BSM - 动力蓄电池绝缘状态异常
IESZT_BMS_BSM_CONNERR, //89 BSM - 动力蓄电池组输出连接器连接状态异常
IESZT_BMS_BSM_FORBIT, //90 BSM - 禁止充电
IESZT_BMS_BST_OT, //91 BST报文接收超时
IESZT_BMS_BST_U_OK, //92 BST - 达到总电压设定值
IESZT_BMS_BST_SNGUOK, //93 BST - 达到单体电压设定值
IESZT_BMS_BST_INSUERR, //94 BST - 绝缘故障
IESZT_BMS_BST_CONN_OVERT, //95 BST - 输出连接器过温
IESZT_BMS_BST_CELL_OVERT, //96 BST - BMS元件过温/输出连接器过温
IESZT_BMS_BST_CONN_ERR, //97 BST - 充电连接器故障
IESZT_BMS_BST_BAT_OVERT, //98 BST - 电池组温度过高
IESZT_BMS_BST_HVRELAY_ERR, //99 BST - 高压继电器故障
IESZT_BMS_BST_2U_ERR, //100 BST - 检测点2电压检测故障
IESZT_BMS_BST_ELSE, //101 BST - 其他故障
IESZT_BMS_BST_OVERI, //102 BST - 电流超过需求值
IESZT_BMS_BST_U_ABNORML, //103 BST - 电压异常
IESZT_BMS_BEM, //104 BEM - 错误报文
IESZT_OUTPUT_VOLT_OVER, //105 直流输出过压
IESZT_OUTPUT_VOLT_LOW, //106 直流输出不达标
IESZT_GUNLOCK_ERR, //107 枪锁状态错误
IESZT_SMOKE_ERR, //108 烟感告警
} IESZT_REASON_E;
typedef enum //星星充电-订单上送-启机失败/停机原因
{
STAR_PILE_STOP = 0, //0 桩主动停止
STAR_URGENCY, //1 急停按键被按下
STAR_WHM_COMM, //2 电表通信故障
STAR_CARdREADER_COMM, //3 读卡器通信故障
STAR_PE_FAULT, //4 接地故障
STAR_MDU_COMM_DOWN, //5 电源模块通信故障
STAR_ALL_MDU_COMM_DOWN, //6 电源模块全部通信故障
STAR_OVER_TEMP, //7 过温故障
STAR_ELE_LEAKAGE, //8 漏电故障
STAR_METER_DATA_ABNOEMAL, //9 电表数据异常停止充电
SATR_ACS, //10 舱门打开停止充电
STAR_URGENCY_PRESS, //11 急停按键被按下(直流专用)
STAR_FCI = 17, //17 FCI故障-部分模块通讯故障(用作开关模块故障)
STAR_INVALID_CURR, //18 无有效电流停止(交流充满,车载故障等)
STAR_LOW_BLANCE, //19 余额不足停止
STAR_GUNLINK_INTERUPTED, //20 充电连接器断开停止
STAR_CARD_STOP, //21 刷卡停止
STAR_BMS_STOP, //22 BMS正常停止(直流充满)
STAR_APP_STOP, //23 手机APP或者微信停止
STAR_SCREEN_STOP, //24 触控屏手动停止
STAR_BMS_CONN_ERR, //25 BMS通信故障
STAR_DC_ELECT_SHORT, //26 充电机输出短路
STAR_MDU_HARD_ERR, //27 模块硬件故障
STAR_OUTPUT_OVER_CURR, //28 充电机输出过流
STAR_PILE_OVER_TEMP, //29 充电机过温保护
STAR_OUTPUT_OVER_VOL, //30 充电机输出过压
STAR_INPUT_OVER_VOL, //31 充电机输入过压
STAR_INPUT_LOW_VOL, //32 充电机输入欠压
STAR_BLEED_ERR, //33 泄放电阻放电故障(未能在规定时间电压降至60V以下)
STAR_BEM_ALARM, //34 BEM报警
STAR_INSUAL_ERR, //35 充电机绝缘检测故障
STAR_GUNLINK_ERR, //36 充电枪未正确连接
STAR_BATT_REVERSE, //37 电池反接故障
STAR_BATT_ABNORMAL, //38 电池异常
STAR_BSD_OVERTIME, //39 BSD超时
STAR_BST_OVERTIME, //40 BST超时
STAR_BCL_OVERTIME, //41 BCL超时
STAR_BRO_OVERTIME, //42 BRO超时
STAR_BCP_OVERTIME, //43 BCP超时
STAR_BRM_OVERTIME, //44 BRM超时
STAR_BMS_OTHER_ERR, //45 BMS其他故障
STAR_BMS_VOL_ABNORMAL, //46 BMS检测电压异常
STAR_BMS_CURR_OVER, //47 BMS检测电流过大
STAR_BMS_BATT_OVER_TEMP, //48 BMS电池组过温
STAR_BMS_COMPOENT_OVER_TEMP,//49 BMS元件过温
STAR_BMS_CONNECTOR_OVER_TEMP,//50 BMS输出连接器过温故障
STAR_BMS_INSUAL_ERR, //51 Bms绝缘故障
STAR_CAR_STOP, //52 车载停止
STAR_SWITCH_CHARGE_WAIT, //53 切换充等待中(用作避雷器故障)
STAR_PLAT_CONN_ERR, //54 与后台通信故障
STAR_PLAT_STOP, //55 后台停止
STAR_TIME_OK, //56 达到设置充电时长停机
STAR_POWER_OK, //57 达到设置充电电量停机
STAR_MONEY_OK, //58 达到设置充电金额停止
STAR_PILE_TERMAL_CONN_ERR, //59 主副板通信故障
STAR_POWER_OUTAGE_STOP, //60 掉电停止
STAR_K3K4_STICK, //61 辅助电源粘连
STAR_K1K2_STICK, //62 输出继电器粘连
STAR_BATTV_OVER10, //63 (启动前)继电器外侧电压大于10v停止充电
STAR_PILE_BHM_MISMATCH, //64 桩输出能力不匹配(BHM)停止充电
STAR_NEED_OVER_MAXVOL=66, //66 需求电压或充电电压大于最高允许充电电压停止充电
STAR_BRO_MAJOR_FAILURE, //67 BRO重大故障停止充电
STAR_PERCHARGE_VOL_MISMATCH,//68 预充电压不匹配停止充电
STAR_SMOKE_ERR, //69 烟雾报警(停止用)
STAR_CAR_MATCH_FAILED, //70 车辆匹配失败
STAR_SOC_REACH_THRESHOLD, //71 SOC达到阀值
STAR_CARD_UNREGISTERED, //100 卡号未注册
STAR_TIME_FORMAT_ABNORMAL, //101 时间格式异常
}STAR_REASON_E;
/*------ Exported function prototypes (函数声明) -------*/
void v_ies_register_req(void);
void v_ies_heart(void);
void v_ies_fee_req(void);
void v_ies_rtd_free(U8_T gunNo); //空闲实时数据 0x13, 变位上送,120s
void v_ies_rtd_chging(U8_T gunNo); //充电中实时数据 0x11 变化加间隔上送,30s
void v_ies_meter_data(U8_T u8_gunNo); //表底值 0x31,30分钟上送一次
void v_ies_fault_V35(U8_T u8_gunNo); //故障告警数据 0x15, V3.5协议故障不分枪
void v_ies_bill_pack(U8_T u8_gunNo); //组上送账单
void v_ies_start_req(U8_T u8_gunNo); //主动启动充电请求 0x41
void v_ies_set_clk_sync_ack(void);
void v_ies_set_fee_ack(void);
void v_ies_upgrade_data_auto_ack(void);
void v_ies_rmt_start_ack(U8_T u8_gunNo, U8_T serialNum ,U8_T flag); //远程启动应答 0x43, 应答帧序号跟询问帧需保持一致
void v_ies_rmt_stop_ack(U8_T u8_gunNo, U8_T serialNum); //远程停机应答 0x45
void v_ies_rmt_oprt_ack(U8_T *u8_opr_cmd, U8_T opr_result); //远程操作应答 0x77
void v_ies_heart_ack(void);
void v_ies_register_ack(U8_T *u8_recvBuf); //登陆帧应答
void v_ies_fee_ack(U8_T *u8_recvBuf); //计费模型应答帧
void v_ies_set_clk_sync(U8_T *u8_recvBuf); //对时
void v_ies_set_fee(U8_T *u8_recvBuf); //计费模型设置
void v_ies_upgrade_data_auto(U8_T *u8_recvBuf); //平台应答文件内容请求
void v_ies_start_req(U8_T gunNo); //主动启动充电请求 0x41
void v_ies_rx_start(U8_T *u8_recvBuf); //运营确认启动 0x42
void v_ies_bill_upload_ack(U8_T *u8_recvBuf); //结算账单应答
void v_ies_rmt_start(U8_T *u8_recvBuf); //远程启动
void v_ies_rmt_stop(U8_T *u8_recvBuf); //远程停机
void v_ies_rmt_oprt(U8_T *u8_recvBuf) ; //远程操作
void v_ies_qr_call(U8_T *u8_recvBuf) ; //二维码召唤
void v_ies_qr_dis(U8_T *u8_recvBuf) ; //二维码下发
U8_T u8_ies_get_gunLink_state(U8_T u8_gunNo);
U8_T u8_ies_get_gun_state(U8_T u8_gunNo);
#endif
#ifdef __cplusplus
}
#endif
#endif /* BS_IES_INTERFACE_H */