diff --git a/4G/量产文件/4G远程升级文件/4G_NETWORK_1.0.0_LuatOS-Air_V4035_RDA8910_BT_FLOAT.dfota.bin b/4G/量产文件/4G远程升级文件/4G_NETWORK_1.0.0_LuatOS-Air_V4035_RDA8910_BT_FLOAT.dfota.bin new file mode 100644 index 0000000..02f07b0 Binary files /dev/null and b/4G/量产文件/4G远程升级文件/4G_NETWORK_1.0.0_LuatOS-Air_V4035_RDA8910_BT_FLOAT.dfota.bin differ diff --git a/4G/量产文件/4G量产文件/4G_NETWORK_1.0.0_LuatOS-Air_V4035_RDA8910_BT_FLOAT.pac b/4G/量产文件/4G量产文件/4G_NETWORK_1.0.0_LuatOS-Air_V4035_RDA8910_BT_FLOAT.pac new file mode 100644 index 0000000..2d042ac Binary files /dev/null and b/4G/量产文件/4G量产文件/4G_NETWORK_1.0.0_LuatOS-Air_V4035_RDA8910_BT_FLOAT.pac differ diff --git a/Core.zip b/Core.zip deleted file mode 100644 index b777069..0000000 Binary files a/Core.zip and /dev/null differ diff --git a/Core/MDK-ARM/.eide/eide.yml b/Core/MDK-ARM/.eide/eide.yml index e7ce5f0..217836c 100644 --- a/Core/MDK-ARM/.eide/eide.yml +++ b/Core/MDK-ARM/.eide/eide.yml @@ -6,9 +6,7 @@ packDir: .pack/Keil/STM32H7xx_DFP.4.1.0 srcDirs: [] virtualFolder: name: - files: - - path: ../README.md - - path: ../../Doc/云快充平台协议V1.6.pdf + files: [] folders: - name: Application files: [] @@ -116,14 +114,14 @@ virtualFolder: - path: ../User/Protocol/Ykc/server_to_charger.h - path: ../User/Protocol/Ykc/ykc_router.c folders: [] - - name: Point - files: - - path: ../User/Protocol/Point/point_protocol.c - folders: [] - name: Host Computer files: - path: ../User/Protocol/Host Computer/host_computer_protocol.c folders: [] + - name: Point + files: + - path: ../User/Protocol/Point/point_protocol.c + folders: [] - name: Drivers files: [] folders: diff --git a/Core/README.md b/Core/README.md deleted file mode 100644 index 9299ad1..0000000 --- a/Core/README.md +++ /dev/null @@ -1,2 +0,0 @@ -### 生产代码设置 -- /User/Global/g_decpile -> void init_chargers(void) 需要修改预设 ,从电桩全局结构体拿 \ No newline at end of file diff --git a/Core/User/Driver/drv_air724.c b/Core/User/Driver/drv_air724.c index dbe7c94..e5b2965 100644 --- a/Core/User/Driver/drv_air724.c +++ b/Core/User/Driver/drv_air724.c @@ -92,11 +92,11 @@ void drv_air724_set_server(const char *ip, uint16_t port) void drv_air724_connect_channel(uint8_t channel) { if (channel < 1 || channel > AIR724_SOCKET_MAX) { - printf("4G: 通道 %d 无效 \r\n", channel); + printf("[ 4G ] 通道 %d 无效 \r\n", channel); return; } drv_air724_send_cmd(0x03, 0x01, &channel, 1); - printf("4G: 通道 %d 连接请求已发送 \r\n", channel); + printf("[ 4G ] 通道 %d 连接请求已发送 \r\n", channel); } /** @@ -108,11 +108,11 @@ void drv_air724_connect_channel(uint8_t channel) void drv_air724_disconnect_channel(uint8_t channel) { if (channel < 1 || channel > AIR724_SOCKET_MAX) { - printf("4G: 通道 %d 无效\r\n", channel); + printf("[ 4G ] 通道 %d 无效\r\n", channel); return; } drv_air724_send_cmd(0x03, 0x02, &channel, 1); - printf("4G: 通道 %d 断开请求已发送\r\n", channel); + printf("[ 4G ] 通道 %d 断开请求已发送\r\n", channel); } /** @@ -186,15 +186,15 @@ void drv_air724_parse_response(const uint8_t *frame, uint16_t len) switch (sub_cmd) { case 0x01: g_air724_info.socket_connected[socket_id - 1] = 1; - printf("4G: 通道 %d 连接成功\r\n", socket_id); + printf("[ 4G ] 通道 %d 连接成功\r\n", socket_id); break; case 0x02: g_air724_info.socket_connected[socket_id - 1] = 0; - printf("4G: 通道 %d 已断开\r\n", socket_id); + printf("[ 4G ] 通道 %d 已断开\r\n", socket_id); break; case 0x03: g_air724_info.socket_connected[socket_id - 1] = 0; - printf("4G: 通道 %d 连接失败\r\n", socket_id); + printf("[ 4G ] 通道 %d 连接失败\r\n", socket_id); break; } } @@ -210,17 +210,17 @@ void drv_air724_parse_response(const uint8_t *frame, uint16_t len) case 0x01: memcpy(g_air724_info.iccid, &frame[5], data_len < 23 ? data_len : 23); g_air724_info.iccid[data_len < 23 ? data_len : 23] = '\0'; - printf("4G: ICCID=%s\r\n", g_air724_info.iccid); + printf("[ 4G ] ICCID=%s\r\n", g_air724_info.iccid); break; case 0x02: memcpy(g_air724_info.imsi, &frame[5], data_len < 15 ? data_len : 15); g_air724_info.imsi[data_len < 15 ? data_len : 15] = '\0'; - printf("4G: IMSI=%s\r\n", g_air724_info.imsi); + printf("[ 4G ] IMSI=%s\r\n", g_air724_info.imsi); break; case 0x03: memcpy(g_air724_info.imei, &frame[5], data_len < 15 ? data_len : 15); g_air724_info.imei[data_len < 15 ? data_len : 15] = '\0'; - printf("4G: IMEI=%s\r\n", g_air724_info.imei); + printf("[ 4G ] IMEI=%s\r\n", g_air724_info.imei); break; } break; @@ -231,7 +231,7 @@ void drv_air724_parse_response(const uint8_t *frame, uint16_t len) if (len >= 7) { g_air724_info.csq = frame[4]; g_air724_info.ber = frame[5]; - printf("4G: CSQ=%d, BER=%d\r\n", g_air724_info.csq, g_air724_info.ber); + printf("[ 4G ] CSQ=%d, BER=%d\r\n", g_air724_info.csq, g_air724_info.ber); } break; @@ -241,7 +241,7 @@ void drv_air724_parse_response(const uint8_t *frame, uint16_t len) for (uint8_t i = 0; i < count; i++) { g_air724_info.socket_connected[i] = frame[4 + i]; } - printf("4G: 链路["); + printf("[ 4G ] 链路["); for (uint8_t i = 0; i < AIR724_SOCKET_MAX; i++) { printf("%d", g_air724_info.socket_connected[i]); } @@ -252,7 +252,7 @@ void drv_air724_parse_response(const uint8_t *frame, uint16_t len) /* ── 0x87: 服务器配置结果 ── */ case 0x87: if (len >= 6) { - printf("4G: 服务器配置%s\r\n", frame[4] == 0 ? "成功" : "失败"); + printf("[ 4G ] 服务器配置%s\r\n", frame[4] == 0 ? "成功" : "失败"); } break; } diff --git a/Core/User/Protocol/Host Computer/host_computer_protocol.c b/Core/User/Protocol/Host Computer/host_computer_protocol.c index d9d9230..bf32001 100644 --- a/Core/User/Protocol/Host Computer/host_computer_protocol.c +++ b/Core/User/Protocol/Host Computer/host_computer_protocol.c @@ -134,7 +134,7 @@ void host_computer_on_get_status(uint8_t id, cJSON *json_pack) udp_send_to_server(str, strlen(str)); free(str); cJSON_Delete(root); - printf("get_status 回复已发送 \r\n"); + printf("[ 上位机 ] get_status 回复已发送 \r\n"); } /** @@ -146,7 +146,7 @@ void host_computer_on_get_status(uint8_t id, cJSON *json_pack) void host_computer_on_reboot(uint8_t id, cJSON *json) { (void) id; - printf("host_computer_on_reboot\r\n"); + printf("[ 上位机 ] host_computer_on_reboot\r\n"); __ASM volatile("cpsid i"); HAL_NVIC_SystemReset(); } @@ -285,11 +285,11 @@ void host_computer_report_data(uint8_t stake_index, uint8_t gun_id) { udp_send_to_server(str, strlen(str)); free(str); - printf("南向:主动上报桩 %d 枪 %d 主动上报数据成功 \r\n", stake_index, gun_id); + printf("[ 上位机 ] 南向:主动上报桩 %d 枪 %d 主动上报数据成功 \r\n", stake_index, gun_id); } else { - printf("Failed to print JSON for report_data\r\n"); + printf("[ 上位机 ] Failed to print JSON for report_data\r\n"); } cJSON_Delete(root); diff --git a/Core/User/Protocol/Ykc/charger_to_server.c b/Core/User/Protocol/Ykc/charger_to_server.c index c995943..e82692b 100644 --- a/Core/User/Protocol/Ykc/charger_to_server.c +++ b/Core/User/Protocol/Ykc/charger_to_server.c @@ -30,7 +30,7 @@ void charger_to_server_0X01(uint8_t stake_index) data.net_conn_type = g_charger_manager.charger_piles[stake_index - 1].login_info.net_conn_type; data.tele_factory = g_charger_manager.charger_piles[stake_index - 1].login_info.tele_factory; memcpy(data.sim, g_charger_manager.charger_piles[stake_index - 1].login_info.sim, 10); - printf("北向:对电桩 %d 发送登录认证\r\n", stake_index); + printf("[ 北向 ] 对电桩 %d 发送登录认证\r\n", stake_index); pack_and_send_server_data(FRAME_TYPE_0X01, (uint8_t *)&data, sizeof(PACK_DATA_0X01), stake_index); } @@ -47,7 +47,7 @@ void charger_to_server_0X03(uint8_t stake_index, uint8_t gun_index) load_charger_serial(stake_index, data.charger_serial); // 加载充电桩序列号 data.gun_index = ((gun_index / 10) << 4) | (gun_index % 10); data.gun_status = g_charger_manager.charger_piles[stake_index - 1].guns[gun_index - 1].heartbeat_status_data.gun_status; - printf("北向:对电桩 %d 发送心跳请求,枪号:%d,状态:%d\r\n", stake_index, gun_index, data.gun_status); + printf("[ 北向 ] 对电桩 %d 发送心跳请求,枪号:%d,状态:%d\r\n", stake_index, gun_index, data.gun_status); pack_and_send_server_data(FRAME_TYPE_0X03, (uint8_t *)&data, sizeof(PACK_DATA_0X03), stake_index); } @@ -63,7 +63,7 @@ void charger_to_server_0X05(uint16_t num, uint8_t stake_index) load_charger_serial(stake_index, data.charger_serial); // 加载充电桩序列号 data.fee_model_no = num; - printf("北向:对电桩 %d 计费模型验证请求,模型号:%d\r\n", stake_index, num); + printf("[ 北向 ] 对电桩 %d 计费模型验证请求,模型号:%d\r\n", stake_index, num); pack_and_send_server_data(FRAME_TYPE_0X05, (uint8_t *)&data, sizeof(PACK_DATA_0X05), stake_index); } @@ -76,7 +76,7 @@ void charger_to_server_0X09(uint8_t stake_index) { PACK_DATA_0X09 data = {0}; load_charger_serial(stake_index, data.charger_serial); // 加载充电桩序列号 - printf("北向:对电桩 %d 计费模型请求\r\n", stake_index); + printf("[ 北向 ] 对电桩 %d 计费模型请求\r\n", stake_index); pack_and_send_server_data(FRAME_TYPE_0X09, (uint8_t *)&data, sizeof(PACK_DATA_0X09), stake_index); } @@ -123,7 +123,7 @@ void charger_to_server_0X19(uint8_t stake_index, uint8_t gun_index) load_charger_serial(stake_index, data.charger_serial); load_trade_serial(stake_index, gun_index, data.trade_serial); data.gun_index = ((gun_index / 10) << 4) | (gun_index % 10); - printf("北向:对电桩 %d 枪 %d 的充电结束上报 \r\n", stake_index, gun_index); + printf("[ 北向 ] 对电桩 %d 枪 %d 的充电结束上报 \r\n", stake_index, gun_index); pack_and_send_server_data(FRAME_TYPE_0X19, (uint8_t *)&data, sizeof(PACK_DATA_0X19), stake_index); } @@ -164,7 +164,7 @@ void charger_to_server_0X35(uint8_t stake_index, uint8_t gun_index, uint8_t resu data.result = result; data.err_code = err_code; - printf("北向:对电桩 %d 的平台停机回复,结果:%d,错误码:%d\r\n", stake_index, result, err_code); + printf("[ 北向 ] 对电桩 %d 的平台停机回复,结果:%d,错误码:%d\r\n", stake_index, result, err_code); pack_and_send_server_data(FRAME_TYPE_0X35, (uint8_t *)&data, sizeof(PACK_DATA_0X35), stake_index); } @@ -219,7 +219,7 @@ void charger_to_server_0X3B(uint8_t stake_index, uint8_t gun_index) memcpy(data.phy_cardid, gun->fee_data.phy_cardid, 8); // 物理卡号 printf("========================================\r\n"); - printf("北向:对电桩 %d 枪 %d 上传交易记录(0x3B),电量:%.2f,金额:%.2f\r\n", + printf("[ 北向 ] 对电桩 %d 枪 %d 上传交易记录(0x3B),电量:%.2f,金额:%.2f\r\n", stake_index, gun_index, data.total_energy / 10000.0f, data.consumption / 10000.0f); printf("\r\n========================================\r\n"); pack_and_send_server_data(FRAME_TYPE_0X3B, (uint8_t *)&data, sizeof(PACK_DATA_0X3B), stake_index); @@ -237,6 +237,6 @@ void charger_to_server_0x57(uint8_t stake_index) load_charger_serial(stake_index, data.charger_serial); data.result = 0x01; - printf("北向:对电桩 %d 的计费模型主动更新回复\r\n", stake_index); + printf("[ 北向 ] 对电桩 %d 的计费模型主动更新回复\r\n", stake_index); pack_and_send_server_data(FRAME_TYPE_0X57, (uint8_t *)&data, sizeof(PACK_DATA_0X57), stake_index); } \ No newline at end of file diff --git a/Core/User/Protocol/Ykc/server_to_charger.c b/Core/User/Protocol/Ykc/server_to_charger.c index 57916a5..9a0efab 100644 --- a/Core/User/Protocol/Ykc/server_to_charger.c +++ b/Core/User/Protocol/Ykc/server_to_charger.c @@ -27,7 +27,7 @@ void on_cmd_frame_type_0X02(uint8_t stake_index, SERVER_PACK *pack) { g_charger_manager.charger_piles[stake_index - 1].is_online = 1; #ifdef DEBUG - printf("北向:桩ID %d 登陆成功!\r\n", stake_index); + printf("[ 北向 ] 桩ID %d 登陆成功!\r\n", stake_index); #endif } } @@ -43,7 +43,7 @@ void on_cmd_frame_type_0X04(uint8_t stake_index, SERVER_PACK *pack) PACK_DATA_0X04 data; memcpy(&data, pack->data, sizeof(PACK_DATA_0X04)); #ifdef DEBUG - printf("北向:桩ID %d 收到心跳应答!\r\n", stake_index); + printf("[ 北向 ] 桩ID %d 收到心跳应答!\r\n", stake_index); #endif } @@ -59,7 +59,7 @@ void on_cmd_frame_type_0X06(uint8_t stake_index, SERVER_PACK *pack) if (is_my_charger_serial(stake_index, data.charger_serial)) { #ifdef DEBUG - printf("北向:接收到计费模型验证应答,模型ID:%d, 验证结果:%d\r\n", data.fee_model_no, data.result); + printf("[ 北向 ] 接收到计费模型验证应答,模型ID:%d, 验证结果:%d\r\n", data.fee_model_no, data.result); #endif } } @@ -81,7 +81,7 @@ void on_cmd_frame_type_0X0A(uint8_t stake_index, SERVER_PACK *pack) #ifdef DEBUG - printf("北向:接收到计费模型应答,模型ID:%d\r\n", g_charger_manager.fee_model_global.fee_model_no); + printf("[ 北向 ] 接收到计费模型应答,模型ID:%d\r\n", g_charger_manager.fee_model_global.fee_model_no); printf("尖电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.shark_fee_ratio, g_charger_manager.fee_model_global.shark_service_ratio); printf("峰电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.peak_fee_ratio, g_charger_manager.fee_model_global.peak_service_ratio); printf("平电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.flat_fee_ratio, g_charger_manager.fee_model_global.flat_service_ratio); @@ -167,7 +167,7 @@ void on_cmd_frame_type_0X58(uint8_t stake_index, SERVER_PACK *pack) #ifdef DEBUG - printf("北向:接收到计费模型应答,模型ID:%d\r\n", g_charger_manager.fee_model_global.fee_model_no); + printf("[ 北向 ] 接收到计费模型应答,模型ID:%d\r\n", g_charger_manager.fee_model_global.fee_model_no); printf("尖电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.shark_fee_ratio, g_charger_manager.fee_model_global.shark_service_ratio); printf("峰电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.peak_fee_ratio, g_charger_manager.fee_model_global.peak_service_ratio); printf("平电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.flat_fee_ratio, g_charger_manager.fee_model_global.flat_service_ratio); @@ -275,7 +275,7 @@ void on_cmd_frame_type_0X36(uint8_t stake_index, SERVER_PACK *pack) uint8_t result = TRUE; // 默认停止结果成功 uint8_t err_code = 0; // 默认错误码为0 memcpy(&data, pack->data, sizeof(PACK_DATA_0X36)); - printf("北向:平台控制停止充电,桩ID:%d, 枪ID:%d\r\n", stake_index, data.gun_index); + printf("[ 北向 ] 平台控制停止充电,桩ID:%d, 枪ID:%d\r\n", stake_index, data.gun_index); if (!is_my_charger_serial(stake_index, data.charger_serial)) { @@ -305,7 +305,7 @@ void on_cmd_frame_type_0X40(uint8_t stake_index, SERVER_PACK *pack) memcpy(&data, pack->data, sizeof(PACK_DATA_0X40)); if (data.result == 0) { - printf("北向:平台接收到交易记录,桩ID:%d, 交易记录:%s\r\n", stake_index, data.trade_serial); + printf("[ 北向 ] 平台接收到交易记录,桩ID:%d, 交易记录:%s\r\n", stake_index, data.trade_serial); return; } } diff --git a/Doc/README.md b/Doc/README.md new file mode 100644 index 0000000..944b04b --- /dev/null +++ b/Doc/README.md @@ -0,0 +1,671 @@ +# BR_YKC 充电桩网关 + +基于 STM32H743 + AIR724 4G模块 的充电桩网关方案,对接**云快充**平台,支持通过**4G TCP**和**以太网UDP**双通道通信。 + + + +--- + +## 目录 + +- [硬件架构](#硬件架构) +- [软件架构](#软件架构) +- [目录结构](#目录结构) +- [通信拓扑](#通信拓扑) +- [三层状态机](#三层状态机) +- [通信协议](#通信协议) + - [南向协议(网关 ↔ 桩)](#南向协议网关--桩) + - [上位机协议(网关 ↔ 上位机APP)](#上位机协议网关--上位机app) + - [北向协议(网关 ↔ 云快充)](#北向协议网关--云快充) + - [4G链路协议(STM32 ↔ AIR724)](#4g链路协议stm32--air724) +- [上位机 C# 客户端](#上位机-c-客户端) + - [项目结构](#项目结构) + - [页面功能](#页面功能) + - [通信机制](#通信机制) + - [数据存储](#数据存储) + - [配置参数](#配置参数) +- [配置指南](#配置指南) + - [修改桩编码(序列号)](#修改桩编码序列号) + - [修改桩数量](#修改桩数量) + - [修改每桩枪数](#修改每桩枪数) + - [配置云快充服务器地址](#配置云快充服务器地址) +- [Flash组件使用说明](#flash组件使用说明) + - [框架层 drv_flash](#框架层-drv_flash) + - [应用层 flash_config](#应用层-flash_config) + - [使用示例](#使用示例) +- [任务列表](#任务列表) +- [日志格式](#日志格式) + +--- + +## 硬件架构 + +``` +┌──────────────────────────────────────────────┐ +│ STM32H743 │ +│ │ +│ UART1 ─── 4G模块(AIR724) ──→ 云快充平台 (TCP)│ +│ UART3 ─── RS485 │ +│ ETH ──── LAN (UDP, 桩1~6 + 上位机) │ +│ UART6 ─── 调试串口(printf) │ +└──────────────────────────────────────────────┘ +``` + +| 外设 | 用途 | +|------|------| +| UART1 (115200) | 与AIR724 4G模块通信 | +| UART3 | RS485接口 | +| ETH (LWIP) | 以太网,桩1~6 UDP通信 + 上位机 | +| UART6 | printf调试输出 | + +--- + +## 软件架构 + +``` + Os/ 任务/队列/信号量/定时器管理 + ├─ os_task.c 5个任务的创建 + ├─ os_queue.c 3个消息队列 + ├─ os_timer.c 软件定时器 + └─ os_semaphore.c 信号量/互斥量 + + App/ 应用层任务 + ├─ task_air724 4G下行数据解析任务 + ├─ task_udp UDP收发 + 解析任务 + ├─ task_ykc 云快充核心状态机任务 + └─ task_sys 系统任务(心跳指示、喂狗) + + Driver/ 驱动层 + ├─ drv_air724 AIR724命令收发 + 响应解析 + ├─ drv_usart 串口收发(含互斥锁) + ├─ drv_flash 通用Flash读写框架 + └─ flash_config 应用层Flash配置 + + Network/ 网络层 + ├─ udp_manager UDP报文发送 + └─ udp_router UDP路由分发 + + Protocol/ 协议层 + ├─ Point/ 南向(充电桩JSON) + ├─ Host Computer/ 上位机JSON通信 + └─ Ykc/ 北向(云快充字节协议) + ├─ charger_to_server 上行帧 + ├─ server_to_charger 下行帧 + ├─ server_common 公共(组包/解包/CRC) + └─ ykc_router 帧类型路由分发 + + Global/ 全局数据 + ├─ g_dcpile 桩/枪 结构体 + 管理器 + ├─ g_init 全局初始化 + ├─ g_runtime 运行时统计 + └─ board_config 板级配置(IP/端口) + + 4G/ 4G模块Lua固件 + ├─ core/main.lua 入口:初始化+串口+网络 + ├─ core/cmd.lua 命令解析+分发 + └─ core/linksocket.lua 多路TCP socket管理 +``` + +--- + +## 通信拓扑 + +``` + 云快充服务器(TCP) + ↑ + │ 4G + AIR724模块 + ↑ UART1 + ┌─────────┴──────────┐ + │ STM32H743 网关 │ + │ (协议转换器) │ + └─────────┬──────────┘ + UDP │ 以太网 + ┌─────────────┼─────────────┐ + │ │ │ + 桩1~6 上位机 RS485设备 + (10.12.19.101~106) (107) (触摸屏等) +``` + +**数据路径:** + +- **云快充 → 桩**:云快充TCP → 4G → UART1 → STM32解析 → 填充数据到桩结构体 +- **桩上报 → 云快充**:桩 → UDP → STM32 → 打包Ykc帧 → UART1 → 4G → TCP → 云快充 +- **上位机查询**:上位机 → UDP → STM32 → 查询桩数据 → 回复 + +--- + +## 三层状态机 + +[task_ykc.c](file:///d:/公司项目/BR_YKC/Core/User/App/task_ykc.c) 实现了 **桩层 + 枪层** 两层非阻塞时间片状态机: + +### 桩层初始化(桩0~2通用,只做一次) + +``` +step 0 ── 等待桩UDP上电 → 连接4G通道(i+1) + ↓ (socket_connected[i] == true) +step 1 ── 发送云快充登录(0x01) + ↓ (is_online == true) +step 2 ── 发送计费模型验证(0x05) + 请求(0x09) + ↓ (get_model == true) +step 3 ── 进入枪层运行态 +``` + +### 枪层运行(每把枪独立) + +``` +gun_step 0 ── 每5秒上传实时数据(0x13) + 主动上报到上位机 + 如有账单(is_get_bill==true),上传交易记录(0x3B) +``` + +### 非阻塞机制 + +所有 `osDelay()` 已被替换为**时间戳轮询**: + +```c +now = HAL_GetTick(); +if (now < pile->step_tick) // 时间没到,立即跳过,不阻塞 + continue; + +// 执行动作 +pile->step_tick = now + 5000; // 设定5秒后的下次超时 +``` + +6个桩每轮循环只需微秒级完成,互不阻塞。 + +--- + +## 通信协议 + +### 南向协议(网关 ↔ 桩) + +- **传输**:以太网 UDP +- **端口**:Server=6001, Stake=6001, App=6002 +- **桩IP**:10.12.19.101 ~ 106 +- **格式**:JSON + +**路由表** [udp_router.c](file:///d:/公司项目/BR_YKC/Core/User/Network/udp_router.c): + +| cmd | 桩ID来源 | 处理函数 | 说明 | +|-----|---------|----------|------| +| `online` | 桩1~6 | `point_callback_power_on` | 上电,设置 is_udp_online | +| `heartbeat` | 桩1~6 | `point_callback_heartbeat` | 心跳 | +| `start charging` | 桩1~6 | `point_callback_start_charging` | 开始充电反馈 | +| `end charging` | 桩1~6 | `point_callback_end_charging` | 停止充电反馈 | +| `realtime data` | 桩1~6 | `point_callback_realtime_data` | 实时数据 | +| `settlement bill` | 桩1~6 | `point_callback_settlement_bill` | 结算账单 | +| `proactive end charging` | 桩1~6 | `point_callback_proactive_end_charging` | 桩主动停止 | +| `charge process real` | 桩1~6 | `point_callback_charge_process` | BMS需求 | +| `bms info real` | 桩1~6 | `point_callback_bms_info` | BMS信息 | + +**桩未上电拦截**:除 `online` 外,所有桩指令都会检查 `is_udp_online`,未上电的桩指令将被静默丢弃。 + +### 上位机协议(网关 ↔ 上位机APP) + +- **传输**:以太网 UDP(同一通道) +- **端口**:Server=6001, App=6002 +- **上位机ID**:7 +- **格式**:JSON,含 `request_id` + `success` + +**指令表** [host_computer_protocol.h](file:///d:/公司项目/BR_YKC/Core/User/Protocol/Host%20Computer/host_computer_protocol.h): + +| cmd | 功能 | 处理函数 | 回复字段 | +|-----|------|----------|----------| +| `server_login` | 登录 | `host_computer_on_login` | success | +| `server_get_status` | 获取所有桩状态 | `host_computer_on_get_status` | piles[].serial/is_online/guns[].status | +| `server_reboot` | 重启网关 | `host_computer_on_reboot` | 无(立即重启) | +| `gateway_get_info` | 查询网关信息 | `host_computer_on_get_gw_info` | device_id, software_ver, hardware_ver, uptime | +| `gateway_get_4g_status` | 查询4G状态 | `host_computer_on_get_4g_status` | iccid, net_status, signal, isp | +| `gateway_get_cloud_config` | 查询云配置 | `host_computer_on_get_cloud_config` | host, port | +| `gateway_set_cloud_config` | 设置云配置 | `host_computer_on_set_cloud_config` | host, port(触发重连) | +| `gateway_get_net_config` | 查询网络配置 | `host_computer_on_get_net_config` | ip, mask, gateway, dns | +| `gateway_set_net_config` | 设置网络配置 | `host_computer_on_set_net_config` | success(重启生效) | +| `server_get_pile_info` | 查询单个桩信息 | `host_computer_on_get_pile_info` | serial, type, gun_num, protocol_ver, software_ver, sim | + +### 北向协议(网关 ↔ 云快充) + +- **传输**:4G TCP +- **数据格式**:字节流,含CRC16校验 +- **封装**:`55 AA 01 socketId len [ykc_frame] AA 55` + +#### YKC帧格式 + +``` +┌────────┬──────┬────────┬─────────┬────────┬──────────┬──────┐ +│ 0x68 │ len │ serial │encrypt │type │ data │ crc │ +│ (起始) │(1字节)│ (2字节)│ (1字节) │(1字节) │ (n字节) │2字节│ +└────────┴──────┴────────┴─────────┴────────┴──────────┴──────┘ +``` + +#### 帧类型(上行 → 云快充) + +| type | 函数 | 说明 | +|------|------|------| +| 0x01 | `charger_to_server_0X01` | 登录认证 | +| 0x03 | `charger_to_server_0X03` | 心跳 | +| 0x05 | `charger_to_server_0X05` | 计费模型验证 | +| 0x09 | `charger_to_server_0X09` | 计费模型请求 | +| 0x13 | `charger_to_server_0X13` | 实时监测数据 | +| 0x19 | `charger_to_server_0X19` | 充电结束 | +| 0x33 | `charger_to_server_0X33` | 远程启动回复 | +| 0x35 | `charger_to_server_0X35` | 远程停机回复 | +| 0x3B | `charger_to_server_0X3B` | 交易记录 | +| 0x57 | `charger_to_server_0x57` | 计费模型应答 | + +#### 帧类型(下行 ← 云快充) + +| type | 处理函数 | 说明 | +|------|----------|------| +| 0x02 | `on_cmd_frame_type_0X02` | 登录认证应答 | +| 0x04 | `on_cmd_frame_type_0X04` | 心跳应答 | +| 0x06 | `on_cmd_frame_type_0X06` | 计费模型验证应答 | +| 0x0A | `on_cmd_frame_type_0X0A` | 获取计费模型 | +| 0x58 | `on_cmd_frame_type_0X58` | 计费模型设置 | +| 0x34 | `on_cmd_frame_type_0X34` | 平台启动充电 | +| 0x36 | `on_cmd_frame_type_0X36` | 平台控制停止充电 | +| 0x40 | `on_cmd_frame_type_0X40` | 交易记录确认 | + +### 4G链路协议(STM32 ↔ AIR724) + +AIR724模块内部运行Lua脚本 [cmd.lua](file:///d:/公司项目/BR_YKC/4G/code/core/cmd.lua) + [linksocket.lua](file:///d:/公司项目/BR_YKC/4G/code/core/linksocket.lua): + +``` +55 AA mainCmd subCmd [payload] AA 55 +``` + +| mainCmd | subCmd | 功能 | +|---------|--------|------| +| 0x01 | socketId | 数据发送到指定Socket | +| 0x02 | - | 系统重启 | +| 0x03 | 0x01/0x02 | 连接/断开Socket | +| 0x04 | 0x00 | 设置服务器地址 | +| 0x05 | 0x01~0x03 | 查询ICCID/IMSI/IMEI | +| 0x06 | 0x00 | 查询信号强度 | +| 0x07 | 0x00 | 查询链路状态 | + +**上行响应(4G → STM32)**: + +| mainCmd | subCmd | 含义 | +|---------|--------|------| +| 0x83 | 0x01 | TCP已连接 | +| 0x83 | 0x02 | TCP已断开 | +| 0x83 | 0x03 | TCP连接失败 | +| 0x84 | 0x01~0x03 | SIM信息(ICCID/IMSI/IMEI) | +| 0x85 | - | 信号强度 | +| 0x86 | - | 链路状态 | + +--- + +## 上位机 C# 客户端 + +C# 上位机客户端项目位于 `C:\Users\Administrator\PycharmProjects\PythonProject\C#\YKC`,基于 **.NET Framework 4.7.2** + **WPF** 框架开发,通过 **UDP** 与网关通信。 + +### 项目结构 + +``` +YKC/ +├── App.xaml(.cs) 程序入口 +├── MainWindow.xaml(.cs) 主窗口(导航框架) +├── LoginWindow.xaml(.cs) 登录窗口 +├── Config.cs 配置参数 + 指令字典 +├── UdpClient.cs UDP通信客户端(同步/异步) +├── PilesDataStore.cs 充电桩历史数据存储(含图表数据) +│ +├── Pages/ +│ ├── DashboardPage.xaml(.cs) 总览页面 +│ ├── RealtimePage.xaml(.cs) 实时监控(含OxyPlot图表) +│ ├── ChargerPage.xaml(.cs) 充电桩管理 +│ └── GatewayPage.xaml(.cs) 网关管理 +│ +├── bin/Debug/ +│ ├── OxyPlot.dll 波形图库 +│ ├── OxyPlot.Wpf.dll +│ ├── OxyPlot.Wpf.Shared.dll +│ └── Newtonsoft.Json.dll JSON库 +│ +└── Properties/ 项目属性 +``` + +### 页面功能 + +#### 1. 登录页面 (LoginWindow) + +- 用户名/密码认证 +- 发送 `server_login` → 网关返回 `success: true/false` +- 默认账号:`admin` / `123456` + +#### 2. 总览页面 (DashboardPage) + +- **连接状态**:显示网关在线/离线 +- **在线/充电统计**:在线桩数、充电中枪数 +- **表格列表**:每桩的序列号、在线状态、每枪状态 +- 每 **5秒** 自动轮询 `server_get_status` + +| 枪状态 | 含义 | +|--------|------| +| 0 | 离线 | +| 1 | 故障 | +| 2 | 空闲 | +| 3 | 充电中 | + +#### 3. 实时监控页面 (RealtimePage) + +- 选择桩号(1~N) + 枪号(1~N) +- 实时显示:电流(A)、电压(V)、功率(kW)、电量(kWh)、总金额、SOC、累计时间、剩余时间 +- **OxyPlot 实时曲线**: + - 电流/电压/功率 折线图(含时间轴,最多300个点) + - 电费/服务费/总金额 柱状图 +- 每 **2秒** 自动轮询 `report_data` 主动上报数据(来自PilesDataStore历史记录) + +#### 4. 充电桩管理页面 (ChargerPage) + +**查询桩信息**: +- 按桩索引查询 +- 回复显示:序列号、类型(直流/交流)、枪数、协议版本、软件版本、SIM + +**设置桩ID**: +- 输入桩索引 + 14位HEX序列号 + +**重启网关**: +- 发送 `server_reboot`(确认弹窗) + +#### 5. 网关管理页面 (GatewayPage) + +**网关信息卡片**: +- 设备ID、软件版本、硬件版本、运行时长 +- 调用 `gateway_get_info` + +**4G状态卡片**: +- ICCID、网络状态、信号强度(dBm)、运营商 +- 调用 `gateway_get_4g_status` + +**云平台配置卡片**: +- 查询(`gateway_get_cloud_config`) / 保存(`gateway_set_cloud_config`) +- 保存时验证:IP格式或域名格式,端口 1~65535 + +**网络配置卡片**: +- IP/掩码/网关/DNS 查询 + 设置 +- 调用 `gateway_get_net_config` / `gateway_set_net_config` +- 支持IP地址格式校验 + +### 通信机制 + +UDP通信封装在 [UdpClient.cs](file:///C:/Users/Administrator/PycharmProjects/PythonProject/C%23/YKC/UdpClient.cs): + +**消息格式**: +```json +{ + "id": 7, // 固定ID=7(上位机) + "cmd": "server_login", + "request_id": "server_login_1700000000000", + ...其他参数... +} +``` + +**回复格式**: +```json +{ + "request_id": "server_login_...", + "success": true, + ...其他数据... +} +``` + +**两种发送模式**: + +| 方法 | 说明 | +|------|------| +| `Send(payload, callback)` | 异步发送,通过回调接收回复 | +| `SendSync(payload, timeoutSec?)` | 同步发送,阻塞等待回复或超时(默认4秒) | + +**超时机制**:异步请求启动定时器,超时后自动回调 `{ success: false, error: "timeout" }` + +**主动上报接收**:`OnActiveReport` 事件监听 `cmd == "report_data"` / `"pile_metrics"` / `"real_time_data"`,由 `PilesDataStore` 订阅存储。 + +**监听端口**:`Config.LocalPort = 6002`,目标网关 `Config.TargetIp:Config.TargetPort`(默认 `10.12.19.100:6001`) + +### 数据存储 + +[PilesDataStore.cs](file:///C:/Users/Administrator/PycharmProjects/PythonProject/C%23/YKC/PilesDataStore.cs) 单例模式管理: + +- **实时数据**:`GetLatest(pile, gun)` → 最新一条 `JObject` +- **图表数据**:`GetChartData(pile, gun)` → `GunData` 对象,内含最多300个历史点的电流/电压/功率/电量/金额等序列 +- **历史清理**:超过300个点自动移除旧数据 + +### 配置参数 + +[Config.cs](file:///C:/Users/Administrator/PycharmProjects/PythonProject/C%23/YKC/Config.cs): + +```csharp +TargetIp = "10.12.19.100"; // 网关IP +TargetPort = 6001; // 网关UDP端口 +LocalPort = 6002; // 本机监听端口 +UdpTimeout = 3; // 超时时间(秒) +``` + +**指令字典**(与网关 `udp_router.c` 路由表对应): + +| 常量 | cmd | 对应网关处理函数 | +|------|-----|------------------| +| `LOGIN` | `server_login` | `host_computer_on_login` | +| `GET_STATUS` | `server_get_status` | `host_computer_on_get_status` | +| `REBOOT` | `server_reboot` | `host_computer_on_reboot` | +| `GET_PILE_INFO` | `server_get_pile_info` | `host_computer_on_get_pile_info` | +| `GET_GW_INFO` | `gateway_get_info` | `host_computer_on_get_gw_info` | +| `GET_4G_STATUS` | `gateway_get_4g_status` | `host_computer_on_get_4g_status` | +| `GET_CLOUD_CONFIG` | `gateway_get_cloud_config` | `host_computer_on_get_cloud_config` | +| `SET_CLOUD_CONFIG` | `gateway_set_cloud_config` | `host_computer_on_set_cloud_config` | +| `GET_NET_CONFIG` | `gateway_get_net_config` | `host_computer_on_get_net_config` | +| `SET_NET_CONFIG` | `gateway_set_net_config` | `host_computer_on_set_net_config` | +| `SET_PILE_ID` | `server_set_pile_id` | 待开发 | +| `REPORT_DATA` | `report_data` | 主动上报(南向) | + +--- + +## 配置指南 + +### 修改桩编码(序列号) + +修改 [g_dcpile.c](file:///d:/公司项目/BR_YKC/Core/User/Global/g_dcpile.c) 中的 `piles_serial` 数组,每个桩编码为7字节十六进制: + +```c +/*充电桩序列号*/ +const uint8_t piles_serial[6][7] = { + {0x32, 0x01, 0x06, 0x01, 0x16, 0x92, 0x45}, // 桩1 + {0x32, 0x01, 0x06, 0x01, 0x16, 0x92, 0x44}, // 桩2 + {0x32, 0x01, 0x06, 0x01, 0x16, 0x92, 0x43}, // 桩3 + {0x32, 0x01, 0x06, 0x01, 0x16, 0x92, 0x42}, // 桩4 + {0x32, 0x01, 0x06, 0x01, 0x11, 0x15, 0x58}, // 桩5 + {0x32, 0x01, 0x06, 0x01, 0x11, 0x15, 0x54}, // 桩6 +}; +``` + +> `init_chargers()` 中通过 `memcpy(ctx->charger_serial, piles_serial[i], CHARGER_SERIAL_LENGTH)` 加载。 + +序列号转换为字符串显示时表现为14位HEX码,例如 `32010601169244`。 + +### 修改桩数量 + +**两步:** + +**①** 修改 [g_dcpile.h](file:///d:/公司项目/BR_YKC/Core/User/Global/g_dcpile.h) 中的宏: + +```c +#define MAX_CHARGER_COUNT 2 // ← 改为实际桩数量 +``` + +**②** 确保 [g_dcpile.c](file:///d:/公司项目/BR_YKC/Core/User/Global/g_dcpile.c) 中的 `piles_serial` 数组有对应数量的序列号。 + +同时需要修改 [udp_router.c](file:///d:/公司项目/BR_YKC/Core/User/Network/udp_router.c) 中 `ROUTE_TABLE` 的路由数量(如果新增桩路由),以及 [task_ykc.c](file:///d:/公司项目/BR_YKC/Core/User/App/task_ykc.c) 中状态机的循环 `for (int i = 0; i < g_charger_manager.charger_count; i++)` 已自动适配。 + +> 桩1~6的UDP IP地址在 [udp_manager.c](file:///d:/公司项目/BR_YKC/Core/User/Network/udp_manager.c) 中硬编码: +> ```c +> static ip4_addr_t s_point_ip[6] = { +> IPADDR4_INIT_BYTES(10, 12, 19, 101), /* 桩1 */ +> IPADDR4_INIT_BYTES(10, 12, 19, 102), /* 桩2 */ +> ... +> }; +> ``` +> 如果桩数量变化,需要同步更新此数组。 + +### 修改每桩枪数 + +修改 [g_dcpile.h](file:///d:/公司项目/BR_YKC/Core/User/Global/g_dcpile.h): + +```c +#define MAX_GUN_PER_CHARGER 2 // ← 改为实际枪数 +``` + +状态机中的枪循环已自动适配: +```c +for (int g = 0; g < MAX_GUN_PER_CHARGER; g++) +``` + +### 配置云快充服务器地址 + +默认在 [linksocket.lua](file:///d:/公司项目/BR_YKC/4G/code/core/linksocket.lua) 中: + +```lua +local server_config = { + ip = "129.211.170.245", + port = 9002 +} +``` + +可通过上位机指令 `gateway_set_cloud_config` 动态修改 `s_cloud_host` / `s_cloud_port`,修改后调用 `drv_air724_set_server` 触发AIR724重新连接。 + +--- + +## Flash组件使用说明 + +Flash存储组件分为**两层**: + +### 框架层 drv_flash + +[drv_flash.h](file:///d:/公司项目/BR_YKC/Core/User/Driver/drv_flash.h) / [drv_flash.c](file:///d:/公司项目/BR_YKC/Core/User/Driver/drv_flash.c) + +提供通用Flash读写管理,支持按帧类型存取、覆写模式、多帧管理。 + +#### 帧格式 + +``` +┌──────┬──────┬──────┬──────┬──────────┬──────┐ +│ HEAD │ size_low │size_high│type│ DATA │ TAIL │ +│(0xA5)│ (2字节 小端) │(1字节)│(n字节) │(0x5A)│ +└──────┴──────┴──────┴──────┴──────────┴──────┘ +``` + +#### 核心API + +| 函数 | 说明 | +|------|------| +| `flash_manage_init(flash_manage_t *fm)` | 初始化:遍历Flash重建可读帧表 | +| `flash_manage_read(fm, *pbuf, frame_type)` | 读取指定类型的帧数据 | +| `flash_manage_write(fm, *pbuf, size, frame_type)` | 写入指定类型的帧数据 | + +#### flash_manage_t 配置 + +```c +typedef struct { + uint8_t align_num; // 地址对齐数(STM32H7一般为32) + flash_write_read_mode_t flash_write_mode; // 写模式 + flash_write_read_mode_t flash_read_mode; // 读模式 + uint32_t flash_start_address; // 管理起始地址(按扇区对齐) + uint32_t manage_sector_num; // 管理的扇区数 + uint32_t sector_size; // 扇区大小(H743=128KB) + void (*read_flash)(...); // 读函数指针 + void (*write_flash)(...); // 写函数指针 + uint8_t (*erase_sector)(...); // 擦除函数指针 +} flash_manage_t; +``` + +### 应用层 flash_config + +[flash_config.h](file:///d:/公司项目/BR_YKC/Core/User/Driver/flash_config.h) / [flash_config.c](file:///d:/公司项目/BR_YKC/Core/User/Driver/flash_config.c) + +基于框架层的封装,提供开箱即用的API: + +```c +// 单例,地址=0x08180000,1个Sector(128KB),32字节对齐 +void stm_flash_init(void); + +// 读取,传入缓冲区 + 帧类型,成功返回1 +int8_t stm_flash_read(uint8_t *pbuf, uint8_t frame_type); + +// 写入,传入数据 + 大小 + 帧类型,成功返回1 +int8_t stm_flash_write(uint8_t *pbuf, uint16_t size, uint8_t frame_type); +``` + +> **注意**:STM32H743 Bank2 的 Sector 擦除规则: +> - 起始地址 `0x08100000`,每Sector = 128KB +> - 写入必须 **32字节对齐**,不满32字节补 `0xFF` +> - `flash_config.c` 使用 `0x08180000`(Bank2的第4个Sector) + +### 使用示例 + +```c +#include "flash_config.h" + +// 初始化(在main中调用一次) +stm_flash_init(); + +// 写入配置数据 +uint8_t config_data[] = {0x01, 0x02, 0x03, 0x04}; +stm_flash_write(config_data, sizeof(config_data), 0x01); // 帧类型1 + +// 读取配置数据 +uint8_t read_buf[64] = {0}; +if (stm_flash_read(read_buf, 0x01) == 1) { + // 读取成功,read_buf中为数据 +} else { + // 无数据 +} +``` + +**写模式**: + +| 模式 | 值 | 说明 | +|------|----|------| +| `FLASH_NO_OVERWRITING_MODE` | 0x00 | 只追加,不覆盖旧帧 | +| `FLASH_OVERWRITING_MODE` | 0x01 | 将旧帧头置为无效,写新帧(默认) | + +**读模式**: + +| 模式 | 值 | 说明 | +|------|----|------| +| `FLASH_NO_CLEAR_MODE` | 0x02 | 读取后不清除(默认) | +| `FLASH_CLEAR_MODE` | 0x03 | 读取后将帧标记为无效 | + +--- + +## 任务列表 + +| 任务 | 函数 | 栈大小 | 优先级 | 说明 | +|------|------|--------|--------|------| +| SysTask | `sys_task_function` | 128 | Low | 指示灯、蜂鸣器、喂狗 | +| Air724RecvTask | `air724_recv_task_function` | 1024 | AboveNormal | 解析4G下行数据 | +| UDPRecvTask | `udp_recv_task_function` | 1536 | High | UDP接收入队 | +| UDPParseTask | `udp_parse_task_function` | 2048 | AboveNormal | UDP数据解析+路由分发 | +| YkcTask | `ykc_task_function` | 1024 | AboveNormal | 云快充状态机+数据上报 | + +### 消息队列 + +| 队列 | 长度 | 消息大小 | 用途 | +|------|------|----------|------| +| Air724_Message_Queue | 20 | 512 | 4G接收数据 | +| RS485_Message_Queue | 5 | 256 | RS485接收数据 | +| UDP_Message_Queue | 20 | sizeof(UdpMsg_t) | UDP接收数据 | + +--- + +## 日志格式 + +``` +[YKC Router] frame=0x02 │ stake=1 │ 登录认证应答 ← 4G下行路由 +[ UDP 接收路由 ] 指令: realtime data │ 桩ID: 1 │ 实时数据 ← 南向UDP +[ UDP 路由拦截 ] 桩ID: 2 未上电,忽略指令: heartbeat ← 上电过滤 +[ 北向 ] 对电桩 1 发送登录认证 ← 4G上行 +[ 北向 ] 对电桩 1 枪 1 上传交易记录(0x3B),电量:0.00,金额:0.00 ← 4G上行 +[ 4G ] 通道 1 连接成功 ← 4G链路通知 +[ 上位机 ] get_status 回复已发送 ← 上位机回复 +``` diff --git a/Doc/桩和网关通讯协议.md b/Doc/桩和网关通讯协议.md new file mode 100644 index 0000000..02c0009 --- /dev/null +++ b/Doc/桩和网关通讯协议.md @@ -0,0 +1,974 @@ +# 充电桩与网关 UDP JSON 通讯协议 + +## 概述 + +充电桩与网关之间通过 **以太网 UDP** 通信,使用 **JSON** 格式进行数据交换。 + +| 项目 | 说明 | +|------|------| +| 传输层 | UDP | +| 网关端口 | 6001 | +| 桩IP范围 | 10.12.19.101 ~ 106 | +| 数据格式 | JSON | +| 编码 | UTF-8 | + +--- + +## 通讯流程 + +``` +充电桩上电 + ↓ +发送 online(上电) ──────→ 网关回复 charger_id + ↓ +正常运行时,每 5~10 秒 +发送 heartbeat(心跳) ──→ 网关回复 + ↓ + ┌─── 网关下发 start charging(启动充电) + │ +充电桩周期上报实时数据 ←──── 网关可下发 end charging(停止充电) +(realtime data / charge process real / bms info real) + │ + └─── 充电结束 → 上报 settlement bill(结算账单) +``` + +--- + +## 指令列表 + +| # | 标题 | cmd | 方向 | 触发方式 | +|---|------|-----|------|----------| +| 1 | 桩上电 | `online` | 桩 → 网关 → 桩 | 上电即发 | +| 2 | 心跳 | `heartbeat` | 桩 → 网关 → 桩 | 5~10秒周期 | +| 3 | 启动充电 | `start charging` | 网关 → 桩 → 网关 | 网关主动下发 | +| 4 | 停止充电 | `end charging` | 网关 → 桩 → 网关 | 网关主动下发 | +| 5 | 主动停止充电 | `proactive end charging` | 桩 → 网关 → 桩 | 桩主动上报 | +| 6 | 实时数据上报 | `realtime data` | 桩 → 网关 → 桩 | 周期上送 | +| 7 | BMS信息上报 | `bms info` | 桩 → 网关 → 桩 | 桩主动上报 | +| 8 | 充电参数配置 | `charge config` | 桩 → 网关 → 桩 | 桩主动上报 | +| 9 | 充电错误报文 | `charge error` | 桩 → 网关 → 桩 | 桩主动上报 | +| 10 | BMS中止充电 | `bms stop` | 桩 → 网关 → 桩 | 桩主动上报 | +| 11 | 充电机中止充电 | `charger stop` | 桩 → 网关 → 桩 | 桩主动上报 | +| 12 | 充电过程BMS需求与输出 | `charge process real` | 桩 → 网关 → 桩 | 15秒周期 | +| 13 | 充电过程BMS信息 | `bms info real` | 桩 → 网关 → 桩 | 15秒周期 | +| 14 | 结算账单上传 | `settlement bill` | 桩 → 网关 → 桩 | 桩主动上报 | + +--- + +## 通用字段说明 + +所有 JSON 消息均包含以下固定字段: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | Number | 桩编码 (1~6) | +| `cmd` | String | 指令标识,见指令列表 | +| `type` | String | `"request"` 请求帧 / `"response"` 回复帧 | + +--- + +## 1. 桩上电 + +> **方向**:充电桩 → 网关 → 充电桩 + +充电桩上电后立即发送,网关回复桩的唯一ID。 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "online", + "type": "request" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 | +| cmd | String | 是 | "online" | +| type | String | 是 | "request" | + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "online", + "charger_id": "32010203040506", + "type": "response" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 | +| cmd | String | 是 | "online" | +| charger_id | String | 是 | 桩唯一ID | +| type | String | 是 | "response" | + +--- + +## 2. 心跳 + +> **方向**:充电桩 → 网关 → 充电桩 +> **周期**:5~10 秒 + +桩定期上报各枪实时状态。 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "heartbeat", + "gun": [ + { "id": 1, "state": 0 }, + { "id": 2, "state": 0 } + ], + "type": "request" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "heartbeat" | +| gun | Array | 是 | 枪口列表 | +| gun[].id | Number | 是 | 枪编号 (1~N) | +| gun[].state | Number | 是 | 枪状态:0 离线;1 故障;2 空闲;3 充电 | +| type | String | 是 | "request" | + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "heartbeat", + "gun_id": 1, + "type": "response" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "heartbeat" | +| gun_id | Number | 是 | 枪编号 (1~N) | +| type | String | 是 | "response" | + +--- + +## 3. 启动充电 + +> **方向**:网关 → 充电桩 → 网关 + +网关向充电桩下发启动充电指令,同步下发**计费模型**。 + +**Request (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "start charging", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "fee": [ + [1, 0, 6, 0.3, 0.5], + [2, 6, 10, 0.8, 0.8], + [3, 10, 15, 1.2, 0.8], + [4, 15, 24, 0.6, 0.6] + ], + "limit_amount": 0, + "type": "request" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "start charging" | +| transaction_id | String | 是 | 订单编码 32位 | +| gun_id | Number | 是 | 枪编码 (1~N) | +| fee | Array | 是 | 计费模型数组,每行:[计费段, 开始时间, 结束时间, 电费, 服务费] | +| limit_amount | Float | 是 | 停止金额(元)。0 为不限制 | +| type | String | 是 | "request" | + +**fee 数组格式:** + +每行固定5个元素: +``` +[计费段, 开始时间(小时), 结束时间(小时), 电费单价, 服务费单价] +``` + +| 计费段 | 含义 | +|--------|------| +| 1 | 尖 | +| 2 | 峰 | +| 3 | 平 | +| 4 | 谷 | + +**Response (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "start charging", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "result": 0, + "error_code": 0, + "type": "response" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "start charging" | +| transaction_id | String | 是 | 订单编码 32位 | +| gun_id | Number | 是 | 枪编码 (1~N) | +| result | Number | 是 | 启动结果:0=失败;1=成功 | +| error_code | Number | 是 | 错误码:0=无;1=设备编号不匹配;2=枪已在充电;3=设备故障;4=设备离线;5=未插枪 | +| type | String | 是 | "response" | + +--- + +## 4. 停止充电 + +> **方向**:网关 → 充电桩 → 网关 + +**Request (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "end charging", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "type": "request" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "end charging" | +| transaction_id | String | 是 | 订单编码 32位 | +| gun_id | Number | 是 | 枪编码 (1~N) | +| type | String | 是 | "request" | + +**Response (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "end charging", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "result": 0, + "error_code": 0, + "type": "response" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "end charging" | +| transaction_id | String | 是 | 订单编码 32位 | +| gun_id | Number | 是 | 枪编码 (1~N) | +| result | Number | 是 | 停止结果:0 失败;1 成功 | +| error_code | Number | 是 | 错误码:0 无;1 枪未在充电;2 其他故障 | +| type | String | 是 | "response" | + +--- + +## 5. 主动停止充电 + +> **方向**:充电桩 → 网关 → 充电桩 + +充电桩主动上报停止充电(如用户刷卡停止、车辆BMS中止等)。 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "proactive end charging", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "type": "request" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "proactive end charging" | +| transaction_id | String | 是 | 订单编码 32位 | +| gun_id | Number | 是 | 枪编码 (1~N) | +| type | String | 是 | "request" | + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "proactive end charging", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "type": "response" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "end charging" | +| transaction_id | String | 是 | 订单编码 32位 | +| gun_id | Number | 是 | 枪编码 (1~N) | +| type | String | 是 | "response" | + +--- + +## 6. 充电桩实时数据上报 + +> **方向**:充电桩 → 网关 → 充电桩 +> **周期**:待机 5 分钟、充电 15 秒 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "realtime data", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "state": 0, + "gun_back": 0, + "gun_insert": 1, + "voltage": 2222, + "current": 2222, + "cable_temp": 85, + "cable_code": "1234567890123456", + "soc": 85, + "battery_temp": 95, + "charge_time": 45, + "remain_time": 30, + "charge_kwh": 12.3456, + "loss_kwh": 12.4567, + "charge_amount": 18.6851, + "fault": 0, + "type": "request" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "realtime data" | +| transaction_id | String | 是 | 交易流水号 32位,待机时填充0 | +| gun_id | Number | 是 | 枪编号 (1~N) | +| state | Number | 是 | 枪状态:0 离线;1 故障;2 空闲;3 充电 | +| gun_back | Number | 是 | 枪是否归位:0 否;1 是;2 未知 | +| gun_insert | Number | 是 | 是否插枪:0 否;1 是 | +| voltage | Float | 是 | 输出电压,单位0.1V。待机时为0 | +| current | Float | 是 | 输出电流,单位0.1A。待机时为0 | +| cable_temp | Number | 是 | 枪线温度,单位℃,偏移量-50。待机时为0 | +| cable_code | String | 是 | 枪线编码 16位,没有时填充0 | +| soc | Number | 是 | 电池SOC百分比 0~100,待机/交流桩为0 | +| battery_temp | Number | 是 | 电池组最高温度,单位℃,偏移量-50。待机/交流桩为0 | +| charge_time | Number | 是 | 累计充电时间,单位分钟。待机时为0 | +| remain_time | Number | 是 | 剩余时间,单位分钟。待机/交流桩为0 | +| charge_kwh | Float | 是 | 充电度数(kWh),精确到小数点后4位。待机时为0 | +| loss_kwh | Float | 是 | 计损充电度数(kWh)。未设置计损比例时等于charge_kwh | +| charge_amount | Float | 是 | 已充金额(元),精确到小数点后4位 | +| fault | Number | 是 | 硬件故障位图(16bit),见下方说明 | +| type | String | 是 | "request" | + +**fault 故障位图:** + +| Bit | 故障 | +|-----|------| +| 1 | 急停 | +| 2 | 无模块 | +| 3 | 温度高 | +| 4 | 防雷故障 | +| 5 | DC20中断 | +| 6 | FC08中断 | +| 7 | 电表中断 | +| 8 | 读卡器中断 | +| 9 | RC10中断 | +| 10 | 风扇故障 | +| 11 | 熔断器故障 | +| 12 | 接触器故障 | +| 13 | 门打开 | + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "realtime data", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "type": "response" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "realtime data" | +| transaction_id | String | 是 | 交易流水号 32位 | +| gun_id | Number | 是 | 枪编号 (1~N) | +| type | String | 是 | "response" | + +--- + +## 7. BMS信息上报 + +> **方向**:充电桩 → 网关 → 充电桩 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "bms info", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "protocol_version": "0001.01", + "battery_type": 3, + "rated_capacity": 600.0, + "rated_voltage": 3600.0, + "manufacturer": "CATL", + "battery_sn": "BT123456", + "production_year": 2023, + "production_month": 6, + "production_day": 15, + "charge_count": 1250, + "ownership": 1, + "reserved": 0, + "vin": "LSVAA4182E2123456", + "software_version": "FFFFFF.07DF.0B.0A.10", + "type": "request" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "bms info" | +| transaction_id | String | 是 | 交易流水号 32位 | +| gun_id | Number | 是 | 枪编号 (1~N) | +| protocol_version | String | 是 | BMS通信协议版本号。格式:`byte3.byte2-byte1`,例:"0001.01"=V1.1 | +| battery_type | Number | 是 | 电池类型:1铅酸;2氢电池;3磷酸铁锂;4锰酸锂;5钴酸锂;6三元材料;7聚合物锂离子;8钛酸锂;255其他 | +| rated_capacity | Float | 是 | 额定容量,单位0.1Ah。例:600.0=60.0Ah | +| rated_voltage | Float | 是 | 额定总电压,单位0.1V。例:3600.0=360.0V | +| manufacturer | String | 是 | 电池生产厂商名称,最长4字节 | +| battery_sn | String | 是 | 电池组序号,最长4字节 | +| production_year | Number | 是 | 生产年份,1985偏移量。例:2023=1985+38 | +| production_month | Number | 是 | 生产月份,1~12 | +| production_day | Number | 是 | 生产日,1~31 | +| charge_count | Number | 是 | 电池组充电次数,0次偏移量 | +| ownership | Number | 是 | 电池产权标识:0租赁;1车自有 | +| reserved | Number | 是 | 预留位 | +| vin | String | 是 | 车辆识别码VIN,17位字符 | +| software_version | String | 是 | BMS软件版本号。格式:`byte8.byte7-byte5.byte4-byte3-byte2-byte1` | +| type | String | 是 | "request" | + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "bms info", + "gun_id": 1, + "type": "response" +} +``` + +--- + +## 8. 充电参数配置 + +> **方向**:充电桩 → 网关 → 充电桩 +> **依据**:GBT-27930 充电桩与BMS参数配置阶段报文 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "charge config", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "bms_max_cell_voltage": 4.20, + "bms_max_current": 250.0, + "bms_rated_energy": 60.0, + "bms_max_voltage": 750.0, + "bms_max_temp": 95, + "bms_soc": 85.0, + "bms_current_voltage": 680.0, + "pile_max_voltage": 750.0, + "pile_min_voltage": 200.0, + "pile_max_current": 250.0, + "pile_min_current": 10.0, + "type": "request" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "charge config" | +| transaction_id | String | 是 | 交易流水号 32位 | +| gun_id | Number | 是 | 枪编号 (1~N) | +| bms_max_cell_voltage | Float | 是 | BMS单体最高允许充电电压,单位0.01V,范围0~24V | +| bms_max_current | Float | 是 | BMS最高允许充电电流,单位0.1A,-400A偏移量 | +| bms_rated_energy | Float | 是 | BMS标称总能量,单位0.1kWh,范围0~1000kWh | +| bms_max_voltage | Float | 是 | BMS最高允许充电总电压,单位0.1V | +| bms_max_temp | Number | 是 | BMS最高允许温度,单位℃,-50℃偏移量,范围-50~200℃ | +| bms_soc | Float | 是 | BMS荷电状态SOC,单位0.1%,范围0~100% | +| bms_current_voltage | Float | 是 | BMS当前电池电压,单位0.1V | +| pile_max_voltage | Float | 是 | 电桩最高输出电压,单位0.1V | +| pile_min_voltage | Float | 是 | 电桩最低输出电压,单位0.1V | +| pile_max_current | Float | 是 | 电桩最大输出电流,单位0.1A,-400A偏移量 | +| pile_min_current | Float | 是 | 电桩最小输出电流,单位0.1A,-400A偏移量 | +| type | String | 是 | "request" | + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "charge config", + "gun_id": 1, + "type": "response" +} +``` + +--- + +## 9. 充电错误报文 + +> **方向**:充电桩 → 网关 → 充电桩 +> **依据**:GBT-27930 充电桩与BMS充电错误报文 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "charge error", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "charger_spn2560_00_timeout": 0, + "charger_spn2560_aa_timeout": 0, + "charger_time_sync_timeout": 0, + "charger_ready_timeout": 0, + "charger_status_timeout": 0, + "charger_stop_timeout": 0, + "charger_statistics_timeout": 0, + "bms_identify_timeout": 0, + "battery_param_timeout": 0, + "bms_ready_timeout": 0, + "battery_status_timeout": 0, + "battery_demand_timeout": 0, + "bms_stop_timeout": 0, + "bms_statistics_timeout": 0, + "type": "request" +} +``` + +所有超时字段取值:0=正常;1=超时;2=不可信状态 + +| 字段 | 说明 | +|------|------| +| charger_spn2560_00_timeout | 接收SPN2560=0x00的充电机辨识报文超时 | +| charger_spn2560_aa_timeout | 接收SPN2560=0xAA的充电机辨识报文超时 | +| charger_time_sync_timeout | 接收时间同步和充电机最大输出能力报文超时 | +| charger_ready_timeout | 接收充电机完成充电准备报文超时 | +| charger_status_timeout | 接收充电机充电状态报文超时 | +| charger_stop_timeout | 接收充电机中止充电报文超时 | +| charger_statistics_timeout | 接收充电机充电统计报文超时 | +| bms_identify_timeout | 接收BMS和车辆的辨识报文超时 | +| battery_param_timeout | 接收电池充电参数报文超时 | +| bms_ready_timeout | 接收BMS完成充电准备报文超时 | +| battery_status_timeout | 接收电池充电总状态报文超时 | +| battery_demand_timeout | 接收电池充电要求报文超时 | +| bms_stop_timeout | 接收BMS中止充电报文超时 | +| bms_statistics_timeout | 接收BMS充电统计报文超时 | + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "charge error", + "gun_id": 1, + "type": "response" +} +``` + +--- + +## 10. BMS中止充电 + +> **方向**:充电桩 → 网关 → 充电桩 +> **依据**:GBT-27930 充电桩与BMS充电阶段BMS中止报文 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "bms stop", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "stop_reason_soc": 0, + "stop_reason_total_voltage": 0, + "stop_reason_cell_voltage": 0, + "stop_reason_charger": 0, + "fault_insulation": 0, + "fault_connector_temp": 0, + "fault_bms_temp": 0, + "fault_connector": 0, + "fault_battery_temp": 0, + "fault_relay": 0, + "fault_voltage_detect": 0, + "fault_other": 0, + "error_current": 0, + "error_voltage": 0, + "type": "request" +} +``` + +所有字段取值:0=正常;1=中止/异常 + +| 字段 | 说明 | +|------|------| +| stop_reason_soc | 达到SOC目标值中止 | +| stop_reason_total_voltage | 达到总电压设定值中止 | +| stop_reason_cell_voltage | 达到单体电压设定值中止 | +| stop_reason_charger | 充电机主动中止 | +| fault_insulation | 绝缘故障 | +| fault_connector_temp | 输出连接器过温 | +| fault_bms_temp | BMS元件过温 | +| fault_connector | 充电连接器故障 | +| fault_battery_temp | 电池组温度过高 | +| fault_relay | 高压继电器故障 | +| fault_voltage_detect | 检测点2电压检测故障 | +| fault_other | 其他故障 | +| error_current | 电流过大 | +| error_voltage | 电压异常 | + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "bms stop", + "gun_id": 1, + "type": "response" +} +``` + +--- + +## 11. 充电机中止充电 + +> **方向**:充电桩 → 网关 → 充电桩 +> **依据**:GBT-27930 充电桩与BMS充电阶段充电机中止报文 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "charger stop", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "stop_reason_condition": 0, + "stop_reason_manual": 0, + "stop_reason_abnormal": 0, + "stop_reason_bms": 0, + "fault_charger_temp": 0, + "fault_connector": 0, + "fault_internal_temp": 0, + "fault_power_transfer": 0, + "fault_emergency": 0, + "fault_other": 0, + "error_current": 0, + "error_voltage": 0, + "type": "request" +} +``` + +所有字段取值:0=正常;1=中止/异常 + +| 字段 | 说明 | +|------|------| +| stop_reason_condition | 达到充电机设定的条件 | +| stop_reason_manual | 人工中止 | +| stop_reason_abnormal | 异常中止 | +| stop_reason_bms | BMS主动中止 | +| fault_charger_temp | 充电机过温 | +| fault_connector | 充电连接器故障 | +| fault_internal_temp | 充电机内部过温 | +| fault_power_transfer | 所需电量不能传送 | +| fault_emergency | 充电机急停 | +| fault_other | 其他故障 | +| error_current | 电流不匹配 | +| error_voltage | 电压异常 | + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "charger stop", + "gun_id": 1, + "type": "response" +} +``` + +--- + +## 12. 充电过程BMS需求与充电机输出 + +> **方向**:充电桩 → 网关 → 充电桩 +> **周期**:15 秒 +> **依据**:GBT-27930 充电过程BMS需求、充电机输出报文 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "charge process real", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "bms_voltage_demand": 680.0, + "bms_current_demand": 250.0, + "bms_charge_mode": 2, + "bms_voltage_measure": 678.5, + "bms_current_measure": 248.0, + "bms_max_cell_voltage": 4.15, + "bms_max_cell_group": 3, + "bms_soc": 85, + "bms_remain_time": 30, + "pile_voltage_output": 680.0, + "pile_current_output": 250.0, + "charge_time": 45, + "type": "request" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "charge process real" | +| transaction_id | String | 是 | 交易流水号 32位 | +| gun_id | Number | 是 | 枪编号 (1~N) | +| bms_voltage_demand | Float | 是 | BMS电压需求,单位0.1V | +| bms_current_demand | Float | 是 | BMS电流需求,单位0.1A,-400A偏移量 | +| bms_charge_mode | Number | 是 | 充电模式:1恒压;2恒流 | +| bms_voltage_measure | Float | 是 | BMS充电电压测量值,单位0.1V | +| bms_current_measure | Float | 是 | BMS充电电流测量值,单位0.1A,-400A偏移量 | +| bms_max_cell_voltage | Float | 是 | 最高单体蓄电池电压,单位0.01V,范围0~24V | +| bms_max_cell_group | Number | 是 | 最高单体电压所在组号,范围0~15 | +| bms_soc | Number | 是 | 当前SOC,单位%,范围0~100 | +| bms_remain_time | Number | 是 | 估算剩余充电时间,单位分钟,范围0~600 | +| pile_voltage_output | Float | 是 | 电桩电压输出值,单位0.1V | +| pile_current_output | Float | 是 | 电桩电流输出值,单位0.1A,-400A偏移量 | +| charge_time | Number | 是 | 累计充电时间,单位分钟,范围0~600 | +| type | String | 是 | "request" | + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "charge process real", + "gun_id": 1, + "type": "response" +} +``` + +--- + +## 13. 充电过程BMS信息 + +> **方向**:充电桩 → 网关 → 充电桩 +> **周期**:15 秒 +> **依据**:GBT-27930 充电过程BMS信息报文 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "bms info real", + "transaction_id": "32010200000000111511161555350260", + "gun_id": 1, + "max_cell_voltage_no": 128, + "max_battery_temp": 45, + "max_temp_point_no": 8, + "min_battery_temp": 25, + "min_temp_point_no": 3, + "cell_voltage_status": 0, + "soc_status": 0, + "charge_current_status": 0, + "battery_temp_status": 0, + "insulation_status": 0, + "connector_status": 0, + "charge_enable": 1, + "type": "request" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "bms info real" | +| transaction_id | String | 是 | 交易流水号 32位 | +| gun_id | Number | 是 | 枪编号 (1~N) | +| max_cell_voltage_no | Number | 是 | 最高单体电压所在编号,1偏移量,范围1~256 | +| max_battery_temp | Number | 是 | 最高电池温度,单位℃,-50℃偏移量,范围-50~200℃ | +| max_temp_point_no | Number | 是 | 最高温度检测点编号,1偏移量,范围1~128 | +| min_battery_temp | Number | 是 | 最低电池温度,单位℃,-50℃偏移量 | +| min_temp_point_no | Number | 是 | 最低温度检测点编号,1偏移量 | +| cell_voltage_status | Number | 是 | 单体电压过高/过低:0正常;1过高;2过低 | +| soc_status | Number | 是 | SOC过高/过低:0正常;1过高;2过低 | +| charge_current_status | Number | 是 | 充电过电流:0正常;1过流;2不可信 | +| battery_temp_status | Number | 是 | 电池温度过高:0正常;1过高;2不可信 | +| insulation_status | Number | 是 | 绝缘状态:0正常;1异常;2不可信 | +| connector_status | Number | 是 | 输出连接器连接状态:0正常;1异常;2不可信 | +| charge_enable | Number | 是 | 充电禁止:0禁止;1允许 | +| type | String | 是 | "request" | + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "bms info real", + "gun_id": 1, + "type": "response" +} +``` + +--- + +## 14. 结算账单上传 + +> **方向**:充电桩 → 网关 → 充电桩 + +充电结束生成结算账单上传。若未收到响应,间隔30秒重试一次,最多重试3次。收到成功响应后,充电桩本地删除该账单。 + +**Request (充电桩 → 网关):** + +```json +{ + "id": 1, + "cmd": "settlement bill", + "transaction_id": "55031412782305012018061910262392", + "gun_id": 1, + "start_time": 1584349487, + "end_time": 1584349487, + "billing": [ + [1.30000, 0.0000, 0.0000, 0.0000], + [1.30000, 0.0000, 0.0000, 0.0000], + [1.30000, 0.0000, 0.0000, 0.0000], + [1.30000, 0.0000, 0.0000, 0.0000] + ], + "meter_start": 0.0000, + "meter_end": 0.0000, + "total_energy": 0.0000, + "total_energy_loss": 0.0000, + "total_amount": 0.0000, + "vin": "", + "trade_type": 2, + "trade_time": 1584349487, + "stop_reason": 0, + "card_physical_id": "D14B0A54", + "type": "request" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "settlement bill" | +| transaction_id | String | 是 | 交易流水号 32位 | +| gun_id | Number | 是 | 枪编号 (1~N) | +| start_time | Number | 是 | 充电开始时间,Unix时间戳(秒) | +| end_time | Number | 是 | 充电结束时间,Unix时间戳(秒) | +| billing | Array | 是 | 尖峰平谷计费数组,4行,顺序:[尖,峰,平,谷],每行:[单价(.5f), 电量(.4f), 计损电量(.4f), 金额(.4f)] | +| meter_start | Float | 是 | 电表总起值(kWh),四位小数 | +| meter_end | Float | 是 | 电表总止值(kWh),四位小数 | +| total_energy | Float | 是 | 总电量(kWh),四位小数 | +| total_energy_loss | Float | 是 | 计损总电量(kWh),四位小数 | +| total_amount | Float | 是 | 消费金额(元),含电费和服务费,四位小数 | +| vin | String | 是 | 电动汽车VIN码,17位ASCII | +| trade_type | Number | 是 | 交易标识:1=app启动;2=卡启动;4=离线卡启动;5=VIN码启动 | +| trade_time | Number | 是 | 交易时间,Unix时间戳(秒) | +| stop_reason | Number | 是 | 停止原因,见云快充附录13.1 | +| card_physical_id | String | 是 | 物理卡号,默认为空 | +| type | String | 是 | "request" | + +**billing 数组格式:** + +``` +[尖, 峰, 平, 谷] ← 4行,固定顺序 + │ + └─ [单价(.5f), 电量(.4f), 计损电量(.4f), 金额(.4f)] +``` + +**Response (网关 → 充电桩):** + +```json +{ + "id": 1, + "cmd": "settlement bill", + "transaction_id": "55031412782305012018061910262392", + "gun_id": 1, + "result": 1, + "type": "response" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Number | 是 | 桩编码 (1~6) | +| cmd | String | 是 | "settlement bill" | +| transaction_id | String | 是 | 交易流水号 32位 | +| gun_id | Number | 是 | 枪编号 (1~N) | +| result | Number | 是 | 账单上传结果:1=成功;0=失败 | +| type | String | 是 | "response" | + +> **重试机制**:若未收到响应,间隔30秒重试一次,最多重试3次。收到成功响应后,本账单在充电桩本地删除。 + +--- + +## 附录:协议汇总表 + +| 编号 | cmd | 请求方 | 响应方 | 触发方式 | +|------|-----|--------|--------|----------| +| 1 | online | 充电桩 | 网关 | 上电 | +| 2 | heartbeat | 充电桩 | 网关 | 5~10s周期 | +| 3 | start charging | 网关 | 充电桩 | 网关下发 | +| 4 | end charging | 网关 | 充电桩 | 网关下发 | +| 5 | proactive end charging | 充电桩 | 网关 | 桩主动 | +| 6 | realtime data | 充电桩 | 网关 | 周期上送 | +| 7 | bms info | 充电桩 | 网关 | 桩主动 | +| 8 | charge config | 充电桩 | 网关 | 桩主动 | +| 9 | charge error | 充电桩 | 网关 | 桩主动 | +| 10 | bms stop | 充电桩 | 网关 | 桩主动 | +| 11 | charger stop | 充电桩 | 网关 | 桩主动 | +| 12 | charge process real | 充电桩 | 网关 | 15s周期 | +| 13 | bms info real | 充电桩 | 网关 | 15s周期 | +| 14 | settlement bill | 充电桩 | 网关 | 充电结束 | diff --git a/README.md b/README.md index 58ab754..f303404 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# BR_YKC - +# 说明 +文档请见/Doc 目录 diff --git a/上位机/YKC/.vs/YKC.csproj.dtbcache.json b/上位机/YKC/.vs/YKC.csproj.dtbcache.json new file mode 100644 index 0000000..bdcca88 --- /dev/null +++ b/上位机/YKC/.vs/YKC.csproj.dtbcache.json @@ -0,0 +1 @@ +{"RootPath":"C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC","ProjectFileName":"YKC.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"App.xaml.cs"},{"SourceFile":"MainWindow.xaml.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"Properties\\Resources.Designer.cs"},{"SourceFile":"Properties\\Settings.Designer.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.7.2.AssemblyAttributes.cs"},{"SourceFile":"C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\obj\\Debug\\MainWindow.g.cs"},{"SourceFile":"C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\obj\\Debug\\App.g.cs"}],"References":[{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\Microsoft.CSharp.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\mscorlib.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\PresentationCore.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\PresentationFramework.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Core.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Data.DataSetExtensions.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Data.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Net.Http.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Xaml.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Xml.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Xml.Linq.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\WindowsBase.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""}],"Analyzers":[],"Outputs":[{"OutputItemFullPath":"C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\bin\\Debug\\YKC.exe","OutputItemRelativePath":"YKC.exe"},{"OutputItemFullPath":"","OutputItemRelativePath":""}],"CopyToOutputEntries":[]} \ No newline at end of file diff --git a/上位机/YKC/.vs/YKC.slnx/FileContentIndex/0aca7fde-0d40-486e-ae92-b800e35e62f0.vsidx b/上位机/YKC/.vs/YKC.slnx/FileContentIndex/0aca7fde-0d40-486e-ae92-b800e35e62f0.vsidx new file mode 100644 index 0000000..a466a06 Binary files /dev/null and b/上位机/YKC/.vs/YKC.slnx/FileContentIndex/0aca7fde-0d40-486e-ae92-b800e35e62f0.vsidx differ diff --git a/上位机/YKC/.vs/YKC.slnx/FileContentIndex/35c09aa0-d937-4364-93ab-6bb3ec122e44.vsidx b/上位机/YKC/.vs/YKC.slnx/FileContentIndex/35c09aa0-d937-4364-93ab-6bb3ec122e44.vsidx new file mode 100644 index 0000000..31de77f Binary files /dev/null and b/上位机/YKC/.vs/YKC.slnx/FileContentIndex/35c09aa0-d937-4364-93ab-6bb3ec122e44.vsidx differ diff --git a/上位机/YKC/.vs/YKC.slnx/FileContentIndex/3d407e8b-8c67-480c-816e-75c618e30e22.vsidx b/上位机/YKC/.vs/YKC.slnx/FileContentIndex/3d407e8b-8c67-480c-816e-75c618e30e22.vsidx new file mode 100644 index 0000000..427cf80 Binary files /dev/null and b/上位机/YKC/.vs/YKC.slnx/FileContentIndex/3d407e8b-8c67-480c-816e-75c618e30e22.vsidx differ diff --git a/上位机/YKC/.vs/YKC.slnx/FileContentIndex/ebba84a0-37b5-4a93-ac62-3624a08a821d.vsidx b/上位机/YKC/.vs/YKC.slnx/FileContentIndex/ebba84a0-37b5-4a93-ac62-3624a08a821d.vsidx new file mode 100644 index 0000000..c8481cb Binary files /dev/null and b/上位机/YKC/.vs/YKC.slnx/FileContentIndex/ebba84a0-37b5-4a93-ac62-3624a08a821d.vsidx differ diff --git a/上位机/YKC/.vs/YKC.slnx/FileContentIndex/ff341f20-79f3-4807-b475-8bbe9844e0df.vsidx b/上位机/YKC/.vs/YKC.slnx/FileContentIndex/ff341f20-79f3-4807-b475-8bbe9844e0df.vsidx new file mode 100644 index 0000000..e069d8a Binary files /dev/null and b/上位机/YKC/.vs/YKC.slnx/FileContentIndex/ff341f20-79f3-4807-b475-8bbe9844e0df.vsidx differ diff --git a/上位机/YKC/.vs/YKC.slnx/v18/.suo b/上位机/YKC/.vs/YKC.slnx/v18/.suo new file mode 100644 index 0000000..eee8aa5 Binary files /dev/null and b/上位机/YKC/.vs/YKC.slnx/v18/.suo differ diff --git a/上位机/YKC/.vs/YKC.slnx/v18/DocumentLayout.backup.json b/上位机/YKC/.vs/YKC.slnx/v18/DocumentLayout.backup.json new file mode 100644 index 0000000..0bf4b08 --- /dev/null +++ b/上位机/YKC/.vs/YKC.slnx/v18/DocumentLayout.backup.json @@ -0,0 +1,228 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\realtimepage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\realtimepage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\gatewaypage.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\gatewaypage.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\realtimepage.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\realtimepage.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\gatewaypage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\gatewaypage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\dashboardpage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\dashboardpage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\chargerpage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\chargerpage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\AppData\\Local\\Temp\\.vsdbgsrc\\3714f74b82eacc6cf8dcf1e32980b0908d4f8b447d25d4eb08ff1424a7b57c02\\ResourcePart.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\app.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:app.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\app.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:app.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{00000000-0000-0000-0000-000000000000}|\u003CSolution\u003E|YKC||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "RealtimePage.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\RealtimePage.xaml", + "RelativeDocumentMoniker": "Pages\\RealtimePage.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\RealtimePage.xaml", + "RelativeToolTip": "Pages\\RealtimePage.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-20T03:56:55.66Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "RealtimePage.xaml.cs", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\RealtimePage.xaml.cs", + "RelativeDocumentMoniker": "Pages\\RealtimePage.xaml.cs", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\RealtimePage.xaml.cs", + "RelativeToolTip": "Pages\\RealtimePage.xaml.cs", + "ViewState": "AgIAAFcAAAAAAAAAAAAowH8AAAAQAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-20T03:48:04.174Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "GatewayPage.xaml.cs", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\GatewayPage.xaml.cs", + "RelativeDocumentMoniker": "Pages\\GatewayPage.xaml.cs", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\GatewayPage.xaml.cs", + "RelativeToolTip": "Pages\\GatewayPage.xaml.cs", + "ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-20T03:56:52.729Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "DashboardPage.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\DashboardPage.xaml", + "RelativeDocumentMoniker": "Pages\\DashboardPage.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\DashboardPage.xaml", + "RelativeToolTip": "Pages\\DashboardPage.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-20T03:55:04.048Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "ChargerPage.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\ChargerPage.xaml", + "RelativeDocumentMoniker": "Pages\\ChargerPage.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\ChargerPage.xaml", + "RelativeToolTip": "Pages\\ChargerPage.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-20T03:55:01.467Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 9, + "Title": "MainWindow.xaml.cs", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\MainWindow.xaml.cs", + "RelativeDocumentMoniker": "MainWindow.xaml.cs", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\MainWindow.xaml.cs", + "RelativeToolTip": "MainWindow.xaml.cs", + "ViewState": "AgIAADMAAAAAAAAAAAAewEoAAAAMAAAAAAAAAA==", + "Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJ7SURBVDhP7ZQ9aBNhGMef9y7t2eH0TOPHnbnzzmDjkpTqNSEdShDBpRbBQbEI/bCSRVA7iFWk1OpS0CGDH5OlgQgZihRioTgU0VzTEKhSTeLg2aYBLUIgzfUj17wuXptcQUFdBH/j83//P953eF4AE0eGZljXkLL4ZErFsY9LA\u002Bb8VyDz4NGUyiKARDJb5A7srMkc27Wcjr98DpFIBLxeL/A8Hx4cHAybewbkwZuvB9aPXvDrcqcfPJ3\u002BN2rBX1dDtMTUZeqbptfr\u002BgYqZd/G5ubmzrAs66Ioql6W5dL09PQ7swwAgGRaL/YVS5jTcZkDBBwug50kCelLoWQBQIAttbHJh7f6McadVqs1RdP0HoRQk8/n\u002B\u002BR0OnOzs7N6pXDbk1\u002B8/8oifSMxMrPECUzt8mmXdezsCfk6QRAJh8Nxw\u002BPxHNI07TIA6ABwslwufwgGg2tGn6jWAdyb\u002BAx3J7PgE2k43rD7Md5Re8XIenp6HnR3dwMAXAWAeoTQBEKotbJfdcPh4eHmdUz0TerusXMtDVoTX5f2OvZment7WYvFklhZWeHm5\u002BczuVwuzzCM50etXVGUccNh2dIBKIqyjyCI1v3kzLVA/7OcMW9sbCwUi8X70WiUVlUVAABWV1dfYYwvEcS2R24hSVKbKIo5nuc5c2ZGEARWFMVFSZJOVc5/ov89/gv/nH9MSFEU2Gw2aygUeppOp41N2EYqlWoOhUIjgiBYGYapyqpWLxAItJEkOW632yEej4eTyWSmMjdwu92HZVk\u002Bn8/nQdf19mAwuLl6VcLR0dFmTdNuRyIRWFhYgLW1zU\u002BkCpIkwWazQVdXF9A0faejoyNuPvPX\u002BA5Fb\u002BAHZWstowAAAABJRU5ErkJggg==", + "WhenOpened": "2026-05-13T09:04:45.364Z" + }, + { + "$type": "Document", + "DocumentIndex": 11, + "Title": "App.xaml.cs", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.xaml.cs", + "RelativeDocumentMoniker": "App.xaml.cs", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.xaml.cs", + "RelativeToolTip": "App.xaml.cs", + "ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==", + "Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJ7SURBVDhP7ZQ9aBNhGMef9y7t2eH0TOPHnbnzzmDjkpTqNSEdShDBpRbBQbEI/bCSRVA7iFWk1OpS0CGDH5OlgQgZihRioTgU0VzTEKhSTeLg2aYBLUIgzfUj17wuXptcQUFdBH/j83//P953eF4AE0eGZljXkLL4ZErFsY9LA\u002Bb8VyDz4NGUyiKARDJb5A7srMkc27Wcjr98DpFIBLxeL/A8Hx4cHAybewbkwZuvB9aPXvDrcqcfPJ3\u002BN2rBX1dDtMTUZeqbptfr\u002BgYqZd/G5ubmzrAs66Ioql6W5dL09PQ7swwAgGRaL/YVS5jTcZkDBBwug50kCelLoWQBQIAttbHJh7f6McadVqs1RdP0HoRQk8/n\u002B\u002BR0OnOzs7N6pXDbk1\u002B8/8oifSMxMrPECUzt8mmXdezsCfk6QRAJh8Nxw\u002BPxHNI07TIA6ABwslwufwgGg2tGn6jWAdyb\u002BAx3J7PgE2k43rD7Md5Re8XIenp6HnR3dwMAXAWAeoTQBEKotbJfdcPh4eHmdUz0TerusXMtDVoTX5f2OvZment7WYvFklhZWeHm5\u002BczuVwuzzCM50etXVGUccNh2dIBKIqyjyCI1v3kzLVA/7OcMW9sbCwUi8X70WiUVlUVAABWV1dfYYwvEcS2R24hSVKbKIo5nuc5c2ZGEARWFMVFSZJOVc5/ov89/gv/nH9MSFEU2Gw2aygUeppOp41N2EYqlWoOhUIjgiBYGYapyqpWLxAItJEkOW632yEej4eTyWSmMjdwu92HZVk\u002Bn8/nQdf19mAwuLl6VcLR0dFmTdNuRyIRWFhYgLW1zU\u002BkCpIkwWazQVdXF9A0faejoyNuPvPX\u002BA5Fb\u002BAHZWstowAAAABJRU5ErkJggg==", + "WhenOpened": "2026-05-13T09:10:18.727Z" + }, + { + "$type": "Document", + "DocumentIndex": 10, + "Title": "App.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.xaml", + "RelativeDocumentMoniker": "App.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.xaml", + "RelativeToolTip": "App.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-13T09:08:55.359Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 6, + "Title": "MainWindow.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\MainWindow.xaml", + "RelativeDocumentMoniker": "MainWindow.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\MainWindow.xaml", + "RelativeToolTip": "MainWindow.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-13T09:04:45.868Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "GatewayPage.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\GatewayPage.xaml", + "RelativeDocumentMoniker": "Pages\\GatewayPage.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\GatewayPage.xaml", + "RelativeToolTip": "Pages\\GatewayPage.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-20T03:55:06.415Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 12, + "Title": "YKC", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\YKC.csproj", + "RelativeDocumentMoniker": "YKC.csproj", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\YKC.csproj", + "RelativeToolTip": "YKC.csproj", + "Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAALUSURBVDhP5ZRfSFNRHMe/5267zrur003TDJrTQJx/yGHRCMFAM3CTRHqoJ6EyiHyIyDdBHwoSRz340OpFihYMwzCD6GnkSOthD7aFuzhMJMUY5vXavNe7u9NLylwpPQZ94Lz8fr/P9xwOhwP8dxAA8Pl8J2ZmZkqmp6ehKEr2zIF0dnbCbrcLvb29AgDoAUCSpH69Xu/heV6RZXktW/oThBCd2Wy2Ukp1siwPAhgAAAYARkdHUVxcDK/XO6VpWuPfrK6urraRkZGEKIoIBAJ7d7PZbBPt7e3\u002BWCx2cm9nfwRByBEEodXlcn2orKwc2KkT/AoEEO5\u002B2u1PqslL/rknaDl6FscKKoL9TYNBR8DBM5J2jdGTV9o2LWOAsk9XY/5Md3FxcQAAdABQUFBwEcCK5Uy\u002BIqUkn8VoaTYZuOat1NbidlvqM01uuxVNvbMp/1BSVG2hhLQfOV\u002B6kNtpWkYQFwCsiKIYxM4d7jC\u002B8BKhr1PpW87b3yilK1PL7ySqqvVpiuHvypp5U5VurCtih7S9UQ9Kh/NSeeZMH9mBALCurCfG4i/OMZqhUaV4tMEkQ0m62Zam6QQFuQkCn6IpU5Tq2yLmSCLb/y2QZ03mjnLPPU2vPmQJcfOUr\u002BNgGiJgzCD0Oig8rI6tA9GGHKLj4BO6Slw4XtSQ8/rLZCtD4XFYaqp0KU0EQ2bzWF7NYXLinIFbztVxIkh6ViOamukjO/DU4dOr1ZbqyTEhMElBJmsKa4XZnjmBUP3dPEP\u002BeKmx5IGVLXzMs6Znkcsxb\u002BxKTMr0dykvL59oaGgYjkQiluzeflBKmfn5\u002BUNVVVVvbTbb7jtkAIDjOLjd7h6WZe/vsQ4gHo8XaZr2pra2timzTgCgr69vQhRFz9LS0mo0Gv2YObAfHMcZnU5nk9VqNRoMhkGv1zuAnc/Bbrc/D4VC4Wg0mu3tiyzLCIfD791uNyoqKoLZ/X\u002BXn25ERIg8ycqdAAAAAElFTkSuQmCC", + "WhenOpened": "2026-05-13T09:08:51.991Z" + }, + { + "$type": "Document", + "DocumentIndex": 8, + "Title": "App.config", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.config", + "RelativeDocumentMoniker": "App.config", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.config", + "RelativeToolTip": "App.config", + "ViewState": "AgIAAAAAAAAAAAAAAADwvwUAAAAQAAAAAAAAAA==", + "Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOhSURBVDhPrZRPSCNXHMe/LxNjTbquSYiLSYwV/1MwEEwFIWsOBQ/\u002BxS6ElUV6qiIG3ZNQSrGswQotu4i3QqkHXTCIYbeHFi9u2Wo1YhSNh7mkQaNpzWSMzDATNXm9OKIj2B76gXd53\u002B/vw\u002BM9eMD/DFFvzM3NGQG8DAaDpv39fWSz2Vu50\u002BlEY2NjeGJi4sWt4ApGveFwOIyJRGLK4XA0GY3G41gs9geA46vltVgsLSaTydbc3Fzo8Xj2VldXz2/O3zmhy\u002BUqA7A5ODiY8Hq9r2pra\u002BeVrKKi4k1lZWWd0\u002BnMAKgC8JxS\u002Buv09PRfSkdzbboilUohnU5jcnLyxU2ZQiaTeVtWVvYdpfSSEPIjIaRtaGjoQyW/I/w3Ojs7v\u002Bjr6/uMENJGKU0BeKnVageUXHu7DgQCAVBKAQD9/f23svb2diQSiQfDw8Ot0WjUaDKZHjIM8wGl9IHSuX6UcDjsbWpq\u002BnxmZsZrtVpbCgoKCn0\u002BH7e0tPSn0nny5Alisdje1tbWZj6fPxBF8XdBEKyCIOxlMpkV3HyUcDjcF4lERoPBoJvnebhcLpSXl8\u002BXlpa\u002BGhgYCCs9NRUVFW8AbMXj8XEA0ITD4TKWZQvdbve8wWD4sqen5\u002B\u002BLi4vc8vIydnd3\u002BwRB\u002BFotuQ8NIWQzk8k8BoDz8/P3sViszWKxpPR6PaLRKBYWFtQz98Kk0\u002Bnvj46O6rq7u8Xe3t6Cqqqqb1dWVmp5ntfKsgxJklie51\u002BrBxVKSkqeAjhW7pBhGGZclmVbKpUyb29vf3xwcNCzs7OjFUURVwWW47j/LNQ2NDSAZVkwDONNJpM4OTlBNpsFpRRarRZFRUWPRkdHP\u002BV5/v3s7KysFqrReL3eY6vVmhVFEYlEArIsgxACQgguLy\u002Bh0\u002BnckiTNGQyGer/fX6gWqNHkcrmmjo6O31pbW1FcXAyNRgOz2QydTgcA4DgOa2tr5lwu9wsh5LFaoEbj9/uP9Hr9VzqdrosQ0kUp7WIYpsvj8WzU1NQgn89DEAQmEok84jhuYmRk5CkAxONxI8uyP7W0tHxiMpmuhQwAhEKhxMbGBptMJtnT01P28PCQ9fl8IqXUrNFoPuI4DqIoglJqOzs728vn80ehUOi5LMvP9Hq9yW63v1tfX1/BfZ/D2NjY6\u002Brq6h/q6\u002BvDdrsdDMNAkiQIggAAD3mer1tcXHxnMBh\u002BdrvdrDJ35z9UMzU11SFJ0ttgMAi32w2bzfZNIBAYV/cU/gFl85csP2dGWAAAAABJRU5ErkJggg==", + "WhenOpened": "2026-05-13T09:08:54.548Z" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "ResourcePart.cs", + "DocumentMoniker": "C:\\Users\\Administrator\\AppData\\Local\\Temp\\.vsdbgsrc\\3714f74b82eacc6cf8dcf1e32980b0908d4f8b447d25d4eb08ff1424a7b57c02\\ResourcePart.cs", + "RelativeDocumentMoniker": "..\\..\\..\\..\\AppData\\Local\\Temp\\.vsdbgsrc\\3714f74b82eacc6cf8dcf1e32980b0908d4f8b447d25d4eb08ff1424a7b57c02\\ResourcePart.cs", + "ToolTip": "C:\\Users\\Administrator\\AppData\\Local\\Temp\\.vsdbgsrc\\3714f74b82eacc6cf8dcf1e32980b0908d4f8b447d25d4eb08ff1424a7b57c02\\ResourcePart.cs [\u53EA\u8BFB]", + "RelativeToolTip": "..\\..\\..\\..\\AppData\\Local\\Temp\\.vsdbgsrc\\3714f74b82eacc6cf8dcf1e32980b0908d4f8b447d25d4eb08ff1424a7b57c02\\ResourcePart.cs [\u53EA\u8BFB]", + "ViewState": "AgIAABMAAAAAAAAAAAAowCcAAAADAAAAAQAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-13T09:19:37.213Z", + "EditorCaption": " [\u53EA\u8BFB]" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/上位机/YKC/.vs/YKC.slnx/v18/DocumentLayout.json b/上位机/YKC/.vs/YKC.slnx/v18/DocumentLayout.json new file mode 100644 index 0000000..0bf4b08 --- /dev/null +++ b/上位机/YKC/.vs/YKC.slnx/v18/DocumentLayout.json @@ -0,0 +1,228 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\realtimepage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\realtimepage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\gatewaypage.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\gatewaypage.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\realtimepage.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\realtimepage.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\gatewaypage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\gatewaypage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\dashboardpage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\dashboardpage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\pages\\chargerpage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:pages\\chargerpage.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|c:\\users\\administrator\\pycharmprojects\\pythonproject\\c#\\ykc\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\AppData\\Local\\Temp\\.vsdbgsrc\\3714f74b82eacc6cf8dcf1e32980b0908d4f8b447d25d4eb08ff1424a7b57c02\\ResourcePart.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\app.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:app.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\app.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:app.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9F34DD1F-FB6D-4E13-9270-13C7A9A87AAA}|YKC.csproj|solutionrelative:app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{00000000-0000-0000-0000-000000000000}|\u003CSolution\u003E|YKC||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "RealtimePage.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\RealtimePage.xaml", + "RelativeDocumentMoniker": "Pages\\RealtimePage.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\RealtimePage.xaml", + "RelativeToolTip": "Pages\\RealtimePage.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-20T03:56:55.66Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "RealtimePage.xaml.cs", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\RealtimePage.xaml.cs", + "RelativeDocumentMoniker": "Pages\\RealtimePage.xaml.cs", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\RealtimePage.xaml.cs", + "RelativeToolTip": "Pages\\RealtimePage.xaml.cs", + "ViewState": "AgIAAFcAAAAAAAAAAAAowH8AAAAQAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-20T03:48:04.174Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "GatewayPage.xaml.cs", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\GatewayPage.xaml.cs", + "RelativeDocumentMoniker": "Pages\\GatewayPage.xaml.cs", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\GatewayPage.xaml.cs", + "RelativeToolTip": "Pages\\GatewayPage.xaml.cs", + "ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-20T03:56:52.729Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "DashboardPage.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\DashboardPage.xaml", + "RelativeDocumentMoniker": "Pages\\DashboardPage.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\DashboardPage.xaml", + "RelativeToolTip": "Pages\\DashboardPage.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-20T03:55:04.048Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "ChargerPage.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\ChargerPage.xaml", + "RelativeDocumentMoniker": "Pages\\ChargerPage.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\ChargerPage.xaml", + "RelativeToolTip": "Pages\\ChargerPage.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-20T03:55:01.467Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 9, + "Title": "MainWindow.xaml.cs", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\MainWindow.xaml.cs", + "RelativeDocumentMoniker": "MainWindow.xaml.cs", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\MainWindow.xaml.cs", + "RelativeToolTip": "MainWindow.xaml.cs", + "ViewState": "AgIAADMAAAAAAAAAAAAewEoAAAAMAAAAAAAAAA==", + "Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJ7SURBVDhP7ZQ9aBNhGMef9y7t2eH0TOPHnbnzzmDjkpTqNSEdShDBpRbBQbEI/bCSRVA7iFWk1OpS0CGDH5OlgQgZihRioTgU0VzTEKhSTeLg2aYBLUIgzfUj17wuXptcQUFdBH/j83//P953eF4AE0eGZljXkLL4ZErFsY9LA\u002Bb8VyDz4NGUyiKARDJb5A7srMkc27Wcjr98DpFIBLxeL/A8Hx4cHAybewbkwZuvB9aPXvDrcqcfPJ3\u002BN2rBX1dDtMTUZeqbptfr\u002BgYqZd/G5ubmzrAs66Ioql6W5dL09PQ7swwAgGRaL/YVS5jTcZkDBBwug50kCelLoWQBQIAttbHJh7f6McadVqs1RdP0HoRQk8/n\u002B\u002BR0OnOzs7N6pXDbk1\u002B8/8oifSMxMrPECUzt8mmXdezsCfk6QRAJh8Nxw\u002BPxHNI07TIA6ABwslwufwgGg2tGn6jWAdyb\u002BAx3J7PgE2k43rD7Md5Re8XIenp6HnR3dwMAXAWAeoTQBEKotbJfdcPh4eHmdUz0TerusXMtDVoTX5f2OvZment7WYvFklhZWeHm5\u002BczuVwuzzCM50etXVGUccNh2dIBKIqyjyCI1v3kzLVA/7OcMW9sbCwUi8X70WiUVlUVAABWV1dfYYwvEcS2R24hSVKbKIo5nuc5c2ZGEARWFMVFSZJOVc5/ov89/gv/nH9MSFEU2Gw2aygUeppOp41N2EYqlWoOhUIjgiBYGYapyqpWLxAItJEkOW632yEej4eTyWSmMjdwu92HZVk\u002Bn8/nQdf19mAwuLl6VcLR0dFmTdNuRyIRWFhYgLW1zU\u002BkCpIkwWazQVdXF9A0faejoyNuPvPX\u002BA5Fb\u002BAHZWstowAAAABJRU5ErkJggg==", + "WhenOpened": "2026-05-13T09:04:45.364Z" + }, + { + "$type": "Document", + "DocumentIndex": 11, + "Title": "App.xaml.cs", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.xaml.cs", + "RelativeDocumentMoniker": "App.xaml.cs", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.xaml.cs", + "RelativeToolTip": "App.xaml.cs", + "ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==", + "Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJ7SURBVDhP7ZQ9aBNhGMef9y7t2eH0TOPHnbnzzmDjkpTqNSEdShDBpRbBQbEI/bCSRVA7iFWk1OpS0CGDH5OlgQgZihRioTgU0VzTEKhSTeLg2aYBLUIgzfUj17wuXptcQUFdBH/j83//P953eF4AE0eGZljXkLL4ZErFsY9LA\u002Bb8VyDz4NGUyiKARDJb5A7srMkc27Wcjr98DpFIBLxeL/A8Hx4cHAybewbkwZuvB9aPXvDrcqcfPJ3\u002BN2rBX1dDtMTUZeqbptfr\u002BgYqZd/G5ubmzrAs66Ioql6W5dL09PQ7swwAgGRaL/YVS5jTcZkDBBwug50kCelLoWQBQIAttbHJh7f6McadVqs1RdP0HoRQk8/n\u002B\u002BR0OnOzs7N6pXDbk1\u002B8/8oifSMxMrPECUzt8mmXdezsCfk6QRAJh8Nxw\u002BPxHNI07TIA6ABwslwufwgGg2tGn6jWAdyb\u002BAx3J7PgE2k43rD7Md5Re8XIenp6HnR3dwMAXAWAeoTQBEKotbJfdcPh4eHmdUz0TerusXMtDVoTX5f2OvZment7WYvFklhZWeHm5\u002BczuVwuzzCM50etXVGUccNh2dIBKIqyjyCI1v3kzLVA/7OcMW9sbCwUi8X70WiUVlUVAABWV1dfYYwvEcS2R24hSVKbKIo5nuc5c2ZGEARWFMVFSZJOVc5/ov89/gv/nH9MSFEU2Gw2aygUeppOp41N2EYqlWoOhUIjgiBYGYapyqpWLxAItJEkOW632yEej4eTyWSmMjdwu92HZVk\u002Bn8/nQdf19mAwuLl6VcLR0dFmTdNuRyIRWFhYgLW1zU\u002BkCpIkwWazQVdXF9A0faejoyNuPvPX\u002BA5Fb\u002BAHZWstowAAAABJRU5ErkJggg==", + "WhenOpened": "2026-05-13T09:10:18.727Z" + }, + { + "$type": "Document", + "DocumentIndex": 10, + "Title": "App.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.xaml", + "RelativeDocumentMoniker": "App.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.xaml", + "RelativeToolTip": "App.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-13T09:08:55.359Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 6, + "Title": "MainWindow.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\MainWindow.xaml", + "RelativeDocumentMoniker": "MainWindow.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\MainWindow.xaml", + "RelativeToolTip": "MainWindow.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-13T09:04:45.868Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "GatewayPage.xaml", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\GatewayPage.xaml", + "RelativeDocumentMoniker": "Pages\\GatewayPage.xaml", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\Pages\\GatewayPage.xaml", + "RelativeToolTip": "Pages\\GatewayPage.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-05-20T03:55:06.415Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 12, + "Title": "YKC", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\YKC.csproj", + "RelativeDocumentMoniker": "YKC.csproj", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\YKC.csproj", + "RelativeToolTip": "YKC.csproj", + "Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAALUSURBVDhP5ZRfSFNRHMe/5267zrur003TDJrTQJx/yGHRCMFAM3CTRHqoJ6EyiHyIyDdBHwoSRz340OpFihYMwzCD6GnkSOthD7aFuzhMJMUY5vXavNe7u9NLylwpPQZ94Lz8fr/P9xwOhwP8dxAA8Pl8J2ZmZkqmp6ehKEr2zIF0dnbCbrcLvb29AgDoAUCSpH69Xu/heV6RZXktW/oThBCd2Wy2Ukp1siwPAhgAAAYARkdHUVxcDK/XO6VpWuPfrK6urraRkZGEKIoIBAJ7d7PZbBPt7e3\u002BWCx2cm9nfwRByBEEodXlcn2orKwc2KkT/AoEEO5\u002B2u1PqslL/rknaDl6FscKKoL9TYNBR8DBM5J2jdGTV9o2LWOAsk9XY/5Md3FxcQAAdABQUFBwEcCK5Uy\u002BIqUkn8VoaTYZuOat1NbidlvqM01uuxVNvbMp/1BSVG2hhLQfOV\u002B6kNtpWkYQFwCsiKIYxM4d7jC\u002B8BKhr1PpW87b3yilK1PL7ySqqvVpiuHvypp5U5VurCtih7S9UQ9Kh/NSeeZMH9mBALCurCfG4i/OMZqhUaV4tMEkQ0m62Zam6QQFuQkCn6IpU5Tq2yLmSCLb/y2QZ03mjnLPPU2vPmQJcfOUr\u002BNgGiJgzCD0Oig8rI6tA9GGHKLj4BO6Slw4XtSQ8/rLZCtD4XFYaqp0KU0EQ2bzWF7NYXLinIFbztVxIkh6ViOamukjO/DU4dOr1ZbqyTEhMElBJmsKa4XZnjmBUP3dPEP\u002BeKmx5IGVLXzMs6Znkcsxb\u002BxKTMr0dykvL59oaGgYjkQiluzeflBKmfn5\u002BUNVVVVvbTbb7jtkAIDjOLjd7h6WZe/vsQ4gHo8XaZr2pra2timzTgCgr69vQhRFz9LS0mo0Gv2YObAfHMcZnU5nk9VqNRoMhkGv1zuAnc/Bbrc/D4VC4Wg0mu3tiyzLCIfD791uNyoqKoLZ/X\u002BXn25ERIg8ycqdAAAAAElFTkSuQmCC", + "WhenOpened": "2026-05-13T09:08:51.991Z" + }, + { + "$type": "Document", + "DocumentIndex": 8, + "Title": "App.config", + "DocumentMoniker": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.config", + "RelativeDocumentMoniker": "App.config", + "ToolTip": "C:\\Users\\Administrator\\PycharmProjects\\PythonProject\\C#\\YKC\\App.config", + "RelativeToolTip": "App.config", + "ViewState": "AgIAAAAAAAAAAAAAAADwvwUAAAAQAAAAAAAAAA==", + "Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOhSURBVDhPrZRPSCNXHMe/LxNjTbquSYiLSYwV/1MwEEwFIWsOBQ/\u002BxS6ElUV6qiIG3ZNQSrGswQotu4i3QqkHXTCIYbeHFi9u2Wo1YhSNh7mkQaNpzWSMzDATNXm9OKIj2B76gXd53\u002B/vw\u002BM9eMD/DFFvzM3NGQG8DAaDpv39fWSz2Vu50\u002BlEY2NjeGJi4sWt4ApGveFwOIyJRGLK4XA0GY3G41gs9geA46vltVgsLSaTydbc3Fzo8Xj2VldXz2/O3zmhy\u002BUqA7A5ODiY8Hq9r2pra\u002BeVrKKi4k1lZWWd0\u002BnMAKgC8JxS\u002Buv09PRfSkdzbboilUohnU5jcnLyxU2ZQiaTeVtWVvYdpfSSEPIjIaRtaGjoQyW/I/w3Ojs7v\u002Bjr6/uMENJGKU0BeKnVageUXHu7DgQCAVBKAQD9/f23svb2diQSiQfDw8Ot0WjUaDKZHjIM8wGl9IHSuX6UcDjsbWpq\u002BnxmZsZrtVpbCgoKCn0\u002BH7e0tPSn0nny5Alisdje1tbWZj6fPxBF8XdBEKyCIOxlMpkV3HyUcDjcF4lERoPBoJvnebhcLpSXl8\u002BXlpa\u002BGhgYCCs9NRUVFW8AbMXj8XEA0ITD4TKWZQvdbve8wWD4sqen5\u002B\u002BLi4vc8vIydnd3\u002BwRB\u002BFotuQ8NIWQzk8k8BoDz8/P3sViszWKxpPR6PaLRKBYWFtQz98Kk0\u002Bnvj46O6rq7u8Xe3t6Cqqqqb1dWVmp5ntfKsgxJklie51\u002BrBxVKSkqeAjhW7pBhGGZclmVbKpUyb29vf3xwcNCzs7OjFUURVwWW47j/LNQ2NDSAZVkwDONNJpM4OTlBNpsFpRRarRZFRUWPRkdHP\u002BV5/v3s7KysFqrReL3eY6vVmhVFEYlEArIsgxACQgguLy\u002Bh0\u002BnckiTNGQyGer/fX6gWqNHkcrmmjo6O31pbW1FcXAyNRgOz2QydTgcA4DgOa2tr5lwu9wsh5LFaoEbj9/uP9Hr9VzqdrosQ0kUp7WIYpsvj8WzU1NQgn89DEAQmEok84jhuYmRk5CkAxONxI8uyP7W0tHxiMpmuhQwAhEKhxMbGBptMJtnT01P28PCQ9fl8IqXUrNFoPuI4DqIoglJqOzs728vn80ehUOi5LMvP9Hq9yW63v1tfX1/BfZ/D2NjY6\u002Brq6h/q6\u002BvDdrsdDMNAkiQIggAAD3mer1tcXHxnMBh\u002BdrvdrDJ35z9UMzU11SFJ0ttgMAi32w2bzfZNIBAYV/cU/gFl85csP2dGWAAAAABJRU5ErkJggg==", + "WhenOpened": "2026-05-13T09:08:54.548Z" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "ResourcePart.cs", + "DocumentMoniker": "C:\\Users\\Administrator\\AppData\\Local\\Temp\\.vsdbgsrc\\3714f74b82eacc6cf8dcf1e32980b0908d4f8b447d25d4eb08ff1424a7b57c02\\ResourcePart.cs", + "RelativeDocumentMoniker": "..\\..\\..\\..\\AppData\\Local\\Temp\\.vsdbgsrc\\3714f74b82eacc6cf8dcf1e32980b0908d4f8b447d25d4eb08ff1424a7b57c02\\ResourcePart.cs", + "ToolTip": "C:\\Users\\Administrator\\AppData\\Local\\Temp\\.vsdbgsrc\\3714f74b82eacc6cf8dcf1e32980b0908d4f8b447d25d4eb08ff1424a7b57c02\\ResourcePart.cs [\u53EA\u8BFB]", + "RelativeToolTip": "..\\..\\..\\..\\AppData\\Local\\Temp\\.vsdbgsrc\\3714f74b82eacc6cf8dcf1e32980b0908d4f8b447d25d4eb08ff1424a7b57c02\\ResourcePart.cs [\u53EA\u8BFB]", + "ViewState": "AgIAABMAAAAAAAAAAAAowCcAAAADAAAAAQAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-13T09:19:37.213Z", + "EditorCaption": " [\u53EA\u8BFB]" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/上位机/YKC/App.config b/上位机/YKC/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/上位机/YKC/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/上位机/YKC/App.xaml b/上位机/YKC/App.xaml new file mode 100644 index 0000000..5ef7f43 --- /dev/null +++ b/上位机/YKC/App.xaml @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/上位机/YKC/App.xaml.cs b/上位机/YKC/App.xaml.cs new file mode 100644 index 0000000..0168215 --- /dev/null +++ b/上位机/YKC/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace YKC +{ + /// + /// App.xaml 的交互逻辑 + /// + public partial class App : Application + { + } +} diff --git a/上位机/YKC/Config.cs b/上位机/YKC/Config.cs new file mode 100644 index 0000000..568c9ea --- /dev/null +++ b/上位机/YKC/Config.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; + +namespace YKC +{ + public static class Config + { + public static string TargetIp { get; set; } = "10.12.19.100"; + public static int TargetPort { get; set; } = 6001; + public static int LocalPort { get; set; } = 6002; + public static int UdpTimeout { get; set; } = 3; + + public static readonly Dictionary Cmd = new Dictionary + { + ["LOGIN"] = "server_login", + ["GET_STATUS"] = "server_get_status", + ["SET_PILE_ID"] = "server_set_pile_id", + ["GET_PILE_INFO"] = "server_get_pile_info", + ["REBOOT"] = "server_reboot", + ["REPORT_DATA"] = "report_data", + ["PILE_METRICS"] = "pile_metrics", + ["REAL_TIME_DATA"] = "real_time_data", + ["GET_GW_INFO"] = "gateway_get_info", + ["GET_4G_STATUS"] = "gateway_get_4g_status", + ["GET_CLOUD_CONFIG"] = "gateway_get_cloud_config", + ["SET_CLOUD_CONFIG"] = "gateway_set_cloud_config", + ["GET_NET_CONFIG"] = "gateway_get_net_config", + ["SET_NET_CONFIG"] = "gateway_set_net_config", + }; + } +} diff --git a/上位机/YKC/LoginWindow.xaml b/上位机/YKC/LoginWindow.xaml new file mode 100644 index 0000000..0de9a25 --- /dev/null +++ b/上位机/YKC/LoginWindow.xaml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + +