Innovenergy_trunk/csharp/App/SaliMax/src/AggregationService/Aggregator.cs

179 lines
7.7 KiB
C#

using InnovEnergy.Lib.Utils;
using static System.Double;
namespace InnovEnergy.App.SaliMax.AggregationService;
public static class Aggregator
{
public static async Task HourlyDataAggregationManager()
{
var currentDateTime = DateTime.Now;
var nextRoundedHour = currentDateTime.AddHours(1).AddMinutes(-currentDateTime.Minute).AddSeconds(-currentDateTime.Second);
// Calculate the time until the next rounded hour
var timeUntilNextHour = nextRoundedHour - currentDateTime;
// Output the current and next rounded hour times
Console.WriteLine("------------------------------------------HourlyDataAggregationManager-------------------------------------------");
Console.WriteLine("Current Date and Time: " + currentDateTime);
Console.WriteLine("Next Rounded Hour: " + nextRoundedHour);
// Output the time until the next rounded hour
Console.WriteLine("Waiting for " + timeUntilNextHour.TotalMinutes + " minutes...");
Console.WriteLine("-----------------------------------------------------------------------------------------------------------------");
// Wait until the next rounded hour
await Task.Delay(timeUntilNextHour);
while (true)
{
try
{
AggregatedData hourlyAggregatedData = CreateAverage("LogDirectory",DateTime.Now.AddHours(-1).ToUnixTime(),DateTime.Now.ToUnixTime());
hourlyAggregatedData.Save("HourlyData");
}
catch (Exception e)
{
Console.WriteLine("An error has occured when calculating hourly aggregated data, exception is:\n" + e);
}
await Task.Delay(TimeSpan.FromHours(1));
}
}
public static async Task DailyDataAggregationManager()
{
var currentDateTime = DateTime.Now;
var nextRoundedHour = currentDateTime.AddDays(1).AddHours(-currentDateTime.Hour).AddMinutes(-currentDateTime.Minute).AddSeconds(-currentDateTime.Second);
// Calculate the time until the next rounded hour
var timeUntilNextDay = nextRoundedHour - currentDateTime;
Console.WriteLine("------------------------------------------DailyDataAggregationManager-------------------------------------------");
// Output the current and next rounded hour times
Console.WriteLine("Current Date and Time: " + currentDateTime);
Console.WriteLine("Next Rounded Hour: " + nextRoundedHour);
// Output the time until the next rounded hour
Console.WriteLine("Waiting for " + timeUntilNextDay.TotalHours + " hours...");
Console.WriteLine("-----------------------------------------------------------------------------------------------------------------");
// Wait until the next rounded hour
await Task.Delay(timeUntilNextDay);
while (true)
{
try
{
AggregatedData dailyAggregatedData = CreateAverage("HourlyData",DateTime.Now.AddDays(-1).ToUnixTime(),DateTime.Now.ToUnixTime());
dailyAggregatedData.Save("DailyData");
}
catch (Exception e)
{
Console.WriteLine("An error has occured when calculating daily aggregated data, exception is:\n" + e);
}
await Task.Delay(TimeSpan.FromDays(1));
}
}
private static AggregatedData CreateAverage(String myDirectory, Int64 afterTimestamp, Int64 beforeTimestamp)
{
// Get all CSV files in the specified directory
var csvFiles = Directory.GetFiles(myDirectory, "*.csv");
var socAverage = new List<Double>();
var pvPowerAverage = new List<Double>();
var batteryPowerAverage = new List<Double>();
Console.WriteLine("-----------------------------------------------------------------------------------------------------------------");
Console.WriteLine("File timestamp should start after "+ afterTimestamp);
foreach (var csvFile in csvFiles)
{
if (csvFile == "LogDirectory/log.csv")
{
continue;
}
if (IsFileWithinTimeRange(csvFile, afterTimestamp, beforeTimestamp))
{
using var reader = new StreamReader(csvFile);
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var lines = line?.Split(';');
// Assuming there are always three columns (variable name and its value)
if (lines is { Length: 3 })
{
var variableName = lines[0].Trim();
if (TryParse(lines[1].Trim(), out var value))
{
switch (variableName)
{
case "/Battery/Soc" or "/AvgSoc":
socAverage.Add(value);
break;
case "/PvOnDc/Dc/Power" or "/AvgPvPower":
pvPowerAverage.Add(value);
break;
case "/Battery/Dc/Power" or "/BatteryPowerAverage":
batteryPowerAverage.Add(value);
break;
// Add more cases as needed
default:
// Code to execute when variableName doesn't match any condition
break;
}
}
else
{
//Handle cases where variableValue is not a valid number
// Console.WriteLine(
// $"Invalid numeric value for variable {variableName}:{lines[1].Trim()}");
}
}
else
{
// Handle invalid column format
//Console.WriteLine("Invalid format in column");
}
}
}
}
AggregatedData aggregatedData = new AggregatedData
{
AvgSoc = socAverage.Any() ? socAverage.Average() : 0.0,
AvgPvPower = pvPowerAverage.Any() ? pvPowerAverage.Average() : 0.0,
BatteryPowerAverage = batteryPowerAverage.Any() ? batteryPowerAverage.Average() : 0.0
};
// Print the stored CSV data for verification
Console.WriteLine($"SOC: {aggregatedData.AvgSoc}");
Console.WriteLine($"PvPower: {aggregatedData.AvgPvPower}");
Console.WriteLine($"Battery: {aggregatedData.BatteryPowerAverage}");
Console.WriteLine("CSV data reading and storage completed.");
Console.WriteLine("-----------------------------------------------------------------------------------------------------------------");
return aggregatedData;
}
// Custom method to check if a string is numeric
private static Boolean GetVariable(String value, String path)
{
return value == path;
}
private static Boolean IsFileWithinTimeRange(string filePath, long startTime, long endTime)
{
var fileTimestamp = long.TryParse(Path.GetFileNameWithoutExtension(filePath).Replace("log_", ""), out var fileTimestamp1) ? fileTimestamp1 : -1;
return fileTimestamp >= startTime && fileTimestamp < endTime;
}
}