Skip to content
This repository has been archived by the owner on Jan 8, 2025. It is now read-only.

Optimiser avalonia #27

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"args": [],
"cwd": "${workspaceFolder}/HeatOptimiser",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"console": "externalTerminal",
"stopAtEntry": false
},
{
Expand Down
38 changes: 19 additions & 19 deletions HeatOptimiser/Classes/AssetManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ public bool IsSelected
}
public static class AssetManager
{
public static string saveFileName = "ProductionAssets.json";
public static ObservableCollection<ProductionAsset> _productionAssets = new ObservableCollection<ProductionAsset>();
private static JsonAssetStorage _jsonAssetStorage = new JsonAssetStorage();
private static JsonAssetStorage _jsonAssetStorage = new JsonAssetStorage("ProductionAssets.json");
public static void AddUnit(string name, string image, double heat, double electricity, double energy, double cost, double carbonDioxide)
{
if (name != null && image != null && !string.IsNullOrWhiteSpace(name) && !string.IsNullOrWhiteSpace(image))
Expand All @@ -92,7 +91,7 @@ public static void AddUnit(string name, string image, double heat, double electr
CarbonDioxide = carbonDioxide,
IsSelected = false
});
_jsonAssetStorage.SaveUnits(_productionAssets, saveFileName); // this is up for debate, I just want to auto save, and they likely wont have thousands of production units, that could cause a performance issue.
_jsonAssetStorage.SaveUnits(_productionAssets); // this is up for debate, I just want to auto save, and they likely wont have thousands of production units, that could cause a performance issue.
}
else
{
Expand All @@ -102,7 +101,7 @@ public static void AddUnit(string name, string image, double heat, double electr
public static void DeleteUnit(Guid ID)
{
_productionAssets.Remove(_productionAssets.FirstOrDefault(x => x.ID == ID)!);
_jsonAssetStorage.SaveUnits(_productionAssets, saveFileName); // this is also up for debate, just like on AddUnit.
_jsonAssetStorage.SaveUnits(_productionAssets); // this is also up for debate, just like on AddUnit.
}
public static void EditUnit(Guid ID, int index, string stringValue)
{
Expand All @@ -117,7 +116,7 @@ public static void EditUnit(Guid ID, int index, string stringValue)
default:
throw new ArgumentOutOfRangeException("Index out of range or wrong type used");
}
_jsonAssetStorage.SaveUnits(_productionAssets, saveFileName); // this is also up for debate, just like on AddUnit.
_jsonAssetStorage.SaveUnits(_productionAssets); // this is also up for debate, just like on AddUnit.
}
public static void EditUnit(Guid ID, int index, double doubleValue)
{
Expand All @@ -141,39 +140,40 @@ public static void EditUnit(Guid ID, int index, double doubleValue)
default:
throw new ArgumentOutOfRangeException("Index out of range or wrong type used");
}
_jsonAssetStorage.SaveUnits(_productionAssets, saveFileName); // this is also up for debate, just like on AddUnit.
_jsonAssetStorage.SaveUnits(_productionAssets); // this is also up for debate, just like on AddUnit.
}
public static ObservableCollection<ProductionAsset> GetAllUnits()
{
return _productionAssets;
}
public static ObservableCollection<ProductionAsset> LoadUnits(string fileName)
public static ObservableCollection<ProductionAsset> LoadUnits()
{
_productionAssets = _jsonAssetStorage.LoadUnits(fileName);
_productionAssets = _jsonAssetStorage.LoadUnits();
return _productionAssets;
}
public static void SaveUnits(ObservableCollection<ProductionAsset> AllAssets, string fileName)
public static void SaveUnits(ObservableCollection<ProductionAsset> AllAssets)
{
_jsonAssetStorage.SaveUnits(AllAssets, fileName);
_jsonAssetStorage.SaveUnits(AllAssets);
}
public static ObservableCollection<ProductionAsset> SearchUnits(string name)
{
var selection = _productionAssets.Where(x => x.Name!.ToLower().Contains(name.ToLower())).ToList();
ObservableCollection<ProductionAsset> selected = [.. selection];
return selected;
}
public static void SetSaveFile(string fileName)
{
saveFileName = fileName;
}
}
public class JsonAssetStorage
{
public ObservableCollection<ProductionAsset> LoadUnits(string fileName)
private string filePath;
public JsonAssetStorage(string passedFilePath)
{
filePath = passedFilePath;
}
public ObservableCollection<ProductionAsset> LoadUnits()
{
if (File.Exists(fileName) && new FileInfo(fileName).Length > 2)
if (File.Exists(filePath) && new FileInfo(filePath).Length > 2)
{
string jsonString = File.ReadAllText(fileName);
string jsonString = File.ReadAllText(filePath);
try
{
var info = JsonSerializer.Deserialize<ObservableCollection<ProductionAsset>>(jsonString)!;
Expand All @@ -189,10 +189,10 @@ public ObservableCollection<ProductionAsset> LoadUnits(string fileName)
return new ObservableCollection<ProductionAsset>();
}
}
public void SaveUnits(ObservableCollection<ProductionAsset> AllAssets, string fileName)
public void SaveUnits(ObservableCollection<ProductionAsset> AllAssets)
{
string jsonString = JsonSerializer.Serialize(AllAssets);
File.WriteAllText(fileName, jsonString);
File.WriteAllText(filePath, jsonString);
}
}

Expand Down
5 changes: 4 additions & 1 deletion HeatOptimiser/Classes/Optimiser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ public static class Optimiser
public static Schedule Optimise(DateTime startDate, DateTime endDate, OptimisationChoice optimisationChoice)
{
SourceData data = new();
data.LoadedData = new List<SourceDataPoint>(); // Initialize LoadedData
if (data.LoadedData == null)
{
data.LoadedData = new List<SourceDataPoint>(); // Initialize LoadedData
}
Schedule schedule = new(startDate, endDate);

ObservableCollection<ProductionAsset> assets = AssetManager.GetAllUnits();
Expand Down
35 changes: 35 additions & 0 deletions HeatOptimiser/Classes/ResultsDataManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,40 @@ public static Schedule Load(DateOnly dateFrom, DateOnly dateTo)

return schedule;
}

public static Schedule LoadAll()
{
var csvConfig = new CsvConfiguration(CultureInfo.CurrentCulture)
{
HasHeaderRecord = false
};

using var streamReader = File.OpenText(filePath);
using var csvReader = new CsvReader(streamReader, csvConfig);

DateTime minDate = DateTime.MaxValue;
DateTime maxDate = DateTime.MinValue;

while (csvReader.Read())
{
string dateString = csvReader.GetField<string>(0);
DateTime date = DateTime.ParseExact(dateString, "dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture);

if (date < minDate)
{
minDate = date;
}

if (date > maxDate)
{
maxDate = date;
}
}

DateOnly minDateOnly = new DateOnly(minDate.Year, minDate.Month, minDate.Day);
DateOnly maxDateOnly = new DateOnly(maxDate.Year, maxDate.Month, maxDate.Day);

return Load(minDateOnly, maxDateOnly);
}
}
}
2 changes: 1 addition & 1 deletion HeatOptimiser/ProductionAssets.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"ID":"f728fabf-b907-41bb-a0d5-91f699d20a85","Name":"GB","Image":"none","Heat":5,"Electricity":0,"Energy":1.1,"Cost":500,"CarbonDioxide":215,"IsSelected":false},{"ID":"33a34683-f561-4265-a70b-c8868407cce2","Name":"OB","Image":"none","Heat":4,"Electricity":0,"Energy":1.2,"Cost":700,"CarbonDioxide":265,"IsSelected":false}]
[{"ID":"c3761220-d94f-4bec-aebd-8abac8213c27","Name":"GB","Image":"none","Heat":1,"Electricity":0,"Energy":1.1,"Cost":500,"CarbonDioxide":215,"IsSelected":false},{"ID":"ee713af7-4105-476b-990a-31ce4a15d45a","Name":"OB","Image":"none","Heat":4,"Electricity":0,"Energy":1.2,"Cost":700,"CarbonDioxide":265,"IsSelected":false},{"ID":"9da179f9-cb21-4f97-8fff-069184e7846b","Name":"GM","Image":"none","Heat":3.6,"Electricity":2.7,"Energy":1.9,"Cost":1100,"CarbonDioxide":640,"IsSelected":false},{"ID":"5829bc61-be56-4f67-8803-609de7217e68","Name":"EK","Image":"none","Heat":8,"Electricity":-8,"Energy":0,"Cost":50,"CarbonDioxide":0,"IsSelected":false}]
4 changes: 2 additions & 2 deletions HeatOptimiser/ViewModels/AssetManagerViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
public string AssetCarbon{get =>_assetCarbon;
set=> this.RaiseAndSetIfChanged(ref _assetCarbon, value);
}
public NewAsset(string n, string h, string elec, string ener, string cost, string carbon)

Check warning on line 57 in HeatOptimiser/ViewModels/AssetManagerViewModel.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_assetName' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 57 in HeatOptimiser/ViewModels/AssetManagerViewModel.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_assetHeat' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 57 in HeatOptimiser/ViewModels/AssetManagerViewModel.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_assetElectricity' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
{
AssetName=n;
AssetHeat=h;
Expand Down Expand Up @@ -210,7 +210,7 @@
}
public void EditAsset()
{
AssetManager.SaveUnits(ProductionAssets, "ProductionAssets.json");
AssetManager.SaveUnits(ProductionAssets);

}
public void ValidateInput(string input)
Expand All @@ -225,7 +225,7 @@
DeleteAssetCommand=ReactiveCommand.Create(DeleteAsset);
UpdateAssetCommand=ReactiveCommand.Create(EditAsset);
//assetManager.SaveUnits(ProductionAssets, assetManager.saveFileName);
ProductionAssets=AssetManager.LoadUnits(AssetManager.saveFileName);
ProductionAssets=AssetManager.LoadUnits();
}

}
87 changes: 3 additions & 84 deletions HeatOptimiser/ViewModels/HomepageViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,95 +20,14 @@ public int AssetCount
set => this.RaiseAndSetIfChanged(ref _assetCount, value);
}

private readonly ObservableCollection<DateTimePoint> _heatDemandData;
private readonly ObservableCollection<DateTimePoint> _electricityPriceData;
private string _sourceText;


public string SourceText
{
get => _sourceText;
set => this.RaiseAndSetIfChanged(ref _sourceText, value);
}

public ObservableCollection<ISeries> Series { get; set; }

public Axis[] XAxes { get; set; }
public Axis[] YAxes { get; set; }


public HomepageViewModel()
{
_heatDemandData = new ObservableCollection<DateTimePoint>();
_electricityPriceData = new ObservableCollection<DateTimePoint>();
_sourceText = "Source Data not loaded. \nPlease load the data.";
_assetCount = AssetManager.LoadUnits(AssetManager.saveFileName).Count;

if (SettingsManager.GetSetting("DataLoaded") == "True")
{
_sourceText = "Source Data loaded.";
foreach (var point in DataVisualizer.sourceData.LoadedData)
{
if (point.HeatDemand.HasValue && point.TimeFrom.HasValue && point.ElectricityPrice.HasValue)
{
_heatDemandData.Add(new DateTimePoint(point.TimeFrom.Value, point.HeatDemand.Value));
_electricityPriceData.Add(new DateTimePoint(point.TimeFrom.Value, point.ElectricityPrice.Value));

Console.WriteLine($"Added Point: TimeFrom={point.TimeFrom.Value}, HeatDemand={point.HeatDemand.Value}, ElectricityPrice={point.ElectricityPrice.Value}");
}
}
}

Series = new ObservableCollection<ISeries>
{
new LineSeries<DateTimePoint>
{
Values = _heatDemandData,
Name = "Heat Demand (MWh)",
Fill = null,
GeometryStroke = null,
GeometryFill = null,
LineSmoothness = 1,
Stroke = new SolidColorPaint(new SKColor(194, 36, 62))
{
StrokeThickness = 3 // Set the thickness of the Heat Demand line
}
},
new LineSeries<DateTimePoint>
{
Values = _electricityPriceData,
Name = "Electricity Price (€/MWh)",
Fill = null,
GeometryStroke = null,
GeometryFill = null,
LineSmoothness = 2,
ScalesYAt = 1, // This tells the series to use the secondary Y-axis
Stroke = new SolidColorPaint(new SKColor(0, 92, 230)) // Set the color shade
{
StrokeThickness = 3 // Set the thickness of the Electricity Price line
},
}
};

XAxes = new Axis[]
{
new DateTimeAxis(TimeSpan.FromDays(1), date => date.ToString("MMMM dd HH:mm"))
};
_assetCount = AssetManager.LoadUnits().Count;

YAxes = new Axis[]
{
new Axis
{
Name = "Heat Demand (MWh)",
TextSize = 16,
NameTextSize = 18
},
new Axis
{
Name = "Electricity Price (€/MWh)",
TextSize = 16,
NameTextSize = 18,
Position = LiveChartsCore.Measure.AxisPosition.End
}
};
}
}
}
Expand Down
30 changes: 26 additions & 4 deletions HeatOptimiser/ViewModels/OptimiserViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,44 @@ public DateTime EndingDate
set => this.RaiseAndSetIfChanged(ref _endingDate, value);
}
public ReactiveCommand<Unit, Unit> OptimiseCommand { get; }
private int _selectedCategoryIndex;
public int SelectedCategoryIndex
{
get => _selectedCategoryIndex;
set => this.RaiseAndSetIfChanged(ref _selectedCategoryIndex, value);
}

public void Optimise(DateTime start, DateTime end )
public void Optimise(DateTime start, DateTime end, int categoryIndex)
{
Console.WriteLine("Testing");
Schedule optimisedData = Optimiser.Optimise(start, end, OptimisationChoice.Cost); //change OptimisationChoice.Cost to correspond with users choice - third argument should be something like OptimisationChoice[OptimisationCategory.SelectedIndex]
Console.WriteLine($"Testing {categoryIndex} optimisation.");

OptimisationChoice choice;
if (categoryIndex == 0)
{
choice = OptimisationChoice.Cost;
}
else
{
choice = OptimisationChoice.Emissions;
}
Schedule optimisedData = Optimiser.Optimise(start, end, choice);
ResultsDataManager.Save(optimisedData);

Console.WriteLine(StartingDate);
Console.WriteLine("Optimised Schedule:");
foreach (var hour in optimisedData.schedule)
{
Console.WriteLine($"Hour: {hour.Hour}, Assets: {string.Join(",", hour.Assets!)}, Demands: {string.Join(",", hour.Demands!)}");
foreach (var asset in hour.Assets!)
{
Console.WriteLine($"Asset: {asset.Name}, Heat: {asset.Heat}, Demand {hour.Demands![hour.Assets!.IndexOf(asset)]}");
}
}
}

public OptimiserViewModel()
{
Console.WriteLine("OptimiserViewModel created");
OptimiseCommand=ReactiveCommand.Create(()=> Optimise(_startingDate, _endingDate));
OptimiseCommand=ReactiveCommand.Create(()=> Optimise(_startingDate, _endingDate, _selectedCategoryIndex));
}
}
Loading
Loading