64 lines
3.1 KiB
C#
64 lines
3.1 KiB
C#
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using BattSim.Models;
|
|
|
|
namespace BattSim.Services
|
|
{
|
|
public static class BatterySimulator
|
|
{
|
|
public static SimulatedBatteryEnergyData[] SimulateBattery(EnergyData[] energyData, double batteryCapacity, double efficiency)
|
|
{
|
|
var results = new List<SimulatedBatteryEnergyData>();
|
|
double batteryCharge = 0;
|
|
|
|
foreach (var e in energyData)
|
|
{
|
|
var simulatedBatteryEnergyData = new SimulatedBatteryEnergyData(e);
|
|
// Simulate charging the battery based on production
|
|
double excessProduction = batteryCharge + e.Production - batteryCapacity;
|
|
batteryCharge = double.Min(batteryCharge + e.Production, batteryCapacity);
|
|
simulatedBatteryEnergyData.SimulatedProduction = double.Max(excessProduction, 0);
|
|
|
|
// Simulate discharging the battery based on consumption
|
|
double availableEnergy = batteryCharge * efficiency;
|
|
double deficit = e.Consumption - availableEnergy;
|
|
double energyDrawn = Math.Min(e.Consumption, availableEnergy);
|
|
batteryCharge = batteryCharge - (energyDrawn / efficiency); // Adjust for loss
|
|
simulatedBatteryEnergyData.SimulatedConsumption = Math.Max(deficit, 0);
|
|
|
|
// Register the current charge
|
|
simulatedBatteryEnergyData.BatteryCharge = batteryCharge;
|
|
results.Add(simulatedBatteryEnergyData);
|
|
}
|
|
|
|
return results.ToArray();
|
|
}
|
|
|
|
public static SimulatedBatteryEnergyData[] GenerateDailyData(SimulatedBatteryEnergyData[] simulationData)
|
|
{
|
|
var simulationDataCopy = (SimulatedBatteryEnergyData[]) simulationData.Clone();
|
|
var dailySimulationData = new ConcurrentDictionary<DateOnly, SimulatedBatteryEnergyData>();
|
|
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.SimulatedConsumption += simulationPoint.SimulatedConsumption;
|
|
existing.SimulatedProduction += simulationPoint.SimulatedProduction;
|
|
existing.BatteryCharge = double.Max(existing.BatteryCharge, simulationPoint.BatteryCharge);
|
|
return existing;
|
|
}
|
|
);
|
|
});
|
|
return dailySimulationData.Values.ToArray();
|
|
}
|
|
}
|
|
} |