Release:5.20灰测
This commit is contained in:
279
Core/User/Protocol/Host Computer/host_computer_protocol.c
Normal file
279
Core/User/Protocol/Host Computer/host_computer_protocol.c
Normal 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);
|
||||
}
|
||||
|
||||
16
Core/User/Protocol/Host Computer/host_computer_protocol.h
Normal file
16
Core/User/Protocol/Host Computer/host_computer_protocol.h
Normal 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 */
|
||||
Reference in New Issue
Block a user