From 0d7bc18293afed11c41c3893d1e04111d9776178 Mon Sep 17 00:00:00 2001 From: douwe Date: Fri, 24 Apr 2026 10:51:48 +0200 Subject: [PATCH] Improved chart visual --- Models/EnergyData.cs | 4 +- Models/SimulatedBatteryEnergyData.cs | 17 ------ Pages/Home.razor | 87 ++++++---------------------- Services/BatterySimulator.cs | 31 +--------- Services/DataFilter.cs | 30 ++++++++++ 5 files changed, 55 insertions(+), 114 deletions(-) delete mode 100644 Models/SimulatedBatteryEnergyData.cs create mode 100644 Services/DataFilter.cs diff --git a/Models/EnergyData.cs b/Models/EnergyData.cs index fc2c2f0..68850fc 100644 --- a/Models/EnergyData.cs +++ b/Models/EnergyData.cs @@ -8,7 +8,8 @@ namespace BattSim.Models public bool DayTariff { get; set; } public double Consumption { get; set; } public double Production { get; set; } - + public double BatteryCharge { get; set; } + public EnergyData(){} public EnergyData(EnergyData other) { @@ -16,6 +17,7 @@ namespace BattSim.Models DayTariff = other.DayTariff; Consumption = other.Consumption; Production = other.Production; + BatteryCharge = other.BatteryCharge; } } } \ No newline at end of file diff --git a/Models/SimulatedBatteryEnergyData.cs b/Models/SimulatedBatteryEnergyData.cs deleted file mode 100644 index 5163234..0000000 --- a/Models/SimulatedBatteryEnergyData.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace BattSim.Models -{ - public class SimulatedBatteryEnergyData : EnergyData - { - public double BatteryCharge { get; set; } - public double SimulatedConsumption { get; set; } - public double SimulatedProduction { get; set; } - - public SimulatedBatteryEnergyData(EnergyData energyData) : base(energyData) { } - public SimulatedBatteryEnergyData(SimulatedBatteryEnergyData simulatedBatteryEnergyData) : base(simulatedBatteryEnergyData) - { - BatteryCharge = simulatedBatteryEnergyData.BatteryCharge; - } - } -} \ No newline at end of file diff --git a/Pages/Home.razor b/Pages/Home.razor index 31c7094..2d8d1b2 100644 --- a/Pages/Home.razor +++ b/Pages/Home.razor @@ -267,7 +267,7 @@ -@if (FluviusDataDaily.Length > 0) +@if (FilteredFluviusData.Length > 0) {

Overzicht: Energie Data & Simulatie

@@ -299,7 +299,7 @@ - @if (SimulationDataDaily.Length > 0) + @if (FilteredSimulationData.Length > 0) { @@ -322,14 +322,13 @@ } @code { - EnergyData[] FluviusDataRaw = []; - EnergyData[] FluviusDataDaily = []; - - SimulatedBatteryEnergyData[] SimulationData = []; - SimulatedBatteryEnergyData[] SimulationDataDaily = []; + EnergyData[] FluviusDataRaw = []; + EnergyData[] SimulationData = []; + DataFilter.FilterOption SelectedFilterOption = DataFilter.FilterOption.ALL; + EnergyData[] FilteredFluviusData = []; - SimulatedBatteryEnergyData[] FilteredSimulationData = []; + EnergyData[] FilteredSimulationData = []; EnergyCostCalculator calculator = new(); double normalCost = 0.0; @@ -406,8 +405,7 @@ StateHasChanged(); FluviusDataRaw = await FluviusDataHandler.LoadAndProcessFile(file); - FluviusDataDaily = FluviusDataHandler.GenerateDailyData(FluviusDataRaw); - FilteredFluviusData = FluviusDataDaily; + SetTimePeriod("all"); FilteredSimulationData = []; StepData[0].isProcessing = false; @@ -415,7 +413,6 @@ StepData[1].Completed = false; StepData[2].Completed = false; SimulationData = []; - SimulationDataDaily = []; StateHasChanged(); } @@ -437,8 +434,7 @@ try { SimulationData = BatterySimulator.SimulateBattery(FluviusDataRaw, BatteryCapacity, Efficiency/100); - SimulationDataDaily = BatterySimulator.GenerateDailyData(SimulationData); - FilteredSimulationData = SimulationDataDaily; + SetTimePeriod("all"); StepData[1].isProcessing = false; StepData[1].Completed = true; @@ -464,9 +460,7 @@ try { - normalCost = calculator.CalculateCostOfEnergyUsage(FluviusDataRaw); - simulatedCost = calculator.CalculateCostOfEnergyUsage(SimulationData); - + normalCost = calculator.CalculateCostOfEnergyUsage(FluviusDataRaw); StepData[2].isProcessing = false; StepData[2].Completed = true; StateHasChanged(); @@ -481,62 +475,19 @@ private void SetTimePeriod(string period) { _timePeriod = period; - + var filterOption = period switch { + "all" => DataFilter.FilterOption.ALL, + "year" => DataFilter.FilterOption.YEAR, + "month" => DataFilter.FilterOption.MONTH, + "week" => DataFilter.FilterOption.WEEK, + "day" => DataFilter.FilterOption.DAY, + }; // Filter data based on selected period - FilteredFluviusData = FilterFluviusDataByPeriod(period); - FilteredSimulationData = FilterSimulationDataByPeriod(period); + if(FluviusDataRaw.Length > 0) FilteredFluviusData = DataFilter.FilterData(FluviusDataRaw, filterOption); + if(FilteredSimulationData.Length > 0) FilteredSimulationData = DataFilter.FilterData(SimulationData, filterOption); StateHasChanged(); } - - private EnergyData[] FilterFluviusDataByPeriod(string period) - { - if (period == "all" || FluviusDataDaily.Length == 0) - return FluviusDataDaily; - - var result = new List(); - - foreach (var item in FluviusDataDaily) - { - // The Time property is DateTime but for daily data it represents the day - var date = DateOnly.FromDateTime(item.Time); - bool include = false; - switch (period) - { - case "day": include = true; break; // Show all daily data - case "week": include = date.DayOfWeek == DayOfWeek.Monday; break; - case "month": include = date.Day == 1; break; - case "year": include = date.Month == 1 && date.Day == 1; break; - } - if (include) result.Add(item); - } - - return result.ToArray(); - } - - private SimulatedBatteryEnergyData[] FilterSimulationDataByPeriod(string period) - { - if (period == "all" || SimulationDataDaily.Length == 0) - return SimulationDataDaily; - - var result = new List(); - - foreach (var item in SimulationDataDaily) - { - var date = DateOnly.FromDateTime(item.Time); - bool include = false; - switch (period) - { - case "day": include = true; break; - case "week": include = date.DayOfWeek == DayOfWeek.Monday; break; - case "month": include = date.Day == 1; break; - case "year": include = date.Month == 1 && date.Day == 1; break; - } - if (include) result.Add(item); - } - - return result.ToArray(); - } private string FormatObject(object value) { if(value is double d) return $"{d:0.##} kWh"; diff --git a/Services/BatterySimulator.cs b/Services/BatterySimulator.cs index 5b4ec9e..cbf5caf 100644 --- a/Services/BatterySimulator.cs +++ b/Services/BatterySimulator.cs @@ -6,14 +6,14 @@ namespace BattSim.Services { public static class BatterySimulator { - public static SimulatedBatteryEnergyData[] SimulateBattery(EnergyData[] energyData, double batteryCapacity, double efficiency) + public static EnergyData[] SimulateBattery(EnergyData[] energyData, double batteryCapacity, double efficiency) { - var results = new List(); + var results = new List(); double batteryCharge = 0; foreach (var e in energyData) { - var simulatedBatteryEnergyData = new SimulatedBatteryEnergyData(e); + var simulatedBatteryEnergyData = new EnergyData(e); // Simulate charging the battery based on production double excessProduction = batteryCharge + e.Production - batteryCapacity; batteryCharge = double.Min(batteryCharge + e.Production, batteryCapacity); @@ -33,30 +33,5 @@ namespace BattSim.Services return results.ToArray(); } - - public static SimulatedBatteryEnergyData[] GenerateDailyData(SimulatedBatteryEnergyData[] simulationData) - { - var simulationDataCopy = (SimulatedBatteryEnergyData[]) simulationData.Clone(); - var dailySimulationData = new ConcurrentDictionary(); - Parallel.ForEach(simulationDataCopy, simulationPoint => - { - var date = DateOnly.FromDateTime(simulationPoint.Time); - - // Use AddOrUpdate to avoid double lookup - dailySimulationData.AddOrUpdate( - date, - new SimulatedBatteryEnergyData(simulationPoint), // If key doesn't exist, add this value - (_, existing) => - { - // If key exists, aggregate the values - existing.Consumption += simulationPoint.Consumption; - existing.Production += simulationPoint.Production; - existing.BatteryCharge = double.Max(existing.BatteryCharge, simulationPoint.BatteryCharge); - return existing; - } - ); - }); - return dailySimulationData.Values.ToArray(); - } } } \ No newline at end of file diff --git a/Services/DataFilter.cs b/Services/DataFilter.cs new file mode 100644 index 0000000..020ef35 --- /dev/null +++ b/Services/DataFilter.cs @@ -0,0 +1,30 @@ +using System.Collections.Concurrent; +using System.Collections.Generic; +using BattSim.Models; + +namespace BattSim.Services +{ + public static class DataFilter + { + public enum FilterOption { ALL, YEAR, MONTH, WEEK, DAY } + public static EnergyData[] FilterData(EnergyData[] data, FilterOption filterOption) + { + var dailyData = data + .GroupBy(d=>d.Time.Date) + .Select(group=> new EnergyData{ + Consumption = group.Sum(d => d.Consumption), + Production = group.Sum(d => d.Production), + BatteryCharge = group.Max(d => d.BatteryCharge), + Time = group.First().Time + }).ToArray(); + + return filterOption switch { + FilterOption.DAY => data[(data.Length > 96?data.Length - 96:0)..], // 24 hours * 4 quarters per hour + FilterOption.WEEK => data[(data.Length > 672?data.Length - 672:0)..], // 7 days * 24 hours * 4 quarters per hour + FilterOption.MONTH => dailyData[(dailyData.Length > 30?dailyData.Length - 30:0)..], + FilterOption.YEAR => dailyData[(dailyData.Length > 365?dailyData.Length - 365:0)..], + _ => dailyData + }; + } + } +} \ No newline at end of file