Files
CCU621M/app/ui/ui_interface.c
T

1126 lines
55 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "ui/ui_comm_impl.h"
#include "ui/ui_task.h"
#include "ui/ui_interface.h"
#include "publicdata/publicdata.h"
#include "collect_ctrl/collect_task.h"
#include "flowctrl/flow_interface.h"
#include "bms/bms_interface.h"
#include "meter_calculate/meter_calculate_impl.h"
#include "fault_cheak/fault_interface.h"
#include "flash_file_mgr/fault_flash_impl.h"
#include "flash_file_mgr/meter_calculate_flash_impl.h"
#include "card_ctrl/card_ctrl.h"
#include "plat_comm/impl/bs_public_impl.h"
#include "ui/ui_info.h"
static void v_ui_get_RQ_code(U8_T u8_gunNo,U8_T *u8_mag , U16_T u16_len);
static U16_T u16_get_first_stop_reason(const S_LOG_DATA *item);
extern S_UI_CTRL_DATA s_ui_ctrl;
/* 防御性枪号归一化:非法枪号统一回退到 0 号枪,避免数组越界。 */
static U8_T ui_safe_gun(U8_T gun_no)
{
return (gun_no < GUN_MAX_CNT) ? gun_no : 0u;
}
void v_ui_request_idle_screen_recover(void)
{
s_ui_ctrl.u8_flow_idle_recover_req = 1U;
}
/**
* @brief UI读取系统数值接口
* @param u8_gunNo 枪号(0~GUN_MAX_CNT-1
* @param e_dataType 数据类型(界面状态、流程状态、计量值等)
* @param u16_dataPara 预留参数(当前兼容实现未使用)
* @return 对应数据值
*
* 设计说明:
* - 已接入:UI使能、屏保使能、枪数量、语言、时区。
* - 未接入:流程/BMS/计量/平台在线等,当前统一返回 0,保证界面可编译可运行。
*/
U16_T u16_ui_get_sys_data(U8_T u8_gunNo, E_UI_GET_DATA_TYPE e_dataType, U16_T u16_dataPara)
{
U8_T gun_no = ui_safe_gun(u8_gunNo);
U16_T u16_ret = 0;
switch (e_dataType)
{
case E_UI_GET_DATA_UI_EN : //UI使能 0不使能 1使能
{
u16_ret = g_t_share_data.t_sys_fix_cfg.u_enable.bit_enable.bit_LcdEnable;
break;
}
case E_UI_GET_DATA_SCREEN_SAVER_EN: //UI屏保界面显示使能 0不使能 1使能 2使能轮播
{
u16_ret = g_t_share_data.t_sys_fix_cfg.u_enable.bit_enable.bit_ScreenSaverEn;
break;
}
case E_UI_GET_DATA_GUN_CNT: //枪数量
{
u16_ret = g_t_share_data.t_sys_fix_cfg.u8_gunCnt;
break;
}
case E_UI_GET_DATA_LALANGGUAGE_TYPE: //语言类型 0中文 1英文
{
u16_ret = g_t_share_data.t_sys_fix_cfg.u_enable.bit_enable.bit_uiEnglishEn; //UI界面 英语使能 0 中文 1英文;
break;
}
case E_UI_GET_DATA_GUN_LINK: //枪连接状态 0未连接 1已连接; AB枪根据参数区分 0-1
{
u16_ret = u8_get_gun_yx_data(YX_GUN_LINK,u8_gunNo);
break;
}
case E_UI_GET_DATA_TIME_ZONE: //时区偏移量
{
u16_ret = g_t_share_data.t_sys_fix_cfg.e_timeZone;
break;
}
case E_UI_GET_DATA_BS_COMM_FLAG: //平台连接标志 0未连接 1已连接
{
u16_ret = u8_bs_get_log_on_flag();
break;
}
case E_UI_GET_DATA_BS_UPDATE_FLAG: //获取远程升级标志
{
u16_ret = u8_bs_get_update_flag();
break;
}
case E_UI_GET_DATA_FLOW_STAET: //充电流程控制状态 0空闲 1充电启动 2绝缘启动 3绝缘计算完成 4绝缘检测模块停止 5开始预充 6预充完成 7充电中 8BMS通讯超时 9充电停止 10充电停止完成
{
u16_ret = u16_flow_put_data(u8_gunNo , E_FLOW_PUT_DATA_GUN_REAL_STATE,0); //0空闲 1充电启动 2绝缘启动 3绝缘计算完成 4绝缘检测模块停止 5开始预充 6预充完成 7充电中 8BMS通讯超时 9充电停止 10充电停止完成
break;
}
case E_UI_GET_DATA_CHAR_VOL: //充电电压 精度 0.1V
{
u16_ret = (U16_T)(u64_get_meter_data(u8_gunNo,0,E_METER_DATA_VOL)/1000);
break;
}
case E_UI_GET_DATA_CHAR_CUR: //充电电流 精度 0.1A
{
u16_ret = (U16_T)(u64_get_meter_data(u8_gunNo,0,E_METER_DATA_CUR)/1000);
break;
}
case E_UI_GET_DATA_CHAR_POWER_H2: //充电电量 高2字节 精度 0.0001 -- 65535
{
u16_ret = (U16_T)(u32_meterlog_put_data(u8_gunNo,E_METERLOG_PUT_LOG_INFO_USED_ENERGY,NULL,0) >> 16);
break;
}
case E_UI_GET_DATA_CHAR_POWER_L2: //充电电量 底2字节 精度 0.0001 -- 65535
{
u16_ret = (U16_T)(u32_meterlog_put_data(u8_gunNo,E_METERLOG_PUT_LOG_INFO_USED_ENERGY,NULL,0) & 0xFFFF);
break;
}
case E_UI_GET_DATA_CHAR_MONEY: //充电金额 0.001元
{
u16_ret = (U16_T)(u32_meterlog_put_data(u8_gunNo,E_METERLOG_PUT_LOG_INFO_USED_MONEY,NULL,0)+ u32_meterlog_put_data(u8_gunNo,E_METERLOG_PUT_LOG_INFO_USED_SERVICE,NULL,0))/ 10; //精度转换,由0.0001转换为0.001
break;
}
case E_UI_GET_DATA_CHAR_TIME: //充电时间 min
{
u16_ret = (U16_T)(u32_meterlog_put_data(u8_gunNo,E_METERLOG_PUT_LOG_INFO_CHAR_TIME,NULL,0)); //获取充电时间
break;
}
case E_UI_GET_DATA_CHAR_SOC: //充电soc %
{
u16_ret = u16_bms_put_data(u8_gunNo,E_BMS_PUT_DATA_GUN_SOC,0);
break;
}
case E_UI_GET_DATA_BAAT_TYPE: //电池类型 01H,铅酸电池;02H:镍氢电池;03H:磷酸铁锂电池;04H:锰酸锂电池;05H:钴酸锂电池;
{
u16_ret = u16_bms_put_data(u8_gunNo,E_BMS_PUT_DATA_GUN_BATT_TYPE,0);
break;
}
case E_UI_GET_DATA_NEED_VOL: //需求电压 精度 0.1V
{
u16_ret = u16_bms_put_data(u8_gunNo,E_BMS_PUT_DATA_BMS_NEED_VOL,0);
break;
}
case E_UI_GET_DATA_NEED_CUR: //需求电流 精度 0.1A
{
u16_ret = u16_bms_put_data(u8_gunNo,E_BMS_PUT_DATA_BMS_NEED_CUR,0);
break;
}
case E_UI_GET_DATA_BATT_ONE_MAX_TEMP: //最高单体温度 度
{
u16_ret = u16_bms_put_data(u8_gunNo,E_BMS_PUT_DATA_GUN_ONE_BATT_MAX_TEMP,0);
break;
}
case E_UI_GET_DATA_BATT_ONE_MAX_VOL: //最高单体电压 0.1V
{
u16_ret = u16_bms_put_data(u8_gunNo,E_BMS_PUT_DATA_GUN_ONE_BATT_MAX_VOL,0);
break;
}
case E_UI_GET_DATA_BATT_RATED_C10: //电池容量 0.1
{
u16_ret = u16_bms_put_data(u8_gunNo,E_BMS_PUT_DATA_GUN_BATT_RATED_C10,0);
break;
}
case E_UI_GET_DATA_RATED_VOL: //额定电压 0.1
{
u16_ret = u16_bms_put_data(u8_gunNo,E_BMS_PUT_DATA_BMS_MAX_VOL,0);
break;
}
case E_UI_GET_DATA_MAX_OUT_CUR: //最大充电电流 0.1
{
u16_ret = u16_bms_put_data(u8_gunNo,E_BMS_PUT_DATA_BMS_MAX_CUR,0);
break;
}
case E_UI_GET_DATA_STOP_INFO: //充电停止原因
{
u16_ret = u16_flow_put_data(u8_gunNo,E_FLOW_PUT_DATA_GUN_STOP_RES,0);
break;
}
case E_UI_GET_DATA_FAULT_NUM: //故障数量
{
if(u16_dataPara == 0) //所有故障
u16_ret = u8_get_fault_sum(0,0);
else
{
u16_ret = u8_get_fault_sum(u8_gunNo+1,0); //根据抢号 获取故障信息
}
break;
}
default:
break;
}
return u16_ret;
}
/**
* @brief UI读取字符串接口
* @param u8_gunNo 枪号
* @param e_dataType 字符串类型(桩号/域名/二维码/APN/版本等)
* @param u16_dataPara 预留参数(版本字符串会使用该参数区分来源)
* @param u8_str 输出缓冲区
* @param u16_len 输出缓冲区长度
* @return 实际字符串长度(0表示无有效数据)
*
* 实现策略:
* - 所有输出先清零并强制保留 '\0' 结尾,避免屏幕显示脏数据。
* - 网络相关字符串统一从 t_sys_fix_cfg.s_net_cfg 读取。
*/
U8_T u8_ui_get_sys_str(U8_T u8_gunNo, E_UI_GET_STR_TYPE e_dataType , U16_T u16_dataPara ,U8_T *u8_str , U16_T u16_len)
{
U8_T gun_no = ui_safe_gun(u8_gunNo);
(void)u16_dataPara;
if ((u8_str == NULL) || (u16_len == 0u)) {
return 0u;
}
memset(u8_str , 0 , u16_len); // 清空数据内容
switch (e_dataType)
{
case E_UI_GET_STR_PILE_NO: //桩编号 参数区分获取两平台桩编号信息
{
//v_pcu_put_pile_mun(&g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platA_pileNum[0]);
strncpy((char *)u8_str , (char *)g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platA_pileNum ,u16_len);
break;
}
case E_UI_GET_STR_VERSION_INFO: //版本信息
{
if(u16_dataPara == 0)
strncpy((char *)u8_str , (char *)g_t_share_data.t_sys_var_cfg.custom_ver ,u16_len);
else
strncpy((char *)u8_str , (char *)Software_Version ,u16_len);
break;
}
case E_UI_GET_STR_MAINTENANCE_PWD: //维护密码
{
strncpy((char *)u8_str , (char *)g_t_share_data.t_sys_fix_cfg.u8_pwd ,u16_len);
break;
}
case E_UI_GET_STR_PILENO: //平台桩编号
{
if(u8_gunNo == 0)
strncpy((char *)u8_str , (char *)g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platA_pileNum ,u16_len);
else
strncpy((char *)u8_str , (char *)g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platB_pileNum ,u16_len);
break;
}
case E_UI_GET_STR_DOMAIN: //平台服务器域名
{
if(u8_gunNo == 0)
strncpy((char *)u8_str , (char *)g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_serverA_domain_name ,u16_len);
else
strncpy((char *)u8_str , (char *)g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_serverB_domain_name ,u16_len);
break;
}
case E_UI_GET_STR_QR: //二维码
case E_UI_GET_STR_QRcode: //二维码
{
v_ui_get_RQ_code(u8_gunNo,u8_str, u16_len);
break;
}
case E_UI_GET_STR_APN: //apn
{
strncpy((char *)u8_str , (char *)&g_t_share_data.t_sys_var_cfg.apn_str ,u16_len);
break;
}
case E_UI_GET_STR_OCPP_AUTH_KEY: //OCPP鉴权密钥
{
strncpy((char *)u8_str , (char *)&g_t_share_data.t_sys_var_cfg.ocpp_auth_key ,u16_len);
break;
}
default:
break;
}
return (U8_T)strlen((char *)u8_str);
}
/**
* @brief 获取历史故障条数
*/
U16_T u16_ui_get_his_fault_count(void)
{
#if (FAULT_FLASH_MGR_ENABLE)
return u16_fault_get_his_count();
#else
return 0u;
#endif
}
/**
* @brief 获取历史故障单行文本(newest_pos: 0=最新)
*/
U8_T u8_ui_get_his_fault_line(U16_T newest_pos, U8_T *u8_str, U16_T u16_len)
{
HIS_FAULT_DATA_T item;
if ((u8_str == NULL) || (u16_len == 0u)) {
return 0u;
}
memset(u8_str, 0, u16_len);
memset(&item, 0, sizeof(item));
#if (FAULT_FLASH_MGR_ENABLE)
if (u8_fault_read_his_by_newest(newest_pos, &item) == 0u) {
return 0u;
}
#else
(void)newest_pos;
strncpy((char *)u8_str, "Fault history disabled", u16_len - 1u);
return (U8_T)strlen((char *)u8_str);
#endif
(void)snprintf((char *)u8_str, u16_len,
"SN:%u TS:%02u-%02u %02u:%02u:%02u FC:%u FS:%u P1:%d P2:%d",
(unsigned)(newest_pos + 1u),
item.s_occur_time.ucMonth, item.s_occur_time.ucDay,
item.s_occur_time.ucHour, item.s_occur_time.ucMin, item.s_occur_time.ucSec,
(unsigned)item.e_fault_info, (unsigned)item.e_site,
(int)item.s16_value1, (int)item.s16_value2);
return (U8_T)strlen((char *)u8_str);
}
/**
* @brief 获取历史充电记录条数
*/
U16_T u16_ui_get_his_charge_count(void)
{
return v_get_chg_order_count();
}
/**
* @brief 获取历史充电记录单行文本(newest_pos: 0=最新)
*/
U8_T u8_ui_get_his_charge_line(U16_T newest_pos, U8_T *u8_str, U16_T u16_len)
{
S_LOG_DATA item;
U16_T total = u16_ui_get_his_charge_count();
U16_T pos_from_oldest;
U16_T stop_reason;
U32_T elec_fee;
char uid[33] = {0};
char ord_pre[EVS_MAX_TRADE_LEN + 1] = {0};
char ord_dev[EVS_MAX_TRADE_LEN + 1] = {0};
char energy_str[24] = {0};
char money_str[24] = {0};
const char *uid_out = "-";
const char *ord_dev_out = "-";
const char *ord_pre_out = "-";
if (u8_str == NULL || u16_len == 0 || total == 0 || newest_pos >= total) {
return 0;
}
memset(u8_str, 0, u16_len);
memset(&item, 0, sizeof(item));
/* v_read_chg_order_by_position 使用从最早到最新的顺序 */
pos_from_oldest = (U16_T)(total - 1u - newest_pos);
if (v_read_chg_order_by_position(&item, pos_from_oldest) != 0) {
return 0;
}
stop_reason = u16_get_first_stop_reason(&item);
elec_fee = (item.u32_used_money >= item.u32_used_service) ?
(item.u32_used_money - item.u32_used_service) : 0u;
strncpy(uid, (const char *)item.u8_user_id, sizeof(uid) - 1u);
strncpy(ord_pre, (const char *)item.u8_preTradeNo, sizeof(ord_pre) - 1u);
strncpy(ord_dev, (const char *)item.u8_tradeNo, sizeof(ord_dev) - 1u);
if (uid[0] != '\0') {
uid_out = uid;
}
if (ord_dev[0] != '\0') {
ord_dev_out = ord_dev;
}
if (ord_pre[0] != '\0') {
ord_pre_out = ord_pre;
}
/* 电量/金额:0.0001 单位,按 xxxx.xxxx 显示(不依赖浮点库) */
snprintf(energy_str, sizeof(energy_str), "%lu.%04lu",
(unsigned long)(item.u32_used_energy / 10000u),
(unsigned long)(item.u32_used_energy % 10000u));
snprintf(money_str, sizeof(money_str), "%lu.%04lu",
(unsigned long)(item.u32_used_money / 10000u),
(unsigned long)(item.u32_used_money % 10000u));
snprintf((char *)u8_str, u16_len,
"SN:%u GUN:%u ST:%04u-%02u-%02u %02u:%02u:%02u ET:%04u-%02u-%02u %02u:%02u:%02u "
"SOC:%u->%u EGY:%s(kWh) AMT:%s(CNY) SVC:%lu.%04lu ELC:%lu.%04lu "
"UID:%s ORD_DEV:%s ORD_PRE:%s RSN:%u",
(unsigned)(newest_pos + 1u),
(unsigned)item.u8_gunNo,
(unsigned)item.StartChargeTime.iYear,
(unsigned)item.StartChargeTime.ucMonth, (unsigned)item.StartChargeTime.ucDay,
(unsigned)item.StartChargeTime.ucHour, (unsigned)item.StartChargeTime.ucMin, (unsigned)item.StartChargeTime.ucSec,
(unsigned)item.EndChargeTime.iYear,
(unsigned)item.EndChargeTime.ucMonth, (unsigned)item.EndChargeTime.ucDay,
(unsigned)item.EndChargeTime.ucHour, (unsigned)item.EndChargeTime.ucMin, (unsigned)item.EndChargeTime.ucSec,
(unsigned)item.u8_startSoc, (unsigned)item.u8_endSoc,
energy_str,
money_str,
(unsigned long)(item.u32_used_service / 10000u),
(unsigned long)(item.u32_used_service % 10000u),
(unsigned long)(elec_fee / 10000u),
(unsigned long)(elec_fee % 10000u),
uid_out, ord_dev_out, ord_pre_out, (unsigned)stop_reason);
return (U8_T)strlen((char *)u8_str);
}
static U16_T u16_get_first_stop_reason(const S_LOG_DATA *item)
{
U16_T i;
if (item == NULL) {
return 0u;
}
for (i = 0; i < NUM_5; i++) {
if (item->e_stop_reason[i] != E_FAULT_NULL) {
return (U16_T)item->e_stop_reason[i];
}
}
return 0u;
}
static void v_ui_get_RQ_code(U8_T u8_gunNo,U8_T *u8_mag , U16_T u16_len)
{
U8_T u8_bs_type = 0; //平台类型 0国网SDK 1积成
U8_T cStrig1[140]="https://cdn-evone-oss.echargenet.com/IntentServe/index.html?M&qrcode=gwwl//:1049:1.0.0:3:"; //{"type":"echarging","systemCode":"桩号","terminalCode":"枪号"}
U8_T cStrig2[20]=":FFFFFFFFFFFF:"; //0\"}";
U8_T cStrig8[80]="https://qrcode.iesztn.com/zl/iecharge?pileno=";
U8_T cStrig9[20] = "&gunno=";
U8_T u8_terminal = 0;//u16_pcu_get_sys_data(u8_gunNo,E_PCU_DATA_TYPE_GUN_ADDR); //获取充电枪地址
if(strlen((char *)&g_t_share_data.t_sys_var_cfg.QRDisplay[u8_gunNo][0]))
strncpy((char *)u8_mag , (char *)&g_t_share_data.t_sys_var_cfg.QRDisplay[u8_gunNo][0] , u16_len);
else
{
if(u8_bs_type == 0) //国网sdk
{
//v_pcu_put_pile_mun((U8_T *)&g_t_share_data.t_sys_var_cfg.s_sdk_data.device_uid[0]);
memcpy(&cStrig1[strlen((const char*)cStrig1)], g_t_share_data.t_sys_var_cfg.s_sdk_data.device_uid, 16);
memcpy(&cStrig1[strlen((const char*)cStrig1)], cStrig2, strlen((const char*)cStrig2));
cStrig1[strlen((const char*)cStrig1)] = 0x30;
cStrig1[strlen((const char*)cStrig1)] = 0x30;
cStrig1[strlen((const char*)cStrig1)] = u8_terminal+0x30;
strncpy((char *)u8_mag , (char *)&cStrig1[0] , u16_len);
}
else
{
/* 平台桩编号在固定配置的网络参数内:t_sys_fix_cfg.s_net_cfg.u8_platA_pileNum */
{
size_t pn_len = strlen((const char *)g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platA_pileNum);
if (pn_len > 16u) pn_len = 16u;
memcpy(&cStrig8[strlen((const char*)cStrig8)],
g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platA_pileNum,
pn_len);
}
memcpy(&cStrig8[strlen((const char*)cStrig8)], cStrig9, strlen((const char*)cStrig9));
cStrig8[strlen((const char*)cStrig8)] = u8_terminal+0x30;
strncpy((char *)u8_mag , (char *)&cStrig8[0] , u16_len);
}
}
}
/**
* ************************************************************************
* @brief - 充电控制 启动、停止
*
* @param[in] u8_gunNo - 枪号 0-N
* @param[in] e_cmd - 控制命令 CMD_ON 启动 CMD_OFF 停止
* @param[in] e_type - 启动方式 0vin 1刷卡
*
* @return U8_T - 1执行成功 0执行失败
*
* @author jiankalka
* @date 2025-09-08
* ************************************************************************
*/
U8_T u8_ui_ctrl_charge(U8_T u8_gunNo,E_CMD e_cmd, E_START_TYPE e_type)
{
U8_T u8_log_ctrl = 0; //订单写入控制 0不动作 1开始充电写入 2停止充电写入
U8_T u8_cardId[NUM_32] = {0};
S_FLOW_CHARGE_CTRL_INFO e_charge_ctrl_info;
memset(&e_charge_ctrl_info , 0, sizeof(S_FLOW_CHARGE_CTRL_INFO));
e_charge_ctrl_info.e_cmd = e_cmd;
if(e_cmd == CMD_ON) //启动
{
if(e_type == E_START_VIN || e_type == E_START_DEBUG)
{
e_charge_ctrl_info.e_start_res = CtR_CMD_VIN_START; //VIN即插即充 CTR_CMD_DEBUG;//
u8_log_ctrl = 1; //1开始充电写入
}
else{
e_charge_ctrl_info.e_start_res = CTR_CMD_ONCARD_START; //在线卡
if(g_t_share_data.t_sys_fix_cfg.u_enable.bit_enable.bit_PlugEn == 1 ) //即插即充使能时 刷卡按调试启动
e_charge_ctrl_info.e_start_res = CTR_CMD_DEBUG;
if(u8_read_card_id(u8_cardId,NUM_32) > 0)
{
UI_LOG("recv card ok ,%s\r\n",u8_cardId);
u8_log_ctrl = 1; //1开始充电写入
}
else
{
return 0; //执行失败
}
}
e_charge_ctrl_info.e_sdk_chargMode = E_SDK_CHGMOD_NONE; //不做限制
}
else //停止
{
if(e_type == E_START_CARD) //刷卡停止
{
if(u8_read_card_id(u8_cardId,NUM_32) > 0)
{
UI_LOG("recv card ok ,%s\r\n",u8_cardId);
U8_T u8_log_cardId[NUM_32];
u32_meterlog_put_data(u8_gunNo,E_METERLOG_PUT_LOG_INFO_USER_ID,u8_log_cardId,NUM_32);
if(strcmp((char *)u8_cardId,(char *)u8_log_cardId) == 0) //卡号一致 停止成功
{
u8_log_ctrl = 2; //1开始充电写入
}
else //卡号不一致
return 0;
}
else
{
return 0; //执行失败
}
}
e_charge_ctrl_info.e_stop_res = E_NORMAL_1001; //本地停止
}
v_flow_start_stop_ctrl(u8_gunNo,&e_charge_ctrl_info);
if(u8_log_ctrl == 2) //停止充电西而入
{
v_meterlog_set_stop_char_log_info(u8_gunNo , E_NORMAL_1001); //本地停止
}
else if(u8_log_ctrl == 1) //开始充电写入
{
S_CHAR_LOG_START_DATA s_log_start_data;
memset(&s_log_start_data , 0 ,sizeof(S_CHAR_LOG_START_DATA));
//控制写入订单信息
s_log_start_data.e_start_reason = e_charge_ctrl_info.e_start_res; //启动方式
/* 离线/本地刷卡尚无平台 transactionId:填 0xFF 占位;联网后由 BS_ocpp_ctrl 未结订单流程先发 StartTransaction 取号再 StopTransaction(勿改用 strlen 判断是否有号) */
s_log_start_data.u8_preTradeNo[0] =0xFF;
s_log_start_data.u8_preTradeNo[1] =0xFF;
s_log_start_data.u8_preTradeNo[2] =0xFF;
s_log_start_data.u8_preTradeNo[3] =0xFF;
s_log_start_data.u8_preTradeNo[4] =0xFF;
s_log_start_data.u8_preTradeNo[5] =0xFF;
s_log_start_data.u8_preTradeNo[6] =0xFF;
s_log_start_data.u8_preTradeNo[7] =0xFF;
if(e_type == E_START_CARD)
strncpy((char *)s_log_start_data.u8_user_id , (char *)u8_cardId , EVS_MAX_TRADE_LEN);
v_meterlog_set_start_char_log_info(u8_gunNo,&s_log_start_data);
}
return 1;
}
/**
* @brief UI通讯超时上报接口
* @param u8_flag 1=通讯超时/故障;0=通讯恢复
*
* 说明:
* - 使用现有故障模块接口 `v_set_fault_data` 触发/恢复故障码 13089(人机通信异常)
* - 通过 `u8_cheak_fault_flag` 去重,避免重复入表
*/
void v_ui_set_comm_timeout(U8_T u8_flag)
{
U8_T u8_ui_fault_flag = u8_cheak_fault_flag(E_FAULT_13089, E_WHOLE_PILE);
if ((u8_flag == 1u) && (u8_ui_fault_flag == 0u)) {
v_set_fault_data(E_WHOLE_PILE, E_FAULT, E_FAULT_13089, 0u, 0, 0); /* UI comm fault */
} else if ((u8_flag == 0u) && (u8_ui_fault_flag != 0u)) {
v_set_fault_data(E_WHOLE_PILE, E_RES, E_FAULT_13089, 0u, 0, 0); /* UI comm fault */
}
}
/**
* ************************************************************************
* @brief - 获取终端充电状态
*
* @param[in] u8_gunNo - 抢号 0-N
*
* @return U8_T - 0空闲/停止 1启动中 2充电中
*
* @author jiankalka
* @date 2025-09-11
* ************************************************************************
*/
U8_T u8_ui_gun_work_state(U8_T u8_gunNo)
{
U8_T u8_ret = 0;
U8_T u8_state = u16_ui_get_sys_data(u8_gunNo,E_UI_GET_DATA_FLOW_STAET,0); //0空闲 1充电启动 2绝缘启动 3绝缘计算完成 4绝缘检测模块停止 5开始预充 6预充完成 7充电中 8BMS通讯超时 9充电停止 10充电停止完成
/*E_FLOW_REAL_FREE=0 , //空闲
E_FLOW_REAL_CHARGE_START , //充电启动
E_FLOW_REAL_INSUL_START , //绝缘启动
E_FLOW_REAL_INSUL_OK , //绝缘计算完成
E_FLOW_REAL_INSUL_MDU_STOP , //绝缘检测模块停止
E_FLOW_REAL_PRE_START , //开始预充
E_FLOW_REAL_PRE_OK , //预充完成
E_FLOW_REAL_CHARGEING , //充电中
E_FLOW_REAL_BMS_OUTTIME , //BMS通讯超时
E_FLOW_REAL_STOP , //充电停止
E_FLOW_REAL_STOP_OK , //充电停止完成 */
if(u8_state > E_FLOW_REAL_FREE && u8_state < E_FLOW_REAL_CHARGEING) //启动中
{
u8_ret = 1;
}
else if(u8_state == E_FLOW_REAL_CHARGEING || u8_state == E_FLOW_REAL_BMS_OUTTIME) //充电中
{
u8_ret = 2;
}
return u8_ret;
}
/**
* ************************************************************************
* @brief - 获取充电方式
*
* @param[in] u8_gunNo - 枪号 0-1
*
* @return U8_T - 1刷卡
*
* @author jiankalka
* @date 2026-01-20
* ************************************************************************
*/
START_REASON e_ui_get_charge_way(U8_T u8_gunNo)
{
U32_T u32_data;
u32_data = u32_meterlog_put_data(u8_gunNo,E_METERLOG_PUT_LOG_INFO_START_TYPE,NULL,0);
return (START_REASON)u32_data;
}
E_CHARGE_STATUS e_ui_get_charge_status(U8_T u8_gunNo)
{
U8_T u8_charge_status;
U8_T u8_state = u16_ui_get_sys_data(u8_gunNo,E_UI_GET_DATA_FLOW_STAET,0); //0空闲 1充电启动 2绝缘启动 3绝缘计算完成 4绝缘检测模块停止 5开始预充 6预充完成 7充电中 8BMS通讯超时 9充电停止 10充电停止完成
U8_T u8_gunLink = u16_ui_get_sys_data(u8_gunNo,E_UI_GET_DATA_GUN_LINK,0); //枪连接状态 0未连接 1已连接
U8_T u8_disable_flag = u8_bs_get_gun_disable_flag(u8_gunNo); //获取枪禁用标志 0未禁用 1禁用
U8_T u8_fault_sum = u8_get_fault_sum(0,0); //获取整桩故障数量
U8_T u8_gun_fault_sum = u8_get_fault_sum(u8_gunNo+1,0); //获取枪故障数量
/*E_CHARGE_STATUS_AVAILABLE, //空闲
E_CHARGE_STATUS_PREPARING, //准备中
E_CHARGE_STATUS_CHARGING, //充电中
E_CHARGE_STATUS_SUSPENDED_EVSE, //充电暂停(充电桩原因)
E_CHARGE_STATUS_SUSPENDED_EV, //充电暂停(车辆原因)
E_CHARGE_STATUS_FINISHING, //结束充电
E_CHARGE_STATUS_RESERVED, //预留
E_CHARGE_STATUS_UNAVAILABLE, //不可用
E_CHARGE_STATUS_FAULTED //故障
*/
if(u8_disable_flag == 1) //禁用
{
return E_CHARGE_STATUS_UNAVAILABLE; //不可用
}
else if(u8_fault_sum > 0 || u8_gun_fault_sum > 0) //故障
{
return E_CHARGE_STATUS_FAULTED; //故障
}
else if(u8_state == E_FLOW_REAL_FREE) //空闲/停止
{
if(u8_gunLink == 0) //枪未连接
{
return E_CHARGE_STATUS_AVAILABLE;
}
else
{
return E_CHARGE_STATUS_PREPARING;
}
}
else if(u8_state > E_FLOW_REAL_FREE && u8_state < E_FLOW_REAL_CHARGEING) //启动中
{
return E_CHARGE_STATUS_PREPARING;
}
else if(u8_state == E_FLOW_REAL_CHARGEING || u8_state == E_FLOW_REAL_BMS_OUTTIME) //充电中
{
return E_CHARGE_STATUS_CHARGING;
}
else if(u8_state == E_FLOW_REAL_STOP || u8_state == E_FLOW_REAL_STOP_OK) //充电停止
{
return E_CHARGE_STATUS_FINISHING;
}
return (E_CHARGE_STATUS)u8_charge_status;
}
/**
* ************************************************************************
* @brief - 获取充电电量
*
* @param[in] u8_gunNo - 枪号 0-1
*
* @return U32_T - 充电电量 单位0.0001度
*
* @author jiankalka
* @date 2026-01-20
* ************************************************************************
*/
U32_T u32_ui_get_charge_power(U8_T u8_gunNo)
{
return u32_meterlog_put_data(u8_gunNo,E_METERLOG_PUT_LOG_INFO_USED_ENERGY,NULL,0); //获取充电电量;
}
#if 1 //系统参数配置
#define UI_PARAM_INFO_PRINT_ENABLE 0 //是否打印参数信息 1为打印 0为不打印
#if UI_PARAM_INFO_PRINT_ENABLE == 1
//参数信息内容打印 u8_falg 0为获取 1为保存
void v_ui_param_info_print(U8_T u8_flag, E_UI_PARAM_TYPE_T e_type)
{
printf("v_ui_param_info_print,u8_flag=%s,e_type=%d\r\n",(u8_flag==0)?"获取":"保存",e_type);
if(e_type == E_UI_PARAM_TYPE_SYSTEM)
{
// 0x0200~0x020C
printf("[0x0200] number_of_guns=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.number_of_guns);
printf("[0x0201] pile_type=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.pile_type);
printf("[0x0202] terminal_address_1=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.terminal_address_1);
printf("[0x0203] terminal_address_2=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.terminal_address_2);
printf("[0x0204] gun_type_1=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.gun_type_1);
printf("[0x0205] gun_type_2=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.gun_type_2);
printf("[0x0206] light_panel_type=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.light_panel_type);
printf("[0x0207] lcd_enable=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.lcd_enable);
printf("[0x0208] system_time_zone=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.system_time_zone);
printf("[0x0209] language_type=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.language_type);
printf("[0x020A] liquid_cooling_enable=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.liquid_cooling_enable);
printf("[0x020B] host_comm_type=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.host_comm_type);
printf("[0x020C] screensaver_enable=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.screensaver_enable);
printf("[0x020D] card_type=%d\r\n",s_ui_param.s_ui_param_union.s_ui_system_param.card_type);
}
else if(e_type == E_UI_PARAM_TYPE_PILE_PROTECT)
{
// 0x0220~0x022A
printf("[0x0220] min_out_vol=%d\r\n",s_ui_param.s_ui_param_union.s_ui_pile_protect_param.min_out_vol);
printf("[0x0221] max_out_vol=%d\r\n",s_ui_param.s_ui_param_union.s_ui_pile_protect_param.max_out_vol);
printf("[0x0222] max_out_cur=%d\r\n",s_ui_param.s_ui_param_union.s_ui_pile_protect_param.max_out_cur);
printf("[0x0223] pile_rated_power=%d\r\n",s_ui_param.s_ui_param_union.s_ui_pile_protect_param.pile_rated_power);
printf("[0x0224] fan_start_temp=%d\r\n",s_ui_param.s_ui_param_union.s_ui_pile_protect_param.fan_start_temp);
printf("[0x0225] fan_stop_temp=%d\r\n",s_ui_param.s_ui_param_union.s_ui_pile_protect_param.fan_stop_temp);
printf("[0x0226] gun_temp_thresh=%d\r\n",s_ui_param.s_ui_param_union.s_ui_pile_protect_param.gun_temp_thresh);
printf("[0x0227] pile_temp_thresh=%d\r\n",s_ui_param.s_ui_param_union.s_ui_pile_protect_param.pile_temp_thresh);
printf("[0x0228] gun1_power_limit=%d\r\n",s_ui_param.s_ui_param_union.s_ui_pile_protect_param.gun1_power_limit);
printf("[0x0229] gun2_power_limit=%d\r\n",s_ui_param.s_ui_param_union.s_ui_pile_protect_param.gun2_power_limit);
printf("[0x022A] soc_thresh=%d\r\n",s_ui_param.s_ui_param_union.s_ui_pile_protect_param.soc_thresh);
}
else if(e_type == E_UI_PARAM_TYPE_NETWORK)
{
// 0x0240~0x0254
printf("[0x0240] local_ip=%d.%d.%d.%d\r\n",
s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_1,
s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_2,
s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_3,
s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_4);
printf("[0x0244] gateway=%d.%d.%d.%d\r\n",
s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_1,
s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_2,
s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_3,
s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_4);
printf("[0x0248] mac=%02X:%02X:%02X:%02X:%02X:%02X\r\n",
(unsigned)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_1,
(unsigned)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_2,
(unsigned)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_3,
(unsigned)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_4,
(unsigned)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_5,
(unsigned)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_6);
printf("[0x024E] apn_type=%d\r\n",s_ui_param.s_ui_param_union.s_ui_net_param.apn_type);
printf("[0x024F] plat1_enable=%d\r\n",s_ui_param.s_ui_param_union.s_ui_net_param.plat1_enable);
printf("[0x0250] plat1_net_type=%d\r\n",s_ui_param.s_ui_param_union.s_ui_net_param.plat1_net_type);
printf("[0x0251] plat1_plat_type=%d\r\n",s_ui_param.s_ui_param_union.s_ui_net_param.plat1_plat_type);
printf("[0x0252] plat2_enable=%d\r\n",s_ui_param.s_ui_param_union.s_ui_net_param.plat2_enable);
printf("[0x0253] plat2_net_type=%d\r\n",s_ui_param.s_ui_param_union.s_ui_net_param.plat2_net_type);
printf("[0x0254] plat2_plat_type=%d\r\n",s_ui_param.s_ui_param_union.s_ui_net_param.plat2_plat_type);
}
else if(e_type == E_UI_PARAM_TYPE_MODULE)
{
// 0x0260~0x0264
printf("[0x0260] module_rated_power=%d\r\n",s_ui_param.s_ui_param_union.s_ui_module_param.module_rated_power);
printf("[0x0261] module_rated_volt=%d\r\n",s_ui_param.s_ui_param_union.s_ui_module_param.module_rated_volt);
printf("[0x0262] module_rated_cur=%d\r\n",s_ui_param.s_ui_param_union.s_ui_module_param.module_rated_cur);
printf("[0x0263] module_count=%d\r\n",s_ui_param.s_ui_param_union.s_ui_module_param.module_count);
printf("[0x0264] module_type=%d\r\n",s_ui_param.s_ui_param_union.s_ui_module_param.module_type);
}
else if(e_type == E_UI_PARAM_TYPE_RESERVE)
{
// 0x0280~0x028B
printf("[0x0280] reserve_1=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_1);
printf("[0x0281] reserve_2=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_2);
printf("[0x0282] reserve_3=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_3);
printf("[0x0283] reserve_4=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_4);
printf("[0x0284] reserve_5=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_5);
printf("[0x0285] reserve_6=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_6);
printf("[0x0286] reserve_7=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_7);
printf("[0x0287] reserve_8=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_8);
printf("[0x0288] reserve_9=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_9);
printf("[0x0289] reserve_10=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_10);
printf("[0x028A] reserve_11=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_11);
printf("[0x028B] reserve_12=%d\r\n",s_ui_param.s_ui_param_union.s_ui_reserve_param.reserve_12);
}
else
{
printf("param type not supported: %d\r\n", e_type);
}
}
#endif
/**
* @brief 按参数区块初始化 UI 参数镜像
* @param e_type 参数区块类型
*
* 当前实现重点:
* - 已完整映射 SYSTEM 区(0x0200 起);
* - 其他区块后续可按同样方式补齐。
*/
void v_ui_param_init_by_type(E_UI_PARAM_TYPE_T e_type)
{
SYS_FIX_CFG_T *t_sys_fix_cfg = &g_t_share_data.t_sys_fix_cfg;
memset(&s_ui_param.s_ui_param_union.u8_data[0],0,sizeof(s_ui_param.s_ui_param_union.u8_data));
if(e_type == E_UI_PARAM_TYPE_INVALID)// 无效参数类型
{
return;
}
else if(e_type == E_UI_PARAM_TYPE_SYSTEM) //系统参数
{
// 地址段:0x0200~0x020C(共 UI_SYSTEM_PARAM_COUNT 个 U16
// 说明:此处填充的是系统固定配置(SYS_FIX_CFG_T),然后按大端打包下发到屏幕
s_ui_param.s_ui_param_union.s_ui_system_param.number_of_guns = t_sys_fix_cfg->u8_gunCnt; // 0x0200 Number of guns
s_ui_param.s_ui_param_union.s_ui_system_param.pile_type = t_sys_fix_cfg->u8_pile_type; // 0x0201 Pile type
s_ui_param.s_ui_param_union.s_ui_system_param.terminal_address_1 = t_sys_fix_cfg->u8_terminal[0]; // 0x0202 Terminal address 1
s_ui_param.s_ui_param_union.s_ui_system_param.terminal_address_2 = t_sys_fix_cfg->u8_terminal[1]; // 0x0203 Terminal address 2
s_ui_param.s_ui_param_union.s_ui_system_param.gun_type_1 = t_sys_fix_cfg->u8_gun_type[0]; // 0x0204 Gun type 1
s_ui_param.s_ui_param_union.s_ui_system_param.gun_type_2 = t_sys_fix_cfg->u8_gun_type[1]; // 0x0205 Gun type 2
s_ui_param.s_ui_param_union.s_ui_system_param.light_panel_type = t_sys_fix_cfg->e_ledType; // 0x0206 Light panel type
s_ui_param.s_ui_param_union.s_ui_system_param.lcd_enable = t_sys_fix_cfg->u_enable.bit_enable.bit_LcdEnable; // 0x0207 LCD Enable
s_ui_param.s_ui_param_union.s_ui_system_param.system_time_zone = t_sys_fix_cfg->e_timeZone; // 0x0208 System Time Zone
s_ui_param.s_ui_param_union.s_ui_system_param.language_type = t_sys_fix_cfg->u_enable.bit_enable.bit_uiEnglishEn; // 0x0209 Language type
s_ui_param.s_ui_param_union.s_ui_system_param.liquid_cooling_enable = t_sys_fix_cfg->u_enable.bit_enable.bit_YeLenEn; // 0x020A Liquid cooling enable
s_ui_param.s_ui_param_union.s_ui_system_param.host_comm_type = 0; // 0x020B Host comm type
s_ui_param.s_ui_param_union.s_ui_system_param.screensaver_enable = t_sys_fix_cfg->u_enable.bit_enable.bit_ScreenSaverEn; // 0x020C Screensaver Enable
s_ui_param.s_ui_param_union.s_ui_system_param.card_type = t_sys_fix_cfg->u_enable.bit_enable.bit_PlugEn; // 0x020D Card type
}
else if(e_type == E_UI_PARAM_TYPE_PILE_PROTECT) //充电桩保护参数
{
// 地址段:0x0220~0x022A(共 UI_PILE_PROTECT_PARAM_COUNT 个 U16
// 单位/精度:
// - 电压/电流在系统侧一般为 0.1 单位(例如 0.1V、0.1A),UI 写入时通过 s_ui_param_addr_map 的 precision 做缩放
s_ui_param.s_ui_param_union.s_ui_pile_protect_param.min_out_vol = t_sys_fix_cfg->u16_min_volt; // 0x0220 Min out vol (0.1V)
s_ui_param.s_ui_param_union.s_ui_pile_protect_param.max_out_vol = t_sys_fix_cfg->u16_max_volt; // 0x0221 Max out vol (0.1V)
s_ui_param.s_ui_param_union.s_ui_pile_protect_param.max_out_cur = t_sys_fix_cfg->u16_max_cur; // 0x0222 Max out cur (0.1A)
s_ui_param.s_ui_param_union.s_ui_pile_protect_param.pile_rated_power = t_sys_fix_cfg->u16_ratePow*10; // 0x0223 Pile rated power (0.1kW)
s_ui_param.s_ui_param_union.s_ui_pile_protect_param.fan_start_temp = 0; // 0x0224 Fan start temp (0.1°C)
s_ui_param.s_ui_param_union.s_ui_pile_protect_param.fan_stop_temp = 0; // 0x0225 Fan stop temp (0.1°C)
s_ui_param.s_ui_param_union.s_ui_pile_protect_param.gun_temp_thresh = t_sys_fix_cfg->u8_threshold_gunTemp*10; // 0x0226 Gun temp thresh (0.1°C)
s_ui_param.s_ui_param_union.s_ui_pile_protect_param.pile_temp_thresh = 0; // 0x0227 Pile temp thresh (0.1°C)
s_ui_param.s_ui_param_union.s_ui_pile_protect_param.gun1_power_limit = t_sys_fix_cfg->u8_gun_power_limit[0]*10; // 0x0228 Gun 1 power limit (0.1kW)
s_ui_param.s_ui_param_union.s_ui_pile_protect_param.gun2_power_limit = t_sys_fix_cfg->u8_gun_power_limit[1]*10; // 0x0229 Gun 2 power limit (0.1kW)
s_ui_param.s_ui_param_union.s_ui_pile_protect_param.soc_thresh = t_sys_fix_cfg->u8_soc_limit*10; // 0x022A SOC thresh (0.1%)
}
else if(e_type == E_UI_PARAM_TYPE_NETWORK) //网络参数
{
// 地址段:0x0240~0x0254(共 UI_NETWORK_PARAM_COUNT 个 U16
// 说明:IP/MAC 均以“每字节一个 U16”形式承载;平台/网络/APN 走位域配置
s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_1 = t_sys_fix_cfg->s_net_cfg.u8_eth_ip[0]; //0x0240 Local IP byte1
s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_2 = t_sys_fix_cfg->s_net_cfg.u8_eth_ip[1]; //0x0241 Local IP byte2
s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_3 = t_sys_fix_cfg->s_net_cfg.u8_eth_ip[2]; //0x0242 Local IP byte3
s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_4 = t_sys_fix_cfg->s_net_cfg.u8_eth_ip[3]; //0x0243 Local IP byte4
s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_1 = t_sys_fix_cfg->s_net_cfg.u8_eth_gate[0]; //0x0244 Gateway IP byte1
s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_2 = t_sys_fix_cfg->s_net_cfg.u8_eth_gate[1]; //0x0245 Gateway IP byte2
s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_3 = t_sys_fix_cfg->s_net_cfg.u8_eth_gate[2]; //0x0246 Gateway IP byte3
s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_4 = t_sys_fix_cfg->s_net_cfg.u8_eth_gate[3]; //0x0247 Gateway IP byte4
s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_1 = t_sys_fix_cfg->s_net_cfg.u8_eth_mac[0]; //0x0248 MAC byte1
s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_2 = t_sys_fix_cfg->s_net_cfg.u8_eth_mac[1]; //0x0249 MAC byte2
s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_3 = t_sys_fix_cfg->s_net_cfg.u8_eth_mac[2]; //0x024A MAC byte3
s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_4 = t_sys_fix_cfg->s_net_cfg.u8_eth_mac[3]; //0x024B MAC byte4
s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_5 = t_sys_fix_cfg->s_net_cfg.u8_eth_mac[4]; //0x024C MAC byte5
s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_6 = t_sys_fix_cfg->s_net_cfg.u8_eth_mac[5]; //0x024D MAC byte6
s_ui_param.s_ui_param_union.s_ui_net_param.apn_type = t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_sim_anp_type; //0x024E APN type
s_ui_param.s_ui_param_union.s_ui_net_param.plat1_enable = t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_platA_en; //0x024F Platform1 enable
s_ui_param.s_ui_param_union.s_ui_net_param.plat1_net_type = t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_netA_type; //0x0250 Platform1 network type
s_ui_param.s_ui_param_union.s_ui_net_param.plat1_plat_type = t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_platA_type; //0x0251 Platform1 platform type
s_ui_param.s_ui_param_union.s_ui_net_param.plat2_enable = t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_platB_en; //0x0252 Platform2 enable
s_ui_param.s_ui_param_union.s_ui_net_param.plat2_net_type = t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_netB_type; //0x0253 Platform2 network type
s_ui_param.s_ui_param_union.s_ui_net_param.plat2_plat_type = t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_platB_type; //0x0254 Platform2 platform type
}
else if(e_type == E_UI_PARAM_TYPE_MODULE) //模块参数
{
/*
* 对应 sharedatastruct.h 中整流模块参数:
* u8_mdu_num - 模块数量
* u8_MduType - 模块类型
* u8_mduTemp_flag - 模块温度获取使能(此处 UI 未单独映射)
* u8_mdu_rated_pow - 模块额定功率 kw
* u16_mdu_max_vol - 模块最大电压 0.1V
* u16_mdu_max_cur - 模块最大电流 0.1A
*/
s_ui_param.s_ui_param_union.s_ui_module_param.module_rated_power = t_sys_fix_cfg->u8_mdu_rated_pow*10; // 0x0260
s_ui_param.s_ui_param_union.s_ui_module_param.module_rated_volt = t_sys_fix_cfg->u16_mdu_max_vol; // 0x0261 (0.1V)
s_ui_param.s_ui_param_union.s_ui_module_param.module_rated_cur = t_sys_fix_cfg->u16_mdu_max_cur; // 0x0262 (0.1A)
s_ui_param.s_ui_param_union.s_ui_module_param.module_count = t_sys_fix_cfg->u8_mdu_num; // 0x0263
s_ui_param.s_ui_param_union.s_ui_module_param.module_type = t_sys_fix_cfg->u8_MduType; // 0x0264
}
else if(e_type == E_UI_PARAM_TYPE_RESERVE) //预留参数
{
// 地址段:0x0280~0x028B(共 UI_RESERVE_PARAM_COUNT 个 U16
// 说明:预留参数默认全部为 0,仅用于 UI 预留寄存器占位
// 预留参数全部初始化为 0 并下发
memset(&s_ui_param.s_ui_param_union.s_ui_reserve_param, 0, sizeof(UI_RESERVE_PARAM_T));
}
else if(e_type == E_UI_PARAM_TYPE_OTHER)
{
}
#if UI_PARAM_INFO_PRINT_ENABLE == 1
v_ui_param_info_print(0,e_type); //参数信息内容打印
#endif
}
/* 参数保存入口:当前统一触发固定参数存储。 */
void v_ui_param_save_by_type(E_UI_PARAM_TYPE_T e_type)
{
U8_T u8_save_flag = 0;
SYS_FIX_CFG_T *t_sys_fix_cfg = &g_t_share_data.t_sys_fix_cfg;
#if UI_PARAM_INFO_PRINT_ENABLE == 1
v_ui_param_info_print(1,e_type); //参数信息内容打印
#endif
if(e_type == E_UI_PARAM_TYPE_INVALID)// 无效参数类型
{
return;
}
else if(e_type == E_UI_PARAM_TYPE_SYSTEM) //系统参数
{
// 将 UI 写入后的系统参数回写到 SYS_FIX_CFG_T(持久化由上层决定)
t_sys_fix_cfg->u8_gunCnt = s_ui_param.s_ui_param_union.s_ui_system_param.number_of_guns; // 0x0200 Number of guns
t_sys_fix_cfg->u8_pile_type = (PILE_TYPE)s_ui_param.s_ui_param_union.s_ui_system_param.pile_type;; // 0x0201 Pile type
t_sys_fix_cfg->u8_terminal[0] = s_ui_param.s_ui_param_union.s_ui_system_param.terminal_address_1; // 0x0202 Terminal address 1
t_sys_fix_cfg->u8_terminal[1] = s_ui_param.s_ui_param_union.s_ui_system_param.terminal_address_2; // 0x0203 Terminal address 2
t_sys_fix_cfg->u8_gun_type[0] = (U8_T)s_ui_param.s_ui_param_union.s_ui_system_param.gun_type_1; // 0x0204 Gun type 1
t_sys_fix_cfg->u8_gun_type[1] = (U8_T)s_ui_param.s_ui_param_union.s_ui_system_param.gun_type_2; // 0x0205 Gun type 2
t_sys_fix_cfg->e_ledType = (E_LED_TYPE)s_ui_param.s_ui_param_union.s_ui_system_param.light_panel_type; // 0x0206 Light panel type
t_sys_fix_cfg->u_enable.bit_enable.bit_LcdEnable = (U8_T)s_ui_param.s_ui_param_union.s_ui_system_param.lcd_enable; // 0x0207 LCD Enable
t_sys_fix_cfg->e_timeZone = (TIMEZONE_ENUM)s_ui_param.s_ui_param_union.s_ui_system_param.system_time_zone; // 0x0208 System Time Zone
t_sys_fix_cfg->u_enable.bit_enable.bit_uiEnglishEn = (U8_T)s_ui_param.s_ui_param_union.s_ui_system_param.language_type; // 0x0209 Language type
t_sys_fix_cfg->u_enable.bit_enable.bit_YeLenEn = (U8_T)s_ui_param.s_ui_param_union.s_ui_system_param.liquid_cooling_enable; // 0x020A Liquid cooling enable
//s_ui_param.s_ui_param_union.s_ui_system_param.host_comm_type
t_sys_fix_cfg->u_enable.bit_enable.bit_ScreenSaverEn = (U8_T)s_ui_param.s_ui_param_union.s_ui_system_param.screensaver_enable; // 0x020C Screensaver Enable
t_sys_fix_cfg->u_enable.bit_enable.bit_PlugEn = (U8_T)s_ui_param.s_ui_param_union.s_ui_system_param.card_type; // 0x020D Card type
u8_save_flag = 1; //系统参数修改后需要保存
}
else if(e_type == E_UI_PARAM_TYPE_PILE_PROTECT) //充电桩保护参数
{
// 将 UI 写入后的保护参数回写到 SYS_FIX_CFG_T
t_sys_fix_cfg->u16_min_volt = s_ui_param.s_ui_param_union.s_ui_pile_protect_param.min_out_vol; // 0x0220 Min out vol (0,1V)
t_sys_fix_cfg->u16_max_volt = s_ui_param.s_ui_param_union.s_ui_pile_protect_param.max_out_vol; // 0x0221 Max out vol (0,1V)
t_sys_fix_cfg->u16_max_cur = s_ui_param.s_ui_param_union.s_ui_pile_protect_param.max_out_cur; // 0x0222 Max out cur (0,1A)
t_sys_fix_cfg->u16_ratePow = s_ui_param.s_ui_param_union.s_ui_pile_protect_param.pile_rated_power/10; // 0x0223 Pile rated power (0,1kW)
t_sys_fix_cfg->u8_threshold_gunTemp = s_ui_param.s_ui_param_union.s_ui_pile_protect_param.gun_temp_thresh/10; // 0x0226 Gun temp thresh (0,1°C)
t_sys_fix_cfg->u8_gun_power_limit[0] = s_ui_param.s_ui_param_union.s_ui_pile_protect_param.gun1_power_limit/10; // 0x0228 Gun 1 power limit (0,1kW)
t_sys_fix_cfg->u8_gun_power_limit[1] = s_ui_param.s_ui_param_union.s_ui_pile_protect_param.gun2_power_limit/10; // 0x0229 Gun 2 power limit (0,1kW)
t_sys_fix_cfg->u8_soc_limit = s_ui_param.s_ui_param_union.s_ui_pile_protect_param.soc_thresh/10; // 0x022A SOC thresh (0,1%)
//s_ui_param.s_ui_param_union.s_ui_pile_protect_param.fan_start_temp
//s_ui_param.s_ui_param_union.s_ui_pile_protect_param.fan_stop_temp
//s_ui_param.s_ui_param_union.s_ui_pile_protect_param.pile_temp_thresh
u8_save_flag = 1; //系统参数修改后需要保存
}
else if(e_type == E_UI_PARAM_TYPE_NETWORK) //网络参数
{
// 将 UI 写入后的网络参数回写到 SYS_FIX_CFG_T(网络字段统一在 s_net_cfg 内)
t_sys_fix_cfg->s_net_cfg.u8_eth_ip[0] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_1;
t_sys_fix_cfg->s_net_cfg.u8_eth_ip[1] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_2;
t_sys_fix_cfg->s_net_cfg.u8_eth_ip[2] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_3;
t_sys_fix_cfg->s_net_cfg.u8_eth_ip[3] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.local_ip_4;
t_sys_fix_cfg->s_net_cfg.u8_eth_gate[0] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_1;
t_sys_fix_cfg->s_net_cfg.u8_eth_gate[1] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_2;
t_sys_fix_cfg->s_net_cfg.u8_eth_gate[2] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_3;
t_sys_fix_cfg->s_net_cfg.u8_eth_gate[3] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.gateway_ip_4;
t_sys_fix_cfg->s_net_cfg.u8_eth_mac[0] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_1;
t_sys_fix_cfg->s_net_cfg.u8_eth_mac[1] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_2;
t_sys_fix_cfg->s_net_cfg.u8_eth_mac[2] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_3;
t_sys_fix_cfg->s_net_cfg.u8_eth_mac[3] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_4;
t_sys_fix_cfg->s_net_cfg.u8_eth_mac[4] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_5;
t_sys_fix_cfg->s_net_cfg.u8_eth_mac[5] = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.mac_addr_6;
t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_sim_anp_type = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.apn_type;
t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_platA_en = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.plat1_enable;
t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_netA_type = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.plat1_net_type;
t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_platA_type = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.plat1_plat_type;
t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_platB_en = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.plat2_enable;
t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_netB_type = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.plat2_net_type;
t_sys_fix_cfg->s_net_cfg.u_net_comm_para.bits.bit_platB_type = (U8_T)s_ui_param.s_ui_param_union.s_ui_net_param.plat2_plat_type;
u8_save_flag = 1; //系统参数修改后需要保存
}
else if(e_type == E_UI_PARAM_TYPE_MODULE) //模块参数
{
/*
* 将 UI 写回的模块参数同步到系统配置:
* - module_rated_power ↔ u8_mdu_rated_pow 0,1 kW
* - module_rated_volt ↔ u16_mdu_max_vol (0.1V)
* - module_rated_cur ↔ u16_mdu_max_cur (0.1A)
* - module_count ↔ u8_mdu_num
* - module_type ↔ u8_MduType
*/
t_sys_fix_cfg->u8_mdu_rated_pow = (U8_T)(s_ui_param.s_ui_param_union.s_ui_module_param.module_rated_power/10);
t_sys_fix_cfg->u16_mdu_max_vol = s_ui_param.s_ui_param_union.s_ui_module_param.module_rated_volt;
t_sys_fix_cfg->u16_mdu_max_cur = s_ui_param.s_ui_param_union.s_ui_module_param.module_rated_cur;
t_sys_fix_cfg->u8_mdu_num = (U8_T)s_ui_param.s_ui_param_union.s_ui_module_param.module_count;
t_sys_fix_cfg->u8_MduType = (U8_T)s_ui_param.s_ui_param_union.s_ui_module_param.module_type;
u8_save_flag = 1; //系统参数修改后需要保存
}
else if(e_type == E_UI_PARAM_TYPE_RESERVE) //预留参数
{
// 预留参数不回写系统配置(仅 UI 占位寄存器)
u8_save_flag = 1; //系统参数修改后需要保存
}
else if(e_type == E_UI_PARAM_TYPE_OTHER)
{
u8_save_flag = 1; //系统参数修改后需要保存
}
if(u8_save_flag == 1)
{
// printf("flash save\r\n");
v_flash_save_cfg_data(); //保存系统固定配置到持久化
}
}
/**
* @brief UI字符串参数回写到共享配置
* @param u16_addr UI字符串寄存器地址
* @param u8_str 输入字符串
* @param u8_str_len 输入长度
*
* 实现要点:
* - 按地址映射到目标字段(桩号/域名/二维码/APN)。
* - 写入前清零、写入后强制 '\0',保证目标字段始终是安全字符串。
*/
void v_ui_para_str_update(U16_T u16_addr, U8_T *u8_str, U8_T u8_str_len)
{
U8_T *dest = NULL;
size_t dest_size = 0u;
size_t copy_len;
if ((u8_str == NULL) || (u8_str_len == 0u)) {
return;
}
// printf("Updating string parameter at address 0x%04X: %.*s\r\n", u16_addr, u8_str_len, u8_str);
if (u16_addr == UI_PLATFORM1_PILE_NO) { // 0x0540 平台1桩编号参数 32字节 0x0540~0x055F
dest = g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platA_pileNum;
dest_size = sizeof(g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platA_pileNum);
} else if (u16_addr == UI_PLATFORM2_PILE_NO) { // 0x0560 平台2桩编号参数 32字节 0x0560~0x057F
dest = g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platB_pileNum;
dest_size = sizeof(g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platB_pileNum);
} else if (u16_addr == UI_PLATFORM1_DOMAIN) { // 0x0580 平台1域名地址 64字节 0x0580~0x05BF
dest = g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_serverA_domain_name;
dest_size = sizeof(g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_serverA_domain_name);
} else if (u16_addr == UI_PLATFORM2_DOMAIN) { // 0x05C0 平台2域名地址 64字节 0x05C0~0x05FF
dest = g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_serverB_domain_name;
dest_size = sizeof(g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_serverB_domain_name);
} else if (u16_addr == UI_QR_CODE_GUN_A) { // 0x0A00 二维码(枪A
dest = (U8_T *)g_t_share_data.t_sys_var_cfg.QRDisplay[0];// 强制转换,消除警告
dest_size = sizeof(g_t_share_data.t_sys_var_cfg.QRDisplay[0]);
} else if (u16_addr == UI_QR_CODE_GUN_B) { // 0x0B00 二维码(枪B
dest = (U8_T *)g_t_share_data.t_sys_var_cfg.QRDisplay[1]; // 强制转换,消除警告
dest_size = sizeof(g_t_share_data.t_sys_var_cfg.QRDisplay[1]);
} else if(u16_addr == UI_STR_APN){ //0x0C00 apn1
dest = (U8_T *)g_t_share_data.t_sys_var_cfg.apn_str; // 强制转换,消除警告
dest_size = sizeof(g_t_share_data.t_sys_var_cfg.apn_str);
} else if(u16_addr == UI_STR_OCPP_AUTH_KEY){ //0x06A0 OCPP鉴权密钥
dest = (U8_T *)g_t_share_data.t_sys_var_cfg.ocpp_auth_key;
dest_size = sizeof(g_t_share_data.t_sys_var_cfg.ocpp_auth_key);
} else if(u16_addr == UI_STR_R2){ //0x0C80 预留3
return;
}
else {
return; // 地址不匹配,直接返回
}
// 统一处理:清零、复制、强制加结束符
if (dest == NULL || dest_size == 0) {
return;
}
memset(dest, 0, dest_size);
copy_len = (u8_str_len < (dest_size - 1u)) ? (size_t)u8_str_len : (dest_size - 1u);
memcpy(dest, u8_str, copy_len);
dest[copy_len] = '\0'; // 确保字符串以'\0'结尾
}
/* 参数初始化入口:调用公共参数初始化流程。 */
void v_ui_param_init(void)
{
v_public_param_init();
}
/* UI触发系统重启入口。 */
void v_ui_system_reboot(void)
{
v_sys_reboot();
}
#endif