diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/BaseTodoItems.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/BaseTodoItems.cs deleted file mode 100644 index 9a7799c..0000000 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/BaseTodoItems.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Blazorise; - -using Elektrifikatsiya.Components.TodoApp; - -using Microsoft.AspNetCore.Components; - -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Elektrifikatsiya.Components.TodoApp; -public abstract class BaseTodoItems : ComponentBase -{ - protected Validations validations; - - protected string description; - - protected Filter filter = Filter.All; - - protected List todos = new() - { - new() { Description = "Buy milk" }, - new() { Description = "Call John regarding the meeting" }, - new() { Description = "Walk a dog" }, - }; - - protected IEnumerable Todos - { - get - { - var query = from t in todos select t; - - if (filter == Filter.Active) - query = from q in query where !q.Completed select q; - - if (filter == Filter.Completed) - query = from q in query where q.Completed select q; - - return query; - } - } - - protected void SetFilter(Filter filter) - { - this.filter = filter; - } - - protected void OnCheckAll(bool isChecked) - { - todos.ForEach(x => x.Completed = isChecked); - } - - protected async Task OnAddTodo() - { - if (await validations.ValidateAll()) - { - todos.Add(new() { Description = description }); - description = null; - - await validations.ClearAll(); - } - } - - protected void OnClearCompleted() - { - todos.RemoveAll(x => x.Completed); - filter = Filter.All; - } - - protected Task OnTodoStatusChanged(bool isChecked) - { - return InvokeAsync(StateHasChanged); - } -} diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/Filter.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/Filter.cs deleted file mode 100644 index 7cd3ac5..0000000 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/Filter.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Elektrifikatsiya.Components.TodoApp; - -public enum Filter -{ - All, - Active, - Completed, -} diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/Todo.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/Todo.cs deleted file mode 100644 index fdf4888..0000000 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/Todo.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Elektrifikatsiya.Components.TodoApp; - -public class Todo -{ - public bool Completed { get; set; } - - public string Description { get; set; } -} diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/TodoItem.razor b/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/TodoItem.razor deleted file mode 100644 index 8233b49..0000000 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/TodoItem.razor +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - @Todo.Description - - - -@code{ - Task OnCheckedChanged( bool isChecked ) - { - Todo.Completed = isChecked; - - return StatusChanged?.Invoke( isChecked ); - } - - [Parameter] public Todo Todo { get; set; } - - [Parameter] public Func StatusChanged { get; set; } -} \ No newline at end of file diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/TodoItems.razor b/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/TodoItems.razor deleted file mode 100644 index a9db980..0000000 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Components/TodoApp/TodoItems.razor +++ /dev/null @@ -1,57 +0,0 @@ -@inherits BaseTodoItems - - - - - - Todo List - - - - - All - - - - - - - - - - - - - - - - - - - - @foreach ( var todo in Todos ) - { - - } - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Layouts/LoginLayout.razor b/src/Elektrifikatsiya/Elektrifikatsiya/Layouts/LoginLayout.razor index 091b551..daca9d9 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Layouts/LoginLayout.razor +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Layouts/LoginLayout.razor @@ -1,17 +1,42 @@ @using System.Diagnostics; +@using FluentResults; + +@inject Elektrifikatsiya.Services.IAuthenticationService AuthenticationService +@inject NavigationManager NavigationManager + @inherits LayoutComponentBase - + - + - - + + @code { - + private string username = string.Empty; + private string password = string.Empty; + private Color color = Color.Primary; + private bool disabled; + private async Task Clicked() + { + color = Color.Primary; + disabled = true; + + Result loginResult = await AuthenticationService.LoginUserAsync(username, password); + + if (loginResult.IsSuccess) + { + NavigationManager.NavigateTo("/", true); + } + else + { + color = Color.Danger; + disabled = false; + } + } } \ No newline at end of file diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Models/PrometheusQueryResult.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Models/PrometheusQueryResult.cs index 7121698..a8f8d06 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Models/PrometheusQueryResult.cs +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Models/PrometheusQueryResult.cs @@ -1,6 +1,6 @@ using System.Diagnostics; +using System.Globalization; using System.Text.Json.Serialization; -using Microsoft.AspNetCore.Mvc.Diagnostics; namespace Elektrifikatsiya.Models; @@ -47,51 +47,50 @@ public class PrometheusDataWrapper ResultType = resultType; Result = result; } - + public FluentResults.Result> MatrixTypeToTimestampFloatTuple() { - if (ResultType != ResultType.Matrix) - { - return FluentResults.Result.Fail("The response did not have the Matrix Type"); - } + if (ResultType != ResultType.Matrix) + { + return FluentResults.Result.Fail("The response did not have the Matrix Type"); + } List<(double, double)> result = new List<(double, double)>(); if (Result.Count == 0 || Result[0]?.Values is null || Result[0]?.Values?[0] is null) { - return FluentResults.Result.Fail("There was no result in the Response Body"); + return FluentResults.Result.Fail("There was no result in the Response Body"); } foreach (object value in Result[0]!.Values!) - { + { - string[] segment = value.ToString()!.Split(","); + string[] segment = value.ToString()!.Split(","); - result.Add((Convert.ToDouble(segment[0][2..^1]), Convert.ToDouble(segment[1][1..^2]))); - } + result.Add((Convert.ToDouble(segment[0][2..^1], CultureInfo.InvariantCulture), Convert.ToDouble(segment[1][1..^2], CultureInfo.InvariantCulture))); + } Debug.WriteLine(result); return result; } public FluentResults.Result<(double, double)> VectorTypeToTimestampFloatTuple() { - if (ResultType != ResultType.Vector) - { - return FluentResults.Result.Fail("The response did not have the Vector Type"); - } + if (ResultType != ResultType.Vector) + { + return FluentResults.Result.Fail("The response did not have the Vector Type"); + } - string[]? segment = Result.FirstOrDefault()?.Value.ToString()?.Split(",") ?? null; + string[]? segment = Result.FirstOrDefault()?.Value?.ToString()?.Split(","); - if (segment is null) - { - return FluentResults.Result.Fail("There was no result in the Response Body"); - } + if (segment is null) + { + return FluentResults.Result.Fail("There was no result in the Response Body"); + } - return((Convert.ToDouble(segment[0][2..^1]), Convert.ToDouble(segment[1][1..^2]))); + return (Convert.ToDouble(segment[0][2..^1]), Convert.ToDouble(segment[1][1..^2], CultureInfo.InvariantCulture)); } } - public class PrometheusDataMetric { [JsonPropertyName("__name__")] public string Name { get; set; } diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/AddPlug.razor b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/AddPlug.razor index d78020d..d7c1b7f 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/AddPlug.razor +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/AddPlug.razor @@ -14,144 +14,155 @@ - - - - - - - Add a plug via wifi - - - - - - - - - - - - - - - - - IP: @context.Item - - - - - - - - - - - - + + + + + + + Add a plug via wifi + + + + + + + + + + + + + + + + + IP: @context.Item + + + + + + + + + + + + - - - - - - - Add a plug via IP - - - - -
- - - -
- -
-
-
-
-
-
- -
+ + + + + + + Add a plug via IP + + + + +
+ + + + + + Please enter a ip address. + Ip address is valid. + Ip address is not valid! + + +
+ +
+
+
+
+
+
+
+ +
@code { - List ipAddresses = new List(); + List ipAddresses = new List(); - Validation? ipValidation; + Validation? ipValidation; - bool visible = true; + bool visible = true; + bool disabled = false; - string ipText = null!; + string ipText = null!; - protected override void OnInitialized() - { - MdnsDiscovery.OnDeviceFound += async ipAddress => - { - visible = false; - if (!ipAddresses.Contains(ipAddress)) - { - ipAddresses.Add(ipAddress); - await InvokeAsync(StateHasChanged); - } - }; + protected override void OnInitialized() + { + MdnsDiscovery.OnDeviceFound += async ipAddress => + { + visible = false; + if (!ipAddresses.Contains(ipAddress)) + { + ipAddresses.Add(ipAddress); + await InvokeAsync(StateHasChanged); + } + }; - MdnsDiscovery.FetchChachedDevices(); - } + MdnsDiscovery.FetchChachedDevices(); + } - private async Task RegisterDevice(IPAddress ipAddress) - { - Result result = await DeviceManagmentService.RegisterDevice(ipAddress, (await AuthenticationService.GetUserAsync()).ValueOrDefault); + private async Task RegisterDevice(IPAddress ipAddress) + { + disabled = true; + Result result = await DeviceManagmentService.RegisterDevice(ipAddress, (await AuthenticationService.GetUserAsync()).ValueOrDefault); - if (result.IsSuccess) - { - await MessageService.Success("Device added!"); - } - else - { - await MessageService.Error(string.Join(',', result.Errors.Select(e => e.Message)), "Adding device failed!"); - } - } + if (result.IsSuccess) + { + await MessageService.Success("Device added!"); + } + else + { + await MessageService.Error(string.Join(',', result.Errors.Select(e => e.Message)), "Adding device failed!"); + } + disabled = false; + } - public void ValidateIPv4(ValidatorEventArgs e) - { - string? input = Convert.ToString(e.Value); + public void ValidateIPv4(ValidatorEventArgs e) + { + string? input = Convert.ToString(e.Value); - if (string.IsNullOrWhiteSpace(input)) - { - e.Status = ValidationStatus.None; - return; - } + if (string.IsNullOrWhiteSpace(input)) + { + e.Status = ValidationStatus.None; + return; + } - string[] splitValues = input.Split('.'); - if (splitValues.Length != 4) - { - e.Status = ValidationStatus.Error; - return; - } + string[] splitValues = input.Split('.'); + if (splitValues.Length != 4) + { + e.Status = ValidationStatus.Error; + return; + } - e.Status = splitValues.All(r => byte.TryParse(r, out _)) ? ValidationStatus.Success : ValidationStatus.Error; - } + e.Status = splitValues.All(r => byte.TryParse(r, out _)) ? ValidationStatus.Success : ValidationStatus.Error; + } } \ No newline at end of file diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor index 5b11650..a09d7f5 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor @@ -152,6 +152,12 @@ { plugnames += $"shellyplug-s-{device.MacAddress}/relay/0|"; } + + if(string.IsNullOrEmpty(plugnames)) + { + return new(); + } + plugnames = plugnames[0..^1]; Debug.WriteLine($$"""sum(power{sensor=~"{{plugnames}}"})[1h:1m]"""); diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/TodoAppPage.razor b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/TodoAppPage.razor deleted file mode 100644 index ed5201a..0000000 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/TodoAppPage.razor +++ /dev/null @@ -1,3 +0,0 @@ -@using Elektrifikatsiya.Components.TodoApp -@page "/apps/todo" - \ No newline at end of file diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Program.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Program.cs index a9408b5..02d9c9d 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Program.cs +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Program.cs @@ -60,7 +60,7 @@ IAuthenticationService authenticationService = serviceScope.ServiceProvider.GetR if (!mainDatabase.Users.Any()) { - authenticationService.RegisterUserAsync("admin", "admin", Role.Admin); + _ = authenticationService.RegisterUserAsync("admin", "admin", Role.Admin); } app.Run(); diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/UpdateService.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/UpdateService.cs index a0b7ef0..f31d184 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/UpdateService.cs +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/UpdateService.cs @@ -33,12 +33,12 @@ public class UpdateService : IHostedService, IDisposable _ = deviceStatusService.TrackDevice(device); } - timer = new Timer((_) => Update(), null, TimeSpan.Zero, TimeSpan.FromSeconds(15)); + timer = new Timer(async (_) => await Update(), null, TimeSpan.Zero, TimeSpan.FromSeconds(15)); logger.LogInformation("Update service started."); } - private async void Update() + private async Task Update() { Result> getDeviceStatusResult = deviceStatusService.GetDevices(); diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/UserDatabase.sqlite-shm b/src/Elektrifikatsiya/Elektrifikatsiya/UserDatabase.sqlite-shm deleted file mode 100644 index fe9ac28..0000000 Binary files a/src/Elektrifikatsiya/Elektrifikatsiya/UserDatabase.sqlite-shm and /dev/null differ diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/UserDatabase.sqlite-wal b/src/Elektrifikatsiya/Elektrifikatsiya/UserDatabase.sqlite-wal deleted file mode 100644 index e69de29..0000000 diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Utilities/PrometheusQuery.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Utilities/PrometheusQuery.cs index 456521f..c952d7f 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Utilities/PrometheusQuery.cs +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Utilities/PrometheusQuery.cs @@ -10,18 +10,15 @@ namespace Elektrifikatsiya.Utilities; public class PrometheusQuery { - private string connectionString; private readonly HttpClient client = new(); public PrometheusQuery(string connectionString) { - this.connectionString = connectionString; client.BaseAddress = new Uri(connectionString); } public Task Query(string query) { - var res = client.GetStringAsync($"/api/v1/query?query={UrlEncoder.Create().Encode(query)}").Result; return client.GetFromJsonAsync($"/api/v1/query?query={UrlEncoder.Create().Encode(query)}", new JsonSerializerOptions() { PropertyNameCaseInsensitive = true,