diff --git a/src/apps/api/Repository/BusinessBestSolarPanelsRepository.cs b/src/apps/api/Repository/BusinessBestSolarPanelsRepository.cs index 31799f6a..04f9f4cc 100644 --- a/src/apps/api/Repository/BusinessBestSolarPanelsRepository.cs +++ b/src/apps/api/Repository/BusinessBestSolarPanelsRepository.cs @@ -8,8 +8,9 @@ public class BusinessBestSolarPanelsRepository private SharedUtils.locationDataClass locationDataClass = new SharedUtils.locationDataClass(); private DataHandlers.SolarDataHandler solarCalculator = new DataHandlers.SolarDataHandler(); private DataHandlers.RooftopDataHandler rooftopDataHandler = new DataHandlers.RooftopDataHandler(); - private SharedUtils.otherDataClass otherDataClass = new SharedUtils.otherDataClass(); private string locationName = ""; + private string? mapboxAccessToken = Environment.GetEnvironmentVariable("MAP_BOX_API_KEY"); + public async Task GetProcessedDataAsync(BestSolarPanelsInput bestSolarPanelsInput) { @@ -32,7 +33,7 @@ public async Task GetProcessedDataAsync(BestSolarPanelsInput bestSolarPa } LocationDataModel? locationData = await locationDataClass.GetLocationData(latitude, longitude); - locationName = await otherDataClass.GetLocationNameFromCoordinates(latitude, longitude); + locationName = await GetLocationNameFromCoordinates(latitude, longitude); if (locationData == null) { await locationDataClass.CreateLocationData(latitude, longitude, locationName); @@ -82,4 +83,28 @@ private async Task GetLocationDataModel(double latitude, doub } return locationData!; } + public async Task GetLocationNameFromCoordinates(double latitude, double longitude) + { + string baseUrl = "https://api.mapbox.com/geocoding/v5/mapbox.places/"; + string requestUrl = + $"{baseUrl}{longitude.ToString().Replace(",", ".")},{latitude.ToString().Replace(",", ".")}.json?&access_token={mapboxAccessToken}"; + + try + { + HttpClient httpClient = new HttpClient(); + var mapResponse = await httpClient.GetFromJsonAsync(requestUrl); + return mapResponse?.Features[0].Place_Name ?? ""; + } + catch (Exception ex) + { + // Handle any errors or exceptions + Console.WriteLine(ex.Message); + return ""; + } + + } + private class GeocodingResponse + { + public List Features { get; set; } = new List(); + } } diff --git a/src/apps/api/Repository/BusinessRequestDataRepository.cs b/src/apps/api/Repository/BusinessRequestDataRepository.cs index a6d3d84b..45524f3a 100644 --- a/src/apps/api/Repository/BusinessRequestDataRepository.cs +++ b/src/apps/api/Repository/BusinessRequestDataRepository.cs @@ -1,4 +1,7 @@ using Newtonsoft.Json; +using System.Text.Json; +using System.Net.Http.Json; +using System.Net; namespace Api.Repository; @@ -12,14 +15,11 @@ private struct DataType { public const string SUNLIGHT_HOURS = "sunlight hours"; } - private SharedUtils.locationDataClass locationDataClass = new SharedUtils.locationDataClass(); + private string? mapboxAccessToken = Environment.GetEnvironmentVariable("MAP_BOX_API_KEY"); private DataHandlers.SolarDataHandler solarCalculator = new DataHandlers.SolarDataHandler(); private DataHandlers.RooftopDataHandler rooftopDataHandler = new DataHandlers.RooftopDataHandler(); - private SharedUtils.otherDataClass otherDataClass = new SharedUtils.otherDataClass(); private DataHandlers.SolarDataHandler solarDataHandler = new DataHandlers.SolarDataHandler(); - // private DataHandlers.RooftopDataHandler rooftopDataHandler = new DataHandlers.RooftopDataHandler(); private string locationName = ""; - private string express = "http://localhost:3333"; private string? API_PORT = Environment.GetEnvironmentVariable("API_PORT"); public BusinessRequestDataRepository() @@ -44,11 +44,11 @@ public async Task GetProcessedDataAsync(BusinessRequestData requestData) var client = new HttpClient(); var dataTypeResponse = new HttpResponseMessage(); - LocationDataModel? locationData = await locationDataClass.GetLocationData(latitude, longitude); - locationName = await otherDataClass.GetLocationNameFromCoordinates(latitude, longitude); + LocationDataModel? locationData = await GetLocationData(latitude, longitude); + locationName = await GetLocationNameFromCoordinates(latitude, longitude); if (locationData == null) { - await locationDataClass.CreateLocationData(latitude, longitude, locationName); + await CreateLocationData(latitude, longitude, locationName); } typeOfData = data!; @@ -127,13 +127,156 @@ private Address getAddress(){ private async Task GetLocationDataModel(double latitude, double longitude) { - LocationDataModel? locationData = await locationDataClass.GetLocationData(latitude, longitude); + LocationDataModel? locationData = await GetLocationData(latitude, longitude); if(locationData==null){ - locationData = await locationDataClass.CreateLocationData(latitude, longitude, locationName); + await CreateLocationData(latitude, longitude, locationName); + locationData = await GetLocationData(latitude, longitude); } return locationData!; } - + public async Task GetLocationData(double latitude, double longitude) + { + try + { + var client = new HttpClient(); + var request = new HttpRequestMessage( + HttpMethod.Get, + express + "/api/locationData/" + latitude + "/" + longitude + ); + Console.WriteLine("Getting LocationData for " + latitude + ", " + longitude); + var response = await client.SendAsync(request); + + if (response.IsSuccessStatusCode) + { + string data = response.Content.ReadAsStringAsync().Result; + LocationDataModelTemp locationDataTemp = System.Text.Json.JsonSerializer.Deserialize(data)!; + LocationDataModel locationData = new LocationDataModel() + { + latitude = locationDataTemp.latitude, + longitude = locationDataTemp.longitude, + locationName = locationDataTemp.locationName, + solarPanelsData = System.Text.Json.JsonSerializer.Deserialize(locationDataTemp.solarPanelsData!), + satteliteImageData = Convert.FromBase64String(locationDataTemp.satteliteImageData!), + annualFluxData = Convert.FromBase64String(locationDataTemp.annualFluxData!), + monthlyFluxData = Convert.FromBase64String(locationDataTemp.monthlyFluxData!), + maskData = Convert.FromBase64String(locationDataTemp.maskData!), + dateCreated = locationDataTemp.dateCreated, + horisonElevationData = locationDataTemp.horisonElevationData + }; + return locationData!; + }else if (response.StatusCode == HttpStatusCode.NotFound) + { + Console.WriteLine(".NET LocationData not found"); + return null!; + } + else + { + Console.WriteLine(".NET Error getting LocationData"); + throw new Exception("Error getting LocationData"); + } + + } + catch (System.Exception) + { + throw new Exception("Could not get LocationData"); + } + } + + public async Task CreateLocationData( + double latitude, + double longitude, + string locationName + + ) + { + + + LocationDataModel? locationData = await GetLocationDataModel(latitude, longitude); + if(locationData!=null){ + return "LocationData could not be created"; + } + string solarPanelsData = locationData!.solarPanelsData!.ToString()!; + byte[] satteliteImageData = locationData!.satteliteImageData!; + byte[] annualFluxData = locationData!.annualFluxData!; + byte[] monthlyFluxData = locationData!.monthlyFluxData!; + byte[] maskData = locationData!.maskData!; + string horisonElevationData = locationData!.horisonElevationData!; + try + { + var client = new HttpClient(); + var request = new HttpRequestMessage( + HttpMethod.Post, + express + "/api/locationData/create" + ); + string satteliteImageDataBase64 = Convert.ToBase64String(satteliteImageData); + string annualFluxDataBase64 = Convert.ToBase64String(annualFluxData); + string monthlyFluxDataBase64 = Convert.ToBase64String(monthlyFluxData); + string maskDataBase64 = Convert.ToBase64String(maskData); + var postData = new + { + latitude = latitude.ToString(), + longitude = longitude.ToString(), + locationName = locationName, + solarPanelsData = solarPanelsData, + satteliteImageData = satteliteImageDataBase64, + annualFluxData = annualFluxDataBase64, + monthlyFluxData = monthlyFluxDataBase64, + maskData = maskDataBase64, + horisonElevationData = horisonElevationData + }; + + var json = System.Text.Json.JsonSerializer.Serialize(postData); + request.Content = new StringContent(json, null, "application/json"); + // Console.WriteLine(await request.Content.ReadAsStringAsync()); + var response = await client.SendAsync(request); + if (response.IsSuccessStatusCode) + { + Console.WriteLine(".NET LocationData created successfully"); + return "LocationData created successfully"; + } + else if (response.StatusCode == HttpStatusCode.BadRequest) + { + Console.WriteLine(".NET Bad Request When Creating LocationData"); + // Get error + string data = response.Content.ReadAsStringAsync().Result; + return data; + } + else + { + Console.WriteLine(".NET Error creating LocationData"); + throw new Exception("Error creating LocationData"); + } + + } + catch (System.Exception) + { + throw new Exception("Could not create locationData"); + } + } + + public async Task GetLocationNameFromCoordinates(double latitude, double longitude) + { + string baseUrl = "https://api.mapbox.com/geocoding/v5/mapbox.places/"; + string requestUrl = + $"{baseUrl}{longitude.ToString().Replace(",", ".")},{latitude.ToString().Replace(",", ".")}.json?&access_token={mapboxAccessToken}"; + + try + { + HttpClient httpClient = new HttpClient(); + var mapResponse = await httpClient.GetFromJsonAsync(requestUrl); + return mapResponse?.Features[0].Place_Name ?? ""; + } + catch (Exception ex) + { + // Handle any errors or exceptions + Console.WriteLine(ex.Message); + return ""; + } + } + private class GeocodingResponse + { + public List Features { get; set; } = new List(); + } } \ No newline at end of file diff --git a/src/apps/blazor-app/Components/Advanced/BuildYourHome.razor b/src/apps/blazor-app/Components/Advanced/BuildYourHome.razor index 44744fee..30f5764e 100644 --- a/src/apps/blazor-app/Components/Advanced/BuildYourHome.razor +++ b/src/apps/blazor-app/Components/Advanced/BuildYourHome.razor @@ -344,16 +344,11 @@
- @{ - if (dlh == (24 - daylight)) - { -

@dlh+

- } - else - { -

@dlh

- } - } + @if(float.IsInfinity(dlh)) { +

12+

+ } else { +

@dlh

+ }

h

@@ -769,10 +764,6 @@ double runningHours = chargingLimit / appliancePowerUsage; double runningHoursPercentage = (runningHours / daylight) * 100; - if (runningHoursPercentage > 100) - { - runningHoursPercentage = 100; - } dlh = (float)Math.Round((24 - daylight) * (runningHoursPercentage / 100), 2); } diff --git a/src/apps/blazor-app/Components/Advanced/Variants.razor b/src/apps/blazor-app/Components/Advanced/Variants.razor index 9264b4f6..c4838788 100644 --- a/src/apps/blazor-app/Components/Advanced/Variants.razor +++ b/src/apps/blazor-app/Components/Advanced/Variants.razor @@ -1,5 +1,7 @@ @inject BlazorApp.Data.ApplianceService applianceService @using System.Text.Json; +@inject BlazorApp.Data.ToastService toastService +
@@ -8,34 +10,42 @@

Once appliances have been added to the calculation with the tool above - specific models of those appliances with their associated power usage can be specified below. If you cannot find your appliance in the list of appliance models below, you can specify the power usage of your appliance by selecting custom appliance

-
- @if (appliances != null) - { - if(appliances.FindAll(x => x.quantity > 0 && x.type == selectedAppliance).Count == 0) { - selectedAppliance = ""; - } - applianceCount = appliances.Count(x => x.quantity > 0); - var i = 0; - - @foreach (var appliance in GetDifferentApplianceGroups()) - { - if (appliance.quantity > 0) +
+
+ Left Arrow +
+
+ @if (appliances != null) + { + if(appliances.FindAll(x => x.quantity > 0 && x.type == selectedAppliance).Count == 0) { + selectedAppliance = ""; + } + applianceCount = appliances.Count(x => x.quantity > 0); + var i = 0; + var selectedAppliances = GetDifferentApplianceGroups().FindAll(x => x.quantity > 0); + applianceNumberOfPage = (int)Math.Ceiling((double)selectedAppliances.Count / 5); + @for (int j = 0; j < 5 && j + appliancesPage*5 < selectedAppliances.Count; j++) { - if(selectedAppliance == "" && appliance.type != null) { - selectedAppliance = appliance.type; - } -
- -
+ if(selectedAppliance == "" && selectedAppliances[j + appliancesPage*5].type != null) { + selectedAppliance = selectedAppliances[j + appliancesPage*5].type!; + } + ApplianceModel? appl = selectedAppliances[j + appliancesPage*5]; +
+ +
+ i++; } - i++; - } - - @if (applianceCount == 0) - { -

No Appliances Selected

+ @if (applianceCount == 0) + { +

No Appliances Selected

+ } } - } +
+
+ Right Arrow +
@if (selectedAppliance != "" && appliances != null && appliances.Where(x => x.type == selectedAppliance)?.LastOrDefault()?.quantity != 0) { @@ -133,13 +143,42 @@ [Parameter] public List? customAppliances { get; set; } private DataHandlers.SystemsDataHandler systemsDataHandler = new DataHandlers.SystemsDataHandler(); - @inject BlazorApp.Data.ToastService toastService + + private int appliancesPage = 0; + private int applianceNumberOfPage = 0; + private string applianceAnimation = ""; + protected override void OnInitialized() { applianceService.UpdateAppliancesRequested += UpdateAppliances; } +private async void IncrementAppliancePage(){ + applianceAnimation = "appliance-slide-out-left"; + StateHasChanged(); + await Task.Delay(100); + if(appliancesPage != applianceNumberOfPage - 1){ + appliancesPage++; + } else { + appliancesPage = 0; + } + applianceAnimation = "appliance-slide-in-right"; + StateHasChanged(); + } + private async void DecrementAppliancePage(){ + applianceAnimation = "appliance-slide-out-right"; + StateHasChanged(); + await Task.Delay(100); + if(appliancesPage != 0){ + appliancesPage--; + } else { + appliancesPage = applianceNumberOfPage - 1; + } + applianceAnimation = "appliance-slide-in-left"; + StateHasChanged(); + } + public void UpdateApplianceDuration(ApplianceModel item, ChangeEventArgs e) { item.durationUsed = Convert.ToDouble(e.Value); @@ -274,6 +313,7 @@ public Task SelectAppliance (string appliance) { + Console.WriteLine("Selected Appliance: " + appliance); if (appliance == selectedAppliance) { selectedAppliance = ""; diff --git a/src/apps/blazor-app/Components/ApplianceEnergyConsumption.razor b/src/apps/blazor-app/Components/ApplianceEnergyConsumption.razor index e362f4e9..6bd0eb34 100644 --- a/src/apps/blazor-app/Components/ApplianceEnergyConsumption.razor +++ b/src/apps/blazor-app/Components/ApplianceEnergyConsumption.razor @@ -67,7 +67,7 @@ int[] powerUsageData = new int[reportAllAppliance.Count]; for (int i = 0; i < reportAllAppliance.Count; i++) { - powerUsageData[i] = reportAllAppliance[i].numberOfAppliances * reportAllAppliance[i].defaultPowerUsage; + powerUsageData[i] = (int)(reportAllAppliance[i].numberOfAppliances * reportAllAppliance[i].powerUsage * reportAllAppliance[i].durationUsed); polarAreaConfig.Data.Labels.Add(reportAllAppliance[i].type + " - " + reportAllAppliance[i].applianceModel); } string[] backgroundColor = new string[reportAllAppliance.Count]; diff --git a/src/apps/blazor-app/Components/Base/Appliance.razor b/src/apps/blazor-app/Components/Base/Appliance.razor index 99525162..a1fa56ff 100644 --- a/src/apps/blazor-app/Components/Base/Appliance.razor +++ b/src/apps/blazor-app/Components/Base/Appliance.razor @@ -1,7 +1,7 @@ @using BlazorApp.Components.Base @using BlazorApp.Models -
+
@if(count > 0) {
diff --git a/src/apps/blazor-app/Components/Dashboard/FancyData/FancyData.razor b/src/apps/blazor-app/Components/Dashboard/FancyData/FancyData.razor index 2f921b76..00259f6f 100644 --- a/src/apps/blazor-app/Components/Dashboard/FancyData/FancyData.razor +++ b/src/apps/blazor-app/Components/Dashboard/FancyData/FancyData.razor @@ -163,8 +163,9 @@

Sun path over the horizon

-

Lorem ipsum dolor sit amet, consectetur adipisicing elit. - Asperiores cupiditate impedit ipsam temporibus, dignissimos nostrum.

+

This is a graph showing the path of the sun as it travels + over the address during different times of the year. + The red dot in the center represents the address you typed in.

diff --git a/src/apps/blazor-app/Components/DaylightChart.razor b/src/apps/blazor-app/Components/DaylightChart.razor index 14e9cc85..b13a5796 100644 --- a/src/apps/blazor-app/Components/DaylightChart.razor +++ b/src/apps/blazor-app/Components/DaylightChart.razor @@ -60,6 +60,11 @@ } public void UpdateDataset() { + if(float.IsInfinity(hours)) + { + hours = 12; + } + pieConfig.Data.Datasets.Clear(); pieConfig.Data.Labels.Clear(); @@ -72,19 +77,63 @@ { remaining = 24 - hours; } else { - remaining = (24 - daylightHours) - hours; + remaining = (24 - daylightHours) - hours; } - PieDataset pieDataset = new PieDataset(new[] { hours, remaining, }) - { - BackgroundColor = new[] { - ColorUtil.ColorHexString(56,113,193), - ColorUtil.ColorHexString(156,163,175), - }, - }; + + if(remaining < 0) + { + remaining = 0; + } + + PieDataset pieDataset = new PieDataset(new[] { hours, remaining }) + { + BackgroundColor = GetColorGradient(hours), + }; + if (pieConfig != null) { pieConfig.Data.Datasets.Add(pieDataset); StateHasChanged(); } } + + private string[] GetColorGradient(float hours) + { + byte greenR = 45, greenG = 189, yellowR = 255, yellowG = 193, redR = 255, redG = 0; + + byte redValue, greenValue; + + if (hours <= 3) + { + redValue = redR; + greenValue = redG; + } + else if (hours >= 12) + { + redValue = greenR; + greenValue = greenG; + } + else if (hours < 6) + { + float t = hours / 6; + redValue = yellowR; + greenValue = (byte)(t * yellowG); + } + else + { + float t = (hours - 6) / 6; + redValue = (byte)(t * greenR + (1 - t) * yellowR); // Decreasing red component + greenValue = (byte)(t * greenG + (1 - t) * yellowG); // Increasing green component + } + + string[] colors = { + ColorUtil.ColorHexString(redValue, greenValue, 0), + ColorUtil.ColorHexString(156, 163, 175) + }; + + return colors; + } + + + } \ No newline at end of file diff --git a/src/apps/blazor-app/Components/SolarScore/Results.razor b/src/apps/blazor-app/Components/SolarScore/Results.razor index 0d5e32a7..42419f3f 100644 --- a/src/apps/blazor-app/Components/SolarScore/Results.razor +++ b/src/apps/blazor-app/Components/SolarScore/Results.razor @@ -136,8 +136,8 @@
- - + +

@tooltipService.GetTooltip("solar score add button")

@@ -161,7 +161,7 @@

kwh

- +
@@ -170,19 +170,11 @@
@{ - if (dlh == daylight) - { -

@dlh+

- } - else - { -

@dlh

- } +

@dlh

}

h

-

Running Hours on Batteries -

+

Running Hours on Batteries

@@ -214,7 +206,7 @@

- @chargingLimitPercentage + @chargingLimitPercentage

%

@@ -223,7 +215,7 @@
-

Battery Utilization

+

Battery Utilisation

@@ -295,10 +287,10 @@ public int numOfBatteries = 3; public double appliancePowerUsage = 0.0; public int numFridges = 2; - public int numTVs = 2; - public int numComputers = 3; + public int numStove = 1; + public int numTV = 3; float dlh = 0f; - private int daylight = 24; + private int daylight = 12; private double chargingLimit = 0.0; private double chargingLimitPercentage = 50.0; private Timer panelTimer = default!; @@ -380,7 +372,7 @@ private void SetGraphicValues() { - appliancePowerUsage = ((numFridges * 250) + (numTVs * 70) + (numComputers * 400)) / 1000.0; + appliancePowerUsage = ((numFridges * 250) + (numStove * 2000) + (numTV * 60)) / 1000.0; var avgEnergyProduction = solarCalculator.getAnnualKwGenerated(numOfPanels, locationData!.solarPanelsData, true) / 365; var usableHours = solarCalculator.getSunlightHours(locationData.solarPanelsData, true); usableHours = Math.Round(usableHours, 2); @@ -398,10 +390,7 @@ double runningHours = chargingLimit / appliancePowerUsage; double runningHoursPercentage = (runningHours / daylight) * 100; - if (runningHoursPercentage > 100) - { - runningHoursPercentage = 100; - } + Console.WriteLine("Running hours percentage: " + runningHoursPercentage); dlh = (float)Math.Round(daylight * (runningHoursPercentage / 100), 2); } diff --git a/src/apps/blazor-app/Pages/Dashboard.razor b/src/apps/blazor-app/Pages/Dashboard.razor index 999304bd..e552be8f 100644 --- a/src/apps/blazor-app/Pages/Dashboard.razor +++ b/src/apps/blazor-app/Pages/Dashboard.razor @@ -51,24 +51,41 @@
+ @{ @* Loop over allAppliances *@ if (appliancesLoaded) { - foreach (KeyValuePair> app in allAppliances) - { - string iconName = app.Key + ".svg"; - int count = 0; - List tempAppliances = app.Value; - for (int i = 0; i < tempAppliances.Count; i++) - { - count += tempAppliances[i].quantity; - } -
- -
- } +
+
+ Left Arrow +
+
+ @{ + applianceNumberOfPage = (int)Math.Ceiling((double)allAppliances.Count / 5); + } + @for (int j = 0; j < 5 && j + appliancesPage*5 < allAppliances.Count; j++) + { + KeyValuePair> app = allAppliances.ElementAt(j + appliancesPage*5); + string iconName = app.Key + ".svg"; + int count = 0; + List tempAppliances = app.Value; + for (int i = 0; i < tempAppliances.Count; i++) + { + count += tempAppliances[i].quantity; + } +
+ +
+ } +
+
+ Right Arrow +
+
} else if (allAppliances.Count == 0 && appliancesLoaded) {

No appliances added

@@ -182,12 +199,12 @@
} } - else { + @* else {
Loading...
- } + } *@ }
@@ -212,9 +229,9 @@
@{ - if (dlh == (24 - daylight)) + if (float.IsInfinity(dlh)) { -

@dlh+

+

12+

} else { @@ -391,7 +408,9 @@ private bool appliancesLoaded = false; private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); Dictionary> allAppliances = new Dictionary>(); - + private int appliancesPage = 0; + private int applianceNumberOfPage = 0; + private string applianceAnimation = ""; /// /// Load the user's reports and all appliances @@ -411,7 +430,7 @@ if (!logIn) { - await ProtectedLocalStore.SetAsync("redirect", "dashboard"); + await ProtectedSessionStore.SetAsync("redirect", "dashboard"); NavigationManager.NavigateTo("/login"); } else if (isAd) @@ -473,6 +492,30 @@ _ = GetSatteliteImage(); } + private async void IncrementAppliancePage(){ + applianceAnimation = "appliance-slide-out-left"; + StateHasChanged(); + await Task.Delay(100); + if(appliancesPage != applianceNumberOfPage - 1){ + appliancesPage++; + } else { + appliancesPage = 0; + } + applianceAnimation = "appliance-slide-in-right"; + StateHasChanged(); + } + private async void DecrementAppliancePage(){ + applianceAnimation = "appliance-slide-out-right"; + StateHasChanged(); + await Task.Delay(100); + if(appliancesPage != 0){ + appliancesPage--; + } else { + appliancesPage = applianceNumberOfPage - 1; + } + applianceAnimation = "appliance-slide-in-left"; + StateHasChanged(); + } private async Task GetSatteliteImage() { if(currentLocationData != null && currentLocationData.satteliteImageData == null) { currentLocationData = await locationDataClass.GetSatelliteImageData(currentLocationData.latitude, currentLocationData.longitude, currentLocationData, cancellationTokenSource.Token); diff --git a/src/apps/blazor-app/Pages/Login.razor b/src/apps/blazor-app/Pages/Login.razor index a1ee0d62..350325a3 100644 --- a/src/apps/blazor-app/Pages/Login.razor +++ b/src/apps/blazor-app/Pages/Login.razor @@ -5,69 +5,87 @@ @using System.Text.Json @inject NavigationManager NavigationManager @inject ProtectedLocalStorage ProtectedLocalStore +@inject ProtectedSessionStorage ProtectedSessionStore Login - @if (!isLoaded) {} - else if (logIn) { - NavigationManager.NavigateTo("/"); - } else if (isAd) { - NavigationManager.NavigateTo("/admin/keys"); - } else { -
-
- Shapes - Shapes -
- - Logo - -
- Sun - UI Elements - Rob - -
-
- - -

Welcome Back

-
-
-

Log In

-
-
-
-

@errorMessage

-
-
- @if (!emailIsValid) - { -

The email is invalid.

- - }else { - - } - @if (!passwordIsValid) - { -

Incorrect Password.

- - } else { - - } - -

Don't have an account yet? Register for free

-
+@if (!isLoaded) { } +else if (logIn) +{ + NavigationManager.NavigateTo("/"); +} +else if (isAd) +{ + NavigationManager.NavigateTo("/admin/keys"); +} +else +{ +
+
+ Shapes + Shapes +
+ + Logo + +
+ Sun + UI Elements + Rob + +
+
+ + +

Welcome Back

+
+
+

Log In

+
+
+
+

@errorMessage

+
+ @if (!emailIsValid) + { +

The email is invalid.

+ + } + else + { + + } + @if (!passwordIsValid) + { +

Incorrect Password.

+ + } + else + { + + } + +

Don't have an account yet? Register for free

+
-
- } + +
+} @code { private SharedUtils.userClass userClass = new SharedUtils.userClass(); @@ -86,11 +104,11 @@ private bool isLoaded = false; private string? redirect = ""; - protected override async Task OnInitializedAsync() + protected override async Task OnInitializedAsync() { var loggedIn = await ProtectedLocalStore.GetAsync("loggedIn"); var isAdmin = await ProtectedLocalStore.GetAsync("isAdmin"); - var re = await ProtectedLocalStore.GetAsync("redirect"); + var re = await ProtectedSessionStore.GetAsync("redirect"); redirect = re.Value; Console.WriteLine("redirect:" + redirect); isAd = isAdmin.Value; @@ -98,53 +116,61 @@ isLoaded = true; } -private async Task HandleSubmit() -{ - Console.WriteLine("OnSubmit"); + private async Task HandleSubmit() + { + Console.WriteLine("OnSubmit"); - var isValid = ValidateForm(); + var isValid = ValidateForm(); - if (isValid) - { - await HandleValidSubmit(); - } - else - { - HandleInvalidSubmit(); + if (isValid) + { + await HandleValidSubmit(); + } + else + { + HandleInvalidSubmit(); + } } -} public async Task HandleValidSubmit() { UserModel? result = await userClass.Login(email!, password!, password!); - if(result != null) { + if (result != null) + { showError = "hidden"; await ProtectedLocalStore.SetAsync("loggedIn", true); - if (email != null) { + if (email != null) + { await ProtectedLocalStore.SetAsync("userEmail", email); - } else { + } + else + { await ProtectedLocalStore.SetAsync("userEmail", ""); } - + await ProtectedLocalStore.SetAsync("userId", result.userId); - if(result.userRole == 1){ + if (result.userRole == 1) + { await ProtectedLocalStore.SetAsync("isAdmin", true); - NavigationManager.NavigateTo("/admin/keys"); + NavigationManager.NavigateTo("/admin/keys"); } - else{ - NavigationManager.NavigateTo("/" + redirect); + else + { await ProtectedLocalStore.SetAsync("isAdmin", false); - await ProtectedLocalStore.DeleteAsync("redirect"); + await ProtectedSessionStore.DeleteAsync("redirect"); + NavigationManager.NavigateTo("/" + redirect); } - } else { + } + else + { Console.WriteLine("Failed"); passwordIsValid = false; @* string message = await response.Content.ReadAsStringAsync(); - errorMessage = message; - showError = "block"; *@ +errorMessage = message; +showError = "block"; *@ } } @@ -153,43 +179,43 @@ private async Task HandleSubmit() Console.WriteLine("OnInvalidSubmit"); } -private bool ValidateForm() -{ - emailIsValid = true; - @* check email using regex *@ - if (string.IsNullOrEmpty(email)) + private bool ValidateForm() { - Console.WriteLine("email is empty"); - return false; + emailIsValid = true; + @* check email using regex *@ + if (string.IsNullOrEmpty(email)) + { + Console.WriteLine("email is empty"); + return false; + } + else if (!Regex.IsMatch(email, @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$")) + { + Console.WriteLine("email is not valid"); + @* Add Toast *@ + emailIsValid = false; + return false; + } + + @* check if password is empty *@ + if (string.IsNullOrEmpty(password)) + { + Console.WriteLine("password is empty"); + + passwordIsValid = false; + + return false; + } + + return true; } - else if (!Regex.IsMatch(email, @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$")) + + private void HandleEmailChanged(string value) { - Console.WriteLine("email is not valid"); - @* Add Toast *@ - emailIsValid = false; - return false; + email = value; } - @* check if password is empty *@ - if (string.IsNullOrEmpty(password)) + private void HandlePasswordChanged(string value) { - Console.WriteLine("password is empty"); - - passwordIsValid = false; - - return false; + password = value; } - - return true; -} - -private void HandleEmailChanged(string value) -{ - email = value; -} - -private void HandlePasswordChanged(string value) -{ - password = value; -} } \ No newline at end of file diff --git a/src/apps/blazor-app/Pages/Report.razor b/src/apps/blazor-app/Pages/Report.razor index e0f79ef1..7a1c411c 100644 --- a/src/apps/blazor-app/Pages/Report.razor +++ b/src/apps/blazor-app/Pages/Report.razor @@ -5,129 +5,204 @@ @using BlazorApp.Components.Dashboard @using ChartJs.Blazor.PolarAreaChart @using ApplianceEnergyConsumption +@using BlazorApp.EnviromentImpact @layout AuthLayout
@if (isLoaded) { -
-
- BlueSkies logo -
-
-
-
+
+
+ BlueSkies logo +
+
+
+
+ +
+

Location

+
+
+
+
+ +
+
+ +
+
+ +
+ Sale +
+

Solar Score


+
+

@solarScore

+

%

+
+
+ +
+ Sale +
+

Avg Daily Energy Production

+
+

@avgEnergyProduction

+

kwh

+
+
+ +
+ Sale +
+

Usable hours of sunlight + per day

+
+

@usableHours

+

h

+
+
+
+ +
+
+ +
+
-

Location

+

System Size

-
-
- -
-
- - -
- -
-
+
+ + +
+
+

@system.inverterOutput

+

kw

+
+ +
+

Appliances

+
+ +

What do you want to run in a power outage?

+
+
+
+ @foreach (var item in applianceQuantity) + { + var imageName = item.Key + ".svg"; + + } +
+
-
-
- -
-

System Size

-
-
-
- - -
-
-

@system.inverterOutput

-

kw

-
-
-
- -
-

Appliances

-
- -

What do you want to run in a power outage?

-
-
-
- @foreach (var item in applianceQuantity) - { - var imageName = item.Key + ".svg"; - - } -
-
- - House + House -
-
-
-

Running Hours on Batteries

- -
-

- @{ - if (dlh == (24 - daylight)) - { +

+
+
+

Running Hours on Batteries

+ +
+

+ @{ + if (dlh == (24 - daylight)) + {

@dlh+

- } - else - { + } + else + {

@dlh

+ } } - } -

-

h

+

+

h

+
+
+
+

Appliance Energy Consumption

+
-
-

Appliance Energy Consumption

- -
-
-
@* *@ - @* Fancy Data *@ -
- -
-

Fancy Data

-
- -

More information about your area

-
-
-
-
-

Annual Flux Map

- Solar Sattelite Image +
@* *@ + @* Fancy Data *@ +
+ +
+

Fancy Data

+
+ +

More information about your area

+
+
+
+
+

Annual Flux Map

+ Solar Sattelite Image +
+
+

Monthly Solar Irradiation

+ +
+
+ +
+
+ +

Rooftop Stats

+
+ @{ + double squaredArea = Math.Round(wholeroofstats!.areaMeters2); + double maxArraArea = Math.Round(resultLocationData.solarPanelsData!.solarPotential!.maxArrayAreaMeters2); + double maxHoursSunlightPerDay = + Math.Round(resultLocationData.solarPanelsData!.solarPotential!.maxSunshineHoursPerYear / 365, 2); + } + +
+ Home Icon +

@squaredArea m²

+
+ +
+ Solar Panels Icon +

@resultLocationData.solarPanelsData!.solarPotential!.maxArrayPanelsCount

+
+ +
+ Area Icon +

@maxArraArea m²

+
+ +
+ Sun Icon +

@maxHoursSunlightPerDay h

+
+
+
+
+
+

Elevation Graph

+ +
- -
-
}
@code { - + private DataHandlers.SolarDataHandler solarCalculator = new DataHandlers.SolarDataHandler(); private DataHandlers.RooftopDataHandler rooftopDataHandler = new DataHandlers.RooftopDataHandler(); private DataHandlers.SolarDataHandler solarDataHandler = new DataHandlers.SolarDataHandler(); @@ -136,7 +211,7 @@ private SharedUtils.reportAllApplianceClass reportAllApplianceClass = new SharedUtils.reportAllApplianceClass(); private SharedUtils.locationDataClass locationDataClass = new SharedUtils.locationDataClass(); private SharedUtils.systemClass systemClass = new SharedUtils.systemClass(); - + private string? SatteliteImage; [Parameter] public string? UserId { get; set; } @@ -161,42 +236,49 @@ private float runningHoursPercentage = 0; private float dlh = 0; private float daylight = 0; - - + public double usableHours { get; set; } = -1; + private double annualKWGenerated = 0; + private Wholeroofstats? wholeroofstats = null; + LocationDataModel? resultLocationData = null; private Dictionary applianceQuantity = new Dictionary(); protected override async Task OnInitializedAsync() { - report = await reportClass.GetReport(int.Parse(ReportId!)); + report = await reportClass.GetReport(int.Parse(ReportId!)); if (report != null) { latitude = report.latitude; longitude = report.longitude; Console.WriteLine("Current report: " + report.reportId); var result = await systemClass.GetSystem(report.systemId); - if(result != null) { + if (result != null) + { system = result; } - LocationDataModel? resultLocationData = await locationDataClass.GetLocationData(latitude, longitude); - if(resultLocationData != null) { + resultLocationData = await locationDataClass.GetLocationData(latitude, longitude); + if (resultLocationData != null) + { locationData = resultLocationData; SatteliteImage = rooftopDataHandler.GetSatelliteImage(locationData.satteliteImageData!); - satteliteImageSrc = rooftopDataHandler.GetAnnualFluxMap(locationData.annualFluxData!, locationData.satteliteImageData!, locationData.maskData!); - solarRadiationPerMonth = solarDataHandler.getMontlySolarRadiation(resultLocationData!.monthlyFluxData!, resultLocationData!.maskData!, true); - avgEnergyProduction = Math.Round(solarCalculator.getAnnualKwGenerated(system.numberOfPanels, resultLocationData.solarPanelsData) / 365, 2).ToString() + " kwh"; - solarScore = solarCalculator.getSolarScore(resultLocationData.solarPanelsData).ToString() + "%"; - Console.WriteLine("Solar score: " + solarScore); - + satteliteImageSrc = rooftopDataHandler.GetAnnualFluxMap(locationData.annualFluxData!, locationData.satteliteImageData!, + locationData.maskData!); + solarRadiationPerMonth = solarDataHandler.getMontlySolarRadiation(resultLocationData!.monthlyFluxData!, + resultLocationData!.maskData!, true); + avgEnergyProduction = Math.Round(solarCalculator.getAnnualKwGenerated(system.numberOfPanels, + resultLocationData.solarPanelsData) / 365, 2).ToString(); + solarScore = solarCalculator.getSolarScore(resultLocationData.solarPanelsData).ToString(); + usableHours = Math.Round(solarCalculator.getSunlightHours(resultLocationData!.solarPanelsData, true), 2); + annualKWGenerated = solarDataHandler.getAnnualKwGenerated(system.numberOfPanels, resultLocationData.solarPanelsData); + wholeroofstats = resultLocationData.solarPanelsData!.solarPotential!.wholeRoofStats; } - - Console.WriteLine("Current location: " + locationData.locationName); reportAllAppliance = await reportAllApplianceClass.GetReportAllApplianceByReportId(int.Parse(ReportId!)); - runningHoursPercentage = systemsDataHandler.CalculateRunningHours(system.numberOfBatteries, system.batterySize * 1000, reportAllAppliance); + runningHoursPercentage = systemsDataHandler.CalculateRunningHours(system.numberOfBatteries, system.batterySize * 1000, + reportAllAppliance); daylight = 12; dlh = (float)Math.Round((24 - daylight) * (runningHoursPercentage / 100), 2); - + foreach (var item in reportAllAppliance) { @@ -213,7 +295,7 @@ var systemSize = system.systemSize!; RenderCharts(); - + if (systemSize.Equals("Small")) { @@ -230,53 +312,56 @@ isLoaded = true; StateHasChanged(); - } else { + } + else + { Console.WriteLine("Report not found"); } } @* RenderCharts *@ - private void RenderCharts(){ + private void RenderCharts() + { pieConfig = new PieConfig(true) - { - Options = new PieOptions { - Responsive = true, - AspectRatio = 3, - Legend = new Legend - { - Display = false, - }, - Title = new OptionsTitle - { - Display = false, - Text = "Running Hours", - FontSize = 20, - Position = Position.Bottom, - LineHeight = 4, - }, - Circumference = 3, - Rotation = -9.341, - Animation = new ArcAnimation + Options = new PieOptions { - AnimateRotate = true, - Duration = 5, + Responsive = true, + AspectRatio = 3, + Legend = new Legend + { + Display = false, + }, + Title = new OptionsTitle + { + Display = false, + Text = "Running Hours", + FontSize = 20, + Position = Position.Bottom, + LineHeight = 4, + }, + Circumference = 3, + Rotation = -9.341, + Animation = new ArcAnimation + { + AnimateRotate = true, + Duration = 5, - }, - Tooltips = new Tooltips - { - Enabled = true, - Mode = InteractionMode.Index, - Intersect = false, - }, - Hover = new Hover - { - Mode = InteractionMode.Index, - Intersect = false - }, - CutoutPercentage = 80 - } - }; + }, + Tooltips = new Tooltips + { + Enabled = true, + Mode = InteractionMode.Index, + Intersect = false, + }, + Hover = new Hover + { + Mode = InteractionMode.Index, + Intersect = false + }, + CutoutPercentage = 80 + } + }; pieConfig.Data.Datasets.Clear(); pieConfig.Data.Labels.Clear(); @@ -289,9 +374,9 @@ PieDataset pieDataset = new PieDataset(new[] { dlh, remaining, }) { BackgroundColor = new[] { - ColorUtil.ColorHexString(56,113,193), - ColorUtil.ColorHexString(156,163,175), - }, +ColorUtil.ColorHexString(56,113,193), +ColorUtil.ColorHexString(156,163,175), +}, }; if (pieConfig != null) { diff --git a/src/apps/blazor-app/wwwroot/css/app.css b/src/apps/blazor-app/wwwroot/css/app.css index 3f2bb4e3..230eb7cf 100644 --- a/src/apps/blazor-app/wwwroot/css/app.css +++ b/src/apps/blazor-app/wwwroot/css/app.css @@ -1024,11 +1024,6 @@ video { margin-bottom: auto; } -.mx-2 { - margin-left: 0.5rem; - margin-right: 0.5rem; -} - .-mb-2 { margin-bottom: -0.5rem; } @@ -1393,6 +1388,10 @@ video { height: 13rem; } +.h-56 { + height: 14rem; +} + .h-6 { height: 1.5rem; } @@ -1502,6 +1501,10 @@ video { width: 2.75rem; } +.w-11\/12 { + width: 91.666667%; +} + .w-12 { width: 3rem; } @@ -1522,6 +1525,10 @@ video { width: 66.666667%; } +.w-2\/5 { + width: 40%; +} + .w-20 { width: 5rem; } @@ -1752,14 +1759,6 @@ video { width: 100vw; } -.w-11\/12 { - width: 91.666667%; -} - -.w-2\/5 { - width: 40%; -} - .min-w-fit { min-width: -moz-fit-content; min-width: fit-content; @@ -2250,12 +2249,24 @@ video { margin-bottom: calc(1.25rem * var(--tw-space-y-reverse)); } +.space-y-6 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); +} + .space-y-8 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(2rem * var(--tw-space-y-reverse)); } +.space-y-9 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(2.25rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(2.25rem * var(--tw-space-y-reverse)); +} + .self-center { align-self: center; } @@ -3028,6 +3039,11 @@ video { color: rgb(17 24 39 / var(--tw-text-opacity)); } +.text-green-600 { + --tw-text-opacity: 1; + color: rgb(22 163 74 / var(--tw-text-opacity)); +} + .text-green-900 { --tw-text-opacity: 1; color: rgb(20 83 45 / var(--tw-text-opacity));