Fixed small bug on aggregator
This commit is contained in:
parent
a871693ba8
commit
4f1f0b0844
|
@ -0,0 +1,188 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using InnovEnergy.Lib.Utils;
|
||||||
|
using static System.Double;
|
||||||
|
namespace InnovEnergy.App.SaliMax.AggregationService;
|
||||||
|
|
||||||
|
public static class Aggregator
|
||||||
|
{
|
||||||
|
|
||||||
|
public static async Task HourlyDataAggregationManager()
|
||||||
|
{
|
||||||
|
DateTime currentDateTime = DateTime.Now;
|
||||||
|
DateTime nextRoundedHour = currentDateTime.AddHours(1).AddMinutes(-currentDateTime.Minute).AddSeconds(-currentDateTime.Second);
|
||||||
|
|
||||||
|
// Calculate the time until the next rounded hour
|
||||||
|
TimeSpan timeUntilNextHour = nextRoundedHour - currentDateTime;
|
||||||
|
|
||||||
|
// 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 " + timeUntilNextHour.TotalMinutes + " minutes...");
|
||||||
|
|
||||||
|
// Wait until the next rounded hour
|
||||||
|
await Task.Delay(timeUntilNextHour);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CreateHourlyAverage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine("An error has occured when calculating hourly aggregated data, exception is:\n" + e);
|
||||||
|
}
|
||||||
|
await Task.Delay(TimeSpan.FromHours(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateHourlyAverage()
|
||||||
|
{
|
||||||
|
var myDirectory = "LogDirectory";
|
||||||
|
|
||||||
|
// Get all CSV files in the specified directory
|
||||||
|
var csvFiles = Directory.GetFiles(myDirectory, "*.csv");
|
||||||
|
|
||||||
|
var currentTimestamp = DateTime.Now.ToUnixTime();
|
||||||
|
Double socAverage = 0;
|
||||||
|
Double pvPowerAverage = 0;
|
||||||
|
Double batteryPowerAverage = 0;
|
||||||
|
|
||||||
|
Console.WriteLine("-----------------------------------------------------------------------------------------------------------------");
|
||||||
|
Console.WriteLine("File timestamp should start after "+ DateTime.Now.AddHours(-1));
|
||||||
|
|
||||||
|
foreach (var csvFile in csvFiles)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (csvFile == "LogDirectory/log.csv")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var fileTimestamp = long.Parse(Path.GetFileNameWithoutExtension(csvFile).Replace("log_", ""));
|
||||||
|
var oneHourBefore = DateTime.Now.AddHours(-1).ToUnixTime();
|
||||||
|
|
||||||
|
|
||||||
|
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}");
|
||||||
|
|
||||||
|
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<Boolean> 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)
|
||||||
|
{
|
||||||
|
return value == "/Battery/Soc";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsPvPower(string value)
|
||||||
|
{
|
||||||
|
return value == "/PvOnDc/Dc/Power";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsBatteryPower(string value)
|
||||||
|
{
|
||||||
|
return value == "/Battery/Dc/Power";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,10 +1,5 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.NetworkInformation;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Reactive.Threading.Tasks;
|
using System.Reactive.Threading.Tasks;
|
||||||
using System.Text;
|
|
||||||
using Flurl.Http;
|
using Flurl.Http;
|
||||||
using InnovEnergy.App.SaliMax.Devices;
|
using InnovEnergy.App.SaliMax.Devices;
|
||||||
using InnovEnergy.App.SaliMax.Ess;
|
using InnovEnergy.App.SaliMax.Ess;
|
||||||
|
@ -24,9 +19,8 @@ using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Channels;
|
using InnovEnergy.Lib.Protocols.Modbus.Channels;
|
||||||
using InnovEnergy.Lib.Units;
|
using InnovEnergy.Lib.Units;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
using System.Text.Json;
|
using InnovEnergy.App.SaliMax.AggregationService;
|
||||||
using InnovEnergy.App.SaliMax.DataTypes;
|
using InnovEnergy.App.SaliMax.DataTypes;
|
||||||
using static System.Double;
|
|
||||||
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig;
|
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig;
|
||||||
using DeviceState = InnovEnergy.App.SaliMax.Devices.DeviceState;
|
using DeviceState = InnovEnergy.App.SaliMax.Devices.DeviceState;
|
||||||
|
|
||||||
|
@ -86,7 +80,7 @@ internal static class Program
|
||||||
public static async Task Main(String[] args)
|
public static async Task Main(String[] args)
|
||||||
{
|
{
|
||||||
//Do not await
|
//Do not await
|
||||||
HourlyDataAggregationManager();
|
Aggregator.HourlyDataAggregationManager();
|
||||||
MiddlewareAgent.InitializeCommunicationToMiddleware();
|
MiddlewareAgent.InitializeCommunicationToMiddleware();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -533,165 +527,6 @@ internal static class Program
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task HourlyDataAggregationManager()
|
|
||||||
{
|
|
||||||
DateTime currentDateTime = DateTime.Now;
|
|
||||||
DateTime nextRoundedHour = currentDateTime.AddHours(1).AddMinutes(-currentDateTime.Minute).AddSeconds(-currentDateTime.Second);
|
|
||||||
|
|
||||||
// Calculate the time until the next rounded hour
|
|
||||||
TimeSpan timeUntilNextHour = nextRoundedHour - currentDateTime;
|
|
||||||
|
|
||||||
// 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 " + timeUntilNextHour.TotalMinutes + " minutes...");
|
|
||||||
|
|
||||||
// Wait until the next rounded hour
|
|
||||||
await Task.Delay(timeUntilNextHour);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CreateHourlyAverage();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine("An error has occured when calculating hourly aggregated data, exception is:\n" + e);
|
|
||||||
}
|
|
||||||
await Task.Delay(TimeSpan.FromHours(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CreateHourlyAverage()
|
|
||||||
{
|
|
||||||
var myDirectory = "LogDirectory";
|
|
||||||
|
|
||||||
// Get all CSV files in the specified directory
|
|
||||||
var csvFiles = Directory.GetFiles(myDirectory, "*.csv");
|
|
||||||
|
|
||||||
var currentTimestamp = DateTime.Now.ToUnixTime();
|
|
||||||
Double socAverage = 0;
|
|
||||||
Double pvPowerAverage = 0;
|
|
||||||
Double batteryPowerAverage = 0;
|
|
||||||
|
|
||||||
Console.WriteLine("-----------------------------------------------------------------------------------------------------------------");
|
|
||||||
Console.WriteLine("File timestamp should start after "+ DateTime.Now.AddHours(-1));
|
|
||||||
|
|
||||||
foreach (var csvFile in csvFiles)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (csvFile == "LogDirectory/log.csv")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var fileTimestamp = long.Parse(Path.GetFileNameWithoutExtension(csvFile).Replace("log_", ""));
|
|
||||||
var oneHourBefore = DateTime.Now.AddHours(-1).ToUnixTime();
|
|
||||||
|
|
||||||
|
|
||||||
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}");
|
|
||||||
|
|
||||||
Console.WriteLine("CSV data reading and storage completed.");
|
|
||||||
//Create a new file to folder "Hourly Aggregated Data and push it to S3"
|
|
||||||
Console.WriteLine("-----------------------------------------------------------------------------------------------------------------");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Custom method to check if a string is numeric
|
|
||||||
private static bool IsSoc(string value)
|
|
||||||
{
|
|
||||||
return value == "/Battery/Soc";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsPvPower(string value)
|
|
||||||
{
|
|
||||||
return value == "/PvOnDc/Dc/Power";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsBatteryPower(string value)
|
|
||||||
{
|
|
||||||
return value == "/Battery/Dc/Power";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ApplyConfigFile(this StatusRecord status, Configuration? config)
|
private static void ApplyConfigFile(this StatusRecord status, Configuration? config)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue