Release:5.20灰测

This commit is contained in:
2026-05-21 10:01:28 +08:00
parent 8a5a32b139
commit fd65e9c6a2
68 changed files with 4329 additions and 1489 deletions

View File

@@ -0,0 +1,279 @@
/**
* @file host_computer_protocol.c
* @brief 上位机通信协议处理模块
* @details 处理上位机与充电桩之间的通信协议,包括登录验证、状态查询、
* 数据上报等功能。支持JSON格式的数据交互通过UDP协议与服务器通信。
* @date 2025-01-09 14:32:15
* @version 1.0.0
* @copyright Copyright (c) 2026
*/
#include "host_computer_protocol.h"
#include "point_protocol.h"
void host_computer_on_login(uint8_t id, cJSON *json_pack)
{
(void) id;
cJSON *request_id = cJSON_GetObjectItem(json_pack, "request_id");
cJSON *username = cJSON_GetObjectItem(json_pack, "username");
cJSON *password = cJSON_GetObjectItem(json_pack, "password");
cJSON *root = NULL;
char *str = NULL;
root = cJSON_CreateObject();
if (root == NULL)
{
printf("Failed to create JSON object for server login\r\n");
return;
}
/* 添加一条字符串类型的JSON数据(添加一个链表节点) */
cJSON_AddStringToObject(root, "request_id", request_id->valuestring);
if (strcmp(username->valuestring, "admin") != 0 || strcmp(password->valuestring, "123456") != 0)
{
cJSON_AddStringToObject(root, "error", "用户或密码错误 ");
cJSON_AddBoolToObject(root, "success", cJSON_False);
printf("登录失败\r\n");
}
else
{
cJSON_AddBoolToObject(root, "success", cJSON_True);
printf("登录成功\r\n");
}
str = cJSON_Print(root);
udp_send_to_server(str, strlen(str));
free(str);
cJSON_Delete(root);
}
// 处理获取状态查询指令
void host_computer_on_get_status(uint8_t id, cJSON *json_pack)
{
(void) id;
cJSON *request_id = cJSON_GetObjectItem(json_pack, "request_id");
cJSON *root = NULL;
cJSON *piles = NULL;
cJSON *pile = NULL;
cJSON *guns = NULL;
cJSON *gun = NULL;
char *str = NULL;
root = cJSON_CreateObject();
if (root == NULL)
{
printf("Failed to create JSON object for get_status\r");
return;
}
cJSON_AddStringToObject(root, "request_id", request_id->valuestring);
cJSON_AddBoolToObject(root, "success", cJSON_True);
/* ── piles 数组 ── */
piles = cJSON_CreateArray();
/* 根据MAX_CHARGER_COUNT动态生成桩数据 */
for (int i = 0; i < MAX_CHARGER_COUNT; i++)
{
ChargerPile *pile_data = &g_charger_manager.charger_piles[i];
pile = cJSON_CreateObject();
if (pile == NULL)
{
continue;
}
/* 添加桩序列号 */
char serial_str[15] = {0};
for (int j = 0; j < 7; j++)
{
sprintf(&serial_str[j * 2], "%02X", pile_data->login_info.charger_serial[j]);
}
cJSON_AddStringToObject(pile, "serial", serial_str);
/* 添加在线状态 */
cJSON_AddBoolToObject(pile, "is_online", pile_data->is_udp_online ? cJSON_True : cJSON_False);
/* 创建guns数组 */
guns = cJSON_CreateArray();
if (guns != NULL)
{
for (int g = 0; g < MAX_GUN_PER_CHARGER; g++)
{
gun = cJSON_CreateObject();
if (gun != NULL)
{
/* 添加枪状态 */
cJSON_AddNumberToObject(gun, "status", pile_data->guns[g].real_time_data.status);
cJSON_AddItemToArray(guns, gun);
}
}
cJSON_AddItemToObject(pile, "guns", guns);
}
cJSON_AddItemToArray(piles, pile);
}
cJSON_AddItemToObject(root, "piles", piles);
/* ── 发送 ── */
str = cJSON_Print(root);
udp_send_to_server(str, strlen(str));
free(str);
cJSON_Delete(root);
printf("get_status 回复已发送 \r\n");
}
void host_computer_on_reboot(uint8_t id, cJSON *json)
{
(void) id;
printf("host_computer_on_reboot\r\n");
__ASM volatile("cpsid i");
HAL_NVIC_SystemReset();
}
/**
* @brief 主动上报充电桩数据
* @note 模拟并上报充电桩实时数据,符合协议格式要求
* @param stake_index 桩索引 (1~6)
* @param gun_id 枪编码 (1~N)
*/
void host_computer_report_data(uint8_t stake_index, uint8_t gun_id)
{
if (stake_index > MAX_CHARGER_COUNT || stake_index == 0)
{
printf("Invalid stake index: %d\r\n", stake_index);
return;
}
if (gun_id == 0 || gun_id > MAX_GUN_PER_CHARGER)
{
printf("Invalid gun id: %d\r\n", gun_id);
return;
}
cJSON *root = NULL;
cJSON *piles_array = NULL;
cJSON *pile_obj = NULL;
cJSON *guns_array = NULL;
cJSON *gun_obj = NULL;
char *str = NULL;
root = cJSON_CreateObject();
if (root == NULL)
{
printf("Failed to create JSON object for report_data\r\n");
return;
}
/* 添加命令字段 */
cJSON_AddStringToObject(root, "cmd", "report_data");
/* 创建piles数组 */
piles_array = cJSON_CreateArray();
if (piles_array == NULL)
{
printf("Failed to create piles array\r\n");
cJSON_Delete(root);
return;
}
/* 创建桩数据对象 */
pile_obj = cJSON_CreateObject();
if (pile_obj == NULL)
{
printf("Failed to create pile object\r\n");
cJSON_Delete(root);
return;
}
/* 从结构体获取真实数据 */
ChargerGun *gun = &g_charger_manager.charger_piles[stake_index - 1].guns[gun_id - 1];
FEE_MODEL *model = &g_charger_manager.fee_model_global;
/* 存入结构体前放大过10倍发送时缩小回去 */
float current = gun->real_time_data.out_current / 10.0f;
float voltage = gun->real_time_data.out_voltage / 10.0f;
float power = (voltage * current) / 1000.0f;
/* 电量(0.01kWh/单位) 金额(0.01元/单位) */
float energy = gun->real_time_data.charge_energy / 10000.0f;
float total_amount = gun->real_time_data.charge_money / 10000.0f;
/* 根据计费模型拆分电费/服务费 */
uint32_t fee_ratio_sum = model->flat_fee_ratio + model->flat_service_ratio;
float electricity_fee = (fee_ratio_sum > 0) ? total_amount * model->flat_fee_ratio / fee_ratio_sum : 0;
float service_fee = total_amount - electricity_fee;
int status = gun->real_time_data.status;
int cumulative_time = gun->real_time_data.charge_time;
int remaining_time = gun->real_time_data.remain_time;
uint8_t soc = gun->real_time_data.soc;
/* 交易流水号 → 十六进制字符串 */
char order_no[33] = {0};
trade_serial_to_string(gun->real_time_data.trade_serial, order_no);
/* 模拟桩数据 */
cJSON_AddNumberToObject(pile_obj, "index", stake_index);
/* 创建guns数组 */
guns_array = cJSON_CreateArray();
if (guns_array == NULL)
{
printf("Failed to create guns array\r\n");
cJSON_Delete(pile_obj);
cJSON_Delete(root);
return;
}
/* 创建枪数据对象 */
gun_obj = cJSON_CreateObject();
if (gun_obj == NULL)
{
printf("Failed to create gun object\r\n");
cJSON_Delete(guns_array);
cJSON_Delete(pile_obj);
cJSON_Delete(root);
return;
}
/* 枪数据 */
cJSON_AddNumberToObject(gun_obj, "gun", gun_id);
cJSON_AddNumberToObject(gun_obj, "current", current); // 电流(随机变化)
cJSON_AddNumberToObject(gun_obj, "voltage", voltage); // 电压(随机变化)
cJSON_AddNumberToObject(gun_obj, "power", power); // 功率(随机变化)
cJSON_AddNumberToObject(gun_obj, "energy", energy); // 电量(随机变化)
cJSON_AddNumberToObject(gun_obj, "service_fee", service_fee); // 服务费(随机变化)
cJSON_AddNumberToObject(gun_obj, "electricity_fee", electricity_fee); // 电费(随机变化)
cJSON_AddNumberToObject(gun_obj, "total_amount", total_amount); // 总金额(随机变化)
cJSON_AddNumberToObject(gun_obj, "status", status); // 状态
cJSON_AddStringToObject(gun_obj, "order_no", order_no);
cJSON_AddNumberToObject(gun_obj, "soc", soc); // SOC随机变化
cJSON_AddNumberToObject(gun_obj, "cumulative_time", cumulative_time); // 累计充电时间(随机变化)
cJSON_AddNumberToObject(gun_obj, "remaining_time", remaining_time); // 剩余时间(随机变化)
cJSON_AddItemToArray(guns_array, gun_obj);
cJSON_AddItemToObject(pile_obj, "guns", guns_array);
cJSON_AddItemToArray(piles_array, pile_obj);
cJSON_AddItemToObject(root, "piles", piles_array);
/* 转换为JSON字符串并发送 */
str = cJSON_Print(root);
if (str != NULL)
{
udp_send_to_server(str, strlen(str));
free(str);
printf("南向:主动上报桩 %d 枪 %d 主动上报数据成功 \r\n", stake_index, gun_id);
}
else
{
printf("Failed to print JSON for report_data\r\n");
}
cJSON_Delete(root);
}

View File

@@ -0,0 +1,16 @@
#ifndef HOST_COMPUTER_HANDLER_H
#define HOST_COMPUTER_HANDLER_H
#include "global.h"
#include "cJSON.h"
#include <stdint.h>
#include "udp_manager.h"
/* ── 路由表注册接口(供 UdpRouter 调用)─────────────── */
void host_computer_on_login (uint8_t id, cJSON *json);
void host_computer_on_get_status(uint8_t id, cJSON *json);
void host_computer_on_reboot (uint8_t id, cJSON *json);
/* ── 主动上报接口(供业务层调用)────────────────────── */
void host_computer_report_data(uint8_t stake_index, uint8_t gun_id);
#endif /* HOST_COMPUTER_HANDLER_H */