diff --git a/csharp/App/SaliMax/src/AggregationService/Aggregator.cs b/csharp/App/SaliMax/src/AggregationService/Aggregator.cs index aca719508..962c39d18 100644 --- a/csharp/App/SaliMax/src/AggregationService/Aggregator.cs +++ b/csharp/App/SaliMax/src/AggregationService/Aggregator.cs @@ -1,6 +1,5 @@ -using System.Runtime.InteropServices; using InnovEnergy.Lib.Utils; -using static System.Double; + namespace InnovEnergy.App.SaliMax.AggregationService; public static class Aggregator @@ -8,11 +7,11 @@ public static class Aggregator public static async Task HourlyDataAggregationManager() { - DateTime currentDateTime = DateTime.Now; - DateTime nextRoundedHour = currentDateTime.AddHours(1).AddMinutes(-currentDateTime.Minute).AddSeconds(-currentDateTime.Second); + var currentDateTime = DateTime.Now; + var nextRoundedHour = currentDateTime.AddHours(1).AddMinutes(-currentDateTime.Minute).AddSeconds(-currentDateTime.Second); // Calculate the time until the next rounded hour - TimeSpan timeUntilNextHour = nextRoundedHour - currentDateTime; + var timeUntilNextHour = nextRoundedHour - currentDateTime; // Output the current and next rounded hour times Console.WriteLine("Current Date and Time: " + currentDateTime); @@ -46,143 +45,66 @@ public static class Aggregator var csvFiles = Directory.GetFiles(myDirectory, "*.csv"); var currentTimestamp = DateTime.Now.ToUnixTime(); - Double socAverage = 0; - Double pvPowerAverage = 0; - Double batteryPowerAverage = 0; + var oneHourBefore = DateTime.Now.AddHours(-1).ToUnixTime(); Console.WriteLine("-----------------------------------------------------------------------------------------------------------------"); Console.WriteLine("File timestamp should start after "+ DateTime.Now.AddHours(-1)); + + var validFiles = csvFiles + .Where(csvFile => IsFileWithinTimeRange(csvFile, oneHourBefore, currentTimestamp)) + .ToList(); - foreach (var csvFile in csvFiles) + try { - - if (csvFile == "LogDirectory/log.csv") - { - continue; - } - var fileTimestamp = long.Parse(Path.GetFileNameWithoutExtension(csvFile).Replace("log_", "")); - var oneHourBefore = DateTime.Now.AddHours(-1).ToUnixTime(); + var average1HSoc = validFiles + .Select(csvFile => csvFile.ExtractValue("/Battery/Soc")) + .NotNull() + .Average(); + + var average1HPvPower = validFiles + .Select(csvFile => csvFile.ExtractValue("/PvOnDc/Dc/Power")) + .NotNull() + .Average(); + + var average1HBatteryPower = validFiles + .Select(csvFile => csvFile.ExtractValue("/Battery/Dc/Power")) + .NotNull() + .Average(); + + + Console.WriteLine($"SOC: {average1HSoc}"); + Console.WriteLine($"PvPower: {average1HPvPower}"); + Console.WriteLine($"Battery: {average1HBatteryPower}"); - - if (fileTimestamp >= oneHourBefore && fileTimestamp <= currentTimestamp) - { - Console.WriteLine("Check file created at "+ DateTimeOffset.FromUnixTimeSeconds(fileTimestamp).DateTime); - 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)) - { - // Check if variableValue is a valid number - if (IsSoc(variableName)) - { - if (socAverage == 0) - { - socAverage = value; - } - else - { - socAverage = (socAverage + value) / 2; - } - } - - if (IsPvPower(variableName)) - { - if (pvPowerAverage == 0) - { - pvPowerAverage = value; - } - else - { - pvPowerAverage = (pvPowerAverage + value) / 2; - } - } - - if (IsBatteryPower(variableName)) - { - if (batteryPowerAverage == 0) - { - batteryPowerAverage = value; - } - else - { - batteryPowerAverage = (batteryPowerAverage + value) / 2; - } - } - } - 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"); - } - } - } } - - // Print the stored CSV data for verification - - Console.WriteLine($"SOC: {socAverage}"); - Console.WriteLine($"PvPower: {pvPowerAverage}"); - Console.WriteLine($"Battery: {batteryPowerAverage}"); - + catch (Exception e) + { + e.WriteLine(); + } + Console.WriteLine("CSV data reading and storage completed."); //Create a new file to folder "Hourly Aggregated Data and push it to S3" Console.WriteLine("-----------------------------------------------------------------------------------------------------------------"); - //UploadAggregatedCsv(); + + } - } - - // private static async Task UploadAggregatedCsv(StatusRecord status, DateTime timeStamp) - // { - // var s3Config = status.Config.S3; - // var csv = status.ToCsv().LogInfo(); - // if (s3Config is null) - // return false; - // - // var s3Path = timeStamp.ToUnixTime() + ".csv"; - // var request = s3Config.CreatePutRequest(s3Path); - // var response = await request.PutAsync(new StringContent(csv)); - // - // - // if (response.StatusCode != 200) - // { - // Console.WriteLine("ERROR: PUT"); - // var error = await response.GetStringAsync(); - // Console.WriteLine(error); - // } - // - // return true; - // } - // - - // Custom method to check if a string is numeric - private static bool IsSoc(string value) + private static Double? ExtractValue(this String csvFile, String path) { - return value == "/Battery/Soc"; + return File + .ReadAllLines(csvFile) + .Select(l => l.Split(';')) + .Where(l => l.Length == 3) + .Where(line => line[0].Trim() == path) + .Select(l => Double.TryParse(l[1].Trim(), out var value) + ? value + : (Double?) null) + .FirstOrDefault(); } - - private static bool IsPvPower(string value) + + private static Boolean IsFileWithinTimeRange(string filePath, long startTime, long endTime) { - return value == "/PvOnDc/Dc/Power"; + var fileTimestamp = long.TryParse(Path.GetFileNameWithoutExtension(filePath).Replace("log_", ""), out var fileTimestamp1) ? fileTimestamp1 : -1; + + return fileTimestamp >= startTime && fileTimestamp < endTime; } - - private static bool IsBatteryPower(string value) - { - return value == "/Battery/Dc/Power"; - } - } \ No newline at end of file