160 lines
6.5 KiB
C#
160 lines
6.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using InnovEnergy.App.SinexcelCommunication.ESS;
|
|
|
|
namespace InnovEnergy.App.SinexcelCommunication.AggregationService;
|
|
|
|
public class HourlyAccumulator
|
|
{
|
|
public DateTime HourStart { get; set; }
|
|
|
|
public double StartSelfGeneratedElectricity { get; set; }
|
|
public double StartElectricityPurchased { get; set; }
|
|
public double StartElectricityFed { get; set; }
|
|
public double StartBatteryChargeEnergy { get; set; }
|
|
public double StartBatteryDischargeEnergy { get; set; }
|
|
public double StartLoadPowerConsumption { get; set; }
|
|
|
|
public double LastSelfGeneratedElectricity { get; set; }
|
|
public double LastElectricityPurchased { get; set; }
|
|
public double LastElectricityFed { get; set; }
|
|
public double LastBatteryChargeEnergy { get; set; }
|
|
public double LastBatteryDischargeEnergy { get; set; }
|
|
public double LastLoadPowerConsumption { get; set; }
|
|
}
|
|
|
|
public static class EnergyAggregation
|
|
{
|
|
private static HourlyAccumulator? _currentHourAccumulator;
|
|
private static DateTime? _lastDailySaveDate;
|
|
|
|
|
|
public static HourlyEnergyData? ProcessHourlyData(StatusRecord statusRecord, DateTime timestamp)
|
|
{
|
|
var r = statusRecord.InverterRecord;
|
|
var hourStart = new DateTime(timestamp.Year, timestamp.Month, timestamp.Day, timestamp.Hour, 0, 0);
|
|
|
|
// First call
|
|
if (_currentHourAccumulator == null)
|
|
{
|
|
_currentHourAccumulator = new HourlyAccumulator
|
|
{
|
|
HourStart = hourStart,
|
|
|
|
StartSelfGeneratedElectricity = r.SelfGeneratedElectricity,
|
|
StartElectricityPurchased = r.ElectricityPurchased,
|
|
StartElectricityFed = r.ElectricityFed,
|
|
StartBatteryChargeEnergy = r.BatteryChargeEnergy,
|
|
StartBatteryDischargeEnergy = r.BatteryDischargeEnergy,
|
|
StartLoadPowerConsumption = r.LoadPowerConsumption,
|
|
|
|
LastSelfGeneratedElectricity = r.SelfGeneratedElectricity,
|
|
LastElectricityPurchased = r.ElectricityPurchased,
|
|
LastElectricityFed = r.ElectricityFed,
|
|
LastBatteryChargeEnergy = r.BatteryChargeEnergy,
|
|
LastBatteryDischargeEnergy = r.BatteryDischargeEnergy,
|
|
LastLoadPowerConsumption = r.LoadPowerConsumption
|
|
};
|
|
|
|
return null;
|
|
}
|
|
|
|
// Still same hour → just update last values
|
|
if (_currentHourAccumulator.HourStart == hourStart)
|
|
{
|
|
_currentHourAccumulator.LastSelfGeneratedElectricity = r.SelfGeneratedElectricity;
|
|
_currentHourAccumulator.LastElectricityPurchased = r.ElectricityPurchased;
|
|
_currentHourAccumulator.LastElectricityFed = r.ElectricityFed;
|
|
_currentHourAccumulator.LastBatteryChargeEnergy = r.BatteryChargeEnergy;
|
|
_currentHourAccumulator.LastBatteryDischargeEnergy = r.BatteryDischargeEnergy;
|
|
_currentHourAccumulator.LastLoadPowerConsumption = r.LoadPowerConsumption;
|
|
|
|
return null;
|
|
}
|
|
|
|
// Hour changed → finalize previous hour
|
|
var completedHour = new HourlyEnergyData
|
|
{
|
|
Timestamp = _currentHourAccumulator.HourStart,
|
|
|
|
SelfGeneratedElectricity = SafeDiff(
|
|
_currentHourAccumulator.LastSelfGeneratedElectricity,
|
|
_currentHourAccumulator.StartSelfGeneratedElectricity),
|
|
|
|
ElectricityPurchased = SafeDiff(
|
|
_currentHourAccumulator.LastElectricityPurchased,
|
|
_currentHourAccumulator.StartElectricityPurchased),
|
|
|
|
ElectricityFed = SafeDiff(
|
|
_currentHourAccumulator.LastElectricityFed,
|
|
_currentHourAccumulator.StartElectricityFed),
|
|
|
|
BatteryChargeEnergy = SafeDiff(
|
|
_currentHourAccumulator.LastBatteryChargeEnergy,
|
|
_currentHourAccumulator.StartBatteryChargeEnergy),
|
|
|
|
BatteryDischargeEnergy = SafeDiff(
|
|
_currentHourAccumulator.LastBatteryDischargeEnergy,
|
|
_currentHourAccumulator.StartBatteryDischargeEnergy),
|
|
|
|
LoadPowerConsumption = SafeDiff(
|
|
_currentHourAccumulator.LastLoadPowerConsumption,
|
|
_currentHourAccumulator.StartLoadPowerConsumption)
|
|
};
|
|
|
|
// Start new hour with current sample
|
|
_currentHourAccumulator = new HourlyAccumulator
|
|
{
|
|
HourStart = hourStart,
|
|
|
|
StartSelfGeneratedElectricity = r.SelfGeneratedElectricity,
|
|
StartElectricityPurchased = r.ElectricityPurchased,
|
|
StartElectricityFed = r.ElectricityFed,
|
|
StartBatteryChargeEnergy = r.BatteryChargeEnergy,
|
|
StartBatteryDischargeEnergy = r.BatteryDischargeEnergy,
|
|
StartLoadPowerConsumption = r.LoadPowerConsumption,
|
|
|
|
LastSelfGeneratedElectricity = r.SelfGeneratedElectricity,
|
|
LastElectricityPurchased = r.ElectricityPurchased,
|
|
LastElectricityFed = r.ElectricityFed,
|
|
LastBatteryChargeEnergy = r.BatteryChargeEnergy,
|
|
LastBatteryDischargeEnergy = r.BatteryDischargeEnergy,
|
|
LastLoadPowerConsumption = r.LoadPowerConsumption
|
|
};
|
|
|
|
return completedHour;
|
|
}
|
|
|
|
public static DailyEnergyData? TryCreateDailyData(StatusRecord statusRecord, DateTime timestamp)
|
|
{
|
|
if (timestamp is { Hour: 23, Minute: 59 })
|
|
{
|
|
if (_lastDailySaveDate != timestamp.Date)
|
|
{
|
|
_lastDailySaveDate = timestamp.Date;
|
|
|
|
var r = statusRecord.InverterRecord;
|
|
|
|
return new DailyEnergyData
|
|
{
|
|
Timestamp = timestamp,
|
|
|
|
DailySelfGeneratedElectricity = r.DailySelfGeneratedElectricity,
|
|
DailyElectricityPurchased = r.DailyElectricityPurchased,
|
|
DailyElectricityFed = r.DailyElectricityFed,
|
|
BatteryDailyChargeEnergy = r.BatteryDailyChargeEnergy,
|
|
BatteryDailyDischargeEnergy = r.BatteryDailyDischargeEnergy,
|
|
DailyLoadPowerConsumption = r.DailyLoadPowerConsumption
|
|
};
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static double SafeDiff(double endValue, double startValue)
|
|
{
|
|
var diff = endValue - startValue;
|
|
return diff < 0 ? 0 : diff;
|
|
}
|
|
} |