# 🚀 充电桩管理系统 - 快速启动指南 ## 📦 文件清单 已创建的文件: ``` Charge/ ├── ChargeStation.cs # 充电桩数据模型 ├── ChargeStationDataService.cs # 数据服务(单例) ├── ChargeStationManagementForm.cs # 管理窗口主类 ├── ChargeStationManagementForm.Designer.cs # 窗口UI设计 ├── ChargeStationManagementExample.cs # 示例代码 ├── README_ChargeStationManagement.md # 详细使用说明 └── QUICKSTART.md # 本文件 ``` ## ⚡ 5分钟快速上手 ### 步骤1:在主窗口添加菜单(推荐方式) 如果您的主窗口有菜单栏,添加一个菜单项: ```csharp // 在主窗口的 InitializeComponent() 或构造函数中添加 // 方法1: 如果有工具栏 var btnChargeManagement = new ToolStripButton("充电桩管理"); btnChargeManagement.Click += (s, e) => { var form = new StandardScene.Charge.ChargeStationManagementForm(); form.Show(); }; toolStrip.Items.Add(btnChargeManagement); // 方法2: 如果有菜单栏 var menuItemCharge = new ToolStripMenuItem("充电桩管理(&C)"); menuItemCharge.Click += (s, e) => { var form = new StandardScene.Charge.ChargeStationManagementForm(); form.Show(); }; menuStrip.Items.Add(menuItemCharge); // 方法3: 如果有按钮面板 var btnChargeManagement = new Button { Text = "充电桩管理", Size = new Size(120, 40), Location = new Point(10, 10) }; btnChargeManagement.Click += (s, e) => { var form = new StandardScene.Charge.ChargeStationManagementForm(); form.Show(); }; this.Controls.Add(btnChargeManagement); ``` ### 步骤2:初始化测试数据(首次运行) 在程序启动时或通过菜单调用: ```csharp // 在主窗口的 Load 事件或启动代码中 StandardScene.Charge.ChargeStationManagementExample.InitializeTestData(); ``` ### 步骤3:打开管理窗口 点击您添加的菜单项或按钮,即可打开充电桩管理窗口。 --- ## 🎯 集成到 AbstractChargeMission 如果您想将充电桩数据与充电任务关联,在 `AbstractChargeMission.cs` 中添加: ### 1. 引用命名空间 ```csharp using StandardScene.Charge; ``` ### 2. 在选择充电站点时使用充电桩数据 ```csharp // 在 Execute() 方法的充电决策部分 var dataService = ChargeStationDataService.Instance; // 获取空闲的充电桩 var idleStations = dataService.GetIdleStations(); // 根据充电桩的站点ID筛选 targetPlan = Commons.GetNearestPlan((Car)car, site => site.fields.ContainsKey("group") && site.fields.ContainsKey("Charge") && GetChargeType(car).Contains(site.fields["group"]) && idleStations.Any(s => s.SiteId == site.id) // 确保站点有空闲充电桩 ); ``` ### 3. 在开始充电时更新充电桩状态 ```csharp // 在车辆到达充电站时 public override void ArriveAction(Car car, Site site) { var dataService = ChargeStationDataService.Instance; var station = dataService.GetAllStations() .FirstOrDefault(s => s.SiteId == site.id && s.Status == ChargeStationStatus.Idle); if (station != null) { dataService.UpdateStationStatus(station.StationId, ChargeStationStatus.Charging); car.tags.Add("chargingStationId", station.StationId); Diagnosis.Log($"车辆 {car.name} 开始在充电桩 {station.Name} 充电", "Charge", true); } } ``` ### 4. 在离开充电站时更新充电桩状态 ```csharp // 在车辆离开充电站时 public override void LeaveAction(Car car, Site site) { if (car.tags.TryGetValue("chargingStationId", out var stationId)) { var dataService = ChargeStationDataService.Instance; dataService.UpdateStationStatus(stationId, ChargeStationStatus.Idle); car.tags.Remove("chargingStationId"); Diagnosis.Log($"车辆 {car.name} 充电完成,充电桩 {stationId} 恢复空闲", "Charge", true); } } ``` --- ## 📊 在主界面显示充电桩统计 在主窗口添加实时统计显示: ```csharp // 添加一个 Timer 定时更新统计信息 private Timer chargeStationStatusTimer; private Label lblChargeStationStatus; private void InitializeChargeStationMonitor() { // 创建状态标签 lblChargeStationStatus = new Label { Text = "充电桩: 加载中...", AutoSize = true, Location = new Point(10, 10), Font = new Font("微软雅黑", 10F, FontStyle.Bold) }; this.Controls.Add(lblChargeStationStatus); // 创建定时器(每3秒更新一次) chargeStationStatusTimer = new Timer { Interval = 3000, Enabled = true }; chargeStationStatusTimer.Tick += UpdateChargeStationStatus; chargeStationStatusTimer.Start(); } private void UpdateChargeStationStatus(object sender, EventArgs e) { try { var dataService = StandardScene.Charge.ChargeStationDataService.Instance; var stations = dataService.GetAllStations(); var idle = stations.Count(s => s.Status == StandardScene.Charge.ChargeStationStatus.Idle); var charging = stations.Count(s => s.Status == StandardScene.Charge.ChargeStationStatus.Charging); var fault = stations.Count(s => s.Status == StandardScene.Charge.ChargeStationStatus.Fault); lblChargeStationStatus.Text = $"充电桩: 总数 {stations.Count} | " + $"空闲 {idle} | 充电中 {charging} | 故障 {fault}"; // 根据状态设置颜色 if (fault > 0) lblChargeStationStatus.ForeColor = Color.Red; else if (idle == 0 && charging > 0) lblChargeStationStatus.ForeColor = Color.Orange; else lblChargeStationStatus.ForeColor = Color.Green; } catch (Exception ex) { lblChargeStationStatus.Text = $"充电桩: 获取状态失败 - {ex.Message}"; lblChargeStationStatus.ForeColor = Color.Gray; } } ``` --- ## 🔧 配置充电桩与站点的映射 ### 方式1: 在站点属性中添加充电桩编号 修改地图站点的 `fields`: ```csharp // 为站点添加充电桩编号 site.fields.Add("ChargeStationId", "CS20240115123456"); ``` ### 方式2: 在充电桩管理界面直接设置站点ID 在充电桩管理窗口中,编辑充电桩时填写"站点ID"字段。 ### 方式3: 自动关联(代码实现) ```csharp // 自动将充电桩与最近的充电站点关联 public void AutoAssignStationsToSites() { var dataService = ChargeStationDataService.Instance; var allStations = dataService.GetAllStations(); var chargeSites = SimpleLib.GetAllSites() .Where(s => s.fields.ContainsKey("Charge")) .ToList(); foreach (var station in allStations) { if (station.SiteId == null || station.SiteId == 0) { // 根据名称或其他规则自动匹配站点 var matchedSite = chargeSites.FirstOrDefault(s => s.fields.ContainsKey("name") && s.fields["name"].Contains(station.Name) ); if (matchedSite != null) { station.SiteId = matchedSite.id; dataService.UpdateStation(station, out _); Diagnosis.Log($"自动关联充电桩 {station.Name} 到站点 {matchedSite.id}", "ChargeStation", true); } } } } ``` --- ## 📱 添加快捷键 为管理窗口添加快捷键(在主窗口): ```csharp protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { // Ctrl+C 打开充电桩管理 if (keyData == (Keys.Control | Keys.C)) { var form = new StandardScene.Charge.ChargeStationManagementForm(); form.Show(); return true; } return base.ProcessCmdKey(ref msg, keyData); } ``` --- ## 🎨 自定义界面样式 如果需要调整窗口样式,修改 `ChargeStationManagementForm.Designer.cs`: ```csharp // 修改窗口大小 this.Size = new Size(1400, 800); // 修改按钮颜色 btnAdd.BackColor = Color.FromArgb(144, 238, 144); // 浅绿色 btnSave.BackColor = Color.FromArgb(135, 206, 250); // 浅蓝色 btnDelete.BackColor = Color.FromArgb(255, 182, 193); // 浅红色 // 修改字体 this.Font = new Font("微软雅黑", 9F); ``` --- ## 🐛 常见问题 ### Q1: 窗口打不开 **A**: 检查是否正确引用了命名空间: ```csharp using StandardScene.Charge; ``` ### Q2: 数据保存失败 **A**: 确保 `Data` 文件夹有写入权限: ```bash # Windows 右键 Data 文件夹 -> 属性 -> 安全 -> 确保当前用户有"写入"权限 ``` ### Q3: 找不到充电桩数据 **A**: 首次运行时需要初始化数据: ```csharp ChargeStationManagementExample.InitializeTestData(); ``` ### Q4: 充电桩状态不更新 **A**: 手动刷新数据: ```csharp ChargeStationDataService.Instance.Reload(); ``` --- ## 📚 进阶功能 ### 实时监控充电桩通信状态 ```csharp // 定期 Ping 充电桩 IP private async Task PingChargeStation(string ip, int port) { try { using (var client = new System.Net.Sockets.TcpClient()) { var result = client.BeginConnect(ip, port, null, null); var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(3)); if (success) { client.EndConnect(result); return true; } return false; } } catch { return false; } } ``` ### 充电桩数据可视化 ```csharp // 在主界面添加充电桩状态图表 private void DrawChargeStationChart(Graphics g) { var dataService = ChargeStationDataService.Instance; var stations = dataService.GetAllStations(); int x = 10, y = 10, size = 40; foreach (var station in stations) { Color color = station.Status switch { ChargeStationStatus.Idle => Color.Green, ChargeStationStatus.Charging => Color.Yellow, ChargeStationStatus.Fault => Color.Red, ChargeStationStatus.Offline => Color.Gray, _ => Color.White }; g.FillRectangle(new SolidBrush(color), x, y, size, size); g.DrawString(station.Name, this.Font, Brushes.Black, x, y + size + 5); x += size + 10; if (x > this.Width - 100) { x = 10; y += size + 30; } } } ``` --- ## 🎉 完成 现在您已经完成了充电桩管理系统的集成! **下一步**: 1. ✅ 添加菜单项或按钮 2. ✅ 初始化测试数据 3. ✅ 打开管理窗口测试 4. ✅ 将充电桩数据集成到充电任务 5. ✅ 添加实时监控和统计 **需要帮助?** - 查看 `README_ChargeStationManagement.md` 获取详细文档 - 参考 `ChargeStationManagementExample.cs` 查看示例代码 - 检查日志中的 `ChargeStation` 标签 --- **版本**: 1.0.0 **最后更新**: 2024-01-15