Merge branch 'feature-DeviceRegistration' of https://github.com/Stefan-5422/-T5-Elektrifikatsiya into feature-DeviceRegistration

This commit is contained in:
Friend2868
2023-06-01 15:23:59 +02:00
7 changed files with 224 additions and 169 deletions
@@ -6,11 +6,13 @@ namespace Elektrifikatsiya.Database;
public class MainDatabaseContext : DbContext public class MainDatabaseContext : DbContext
{ {
public DbSet<Device> Devices { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<EnergyPriceChange> EnergyPriceChanges { get; set; }
public MainDatabaseContext(DbContextOptions<MainDatabaseContext> dbContextOptions) : base(dbContextOptions) public MainDatabaseContext(DbContextOptions<MainDatabaseContext> dbContextOptions) : base(dbContextOptions)
{ {
} }
public DbSet<User> Users { get; set; }
public DbSet<Device> Devices { get; set; }
public DbSet<Event> Events { get; set; }
} }
@@ -0,0 +1,23 @@
using System.ComponentModel.DataAnnotations;
namespace Elektrifikatsiya.Models;
public class EnergyPriceChange
{
[Key]
public DateTime DateTime { get; set; }
public double EnergyPrice { get; set; }
public EnergyPriceChange(DateTime dateTime, double energyPrice)
{
DateTime = dateTime;
EnergyPrice = energyPrice;
}
public EnergyPriceChange(double energyPrice)
{
EnergyPrice = energyPrice;
DateTime = DateTime.Now;
}
}
@@ -1,5 +1,6 @@
@page "/" @page "/"
@using Blazorise.Components; @using Blazorise.Components;
@using Elektrifikatsiya.Database;
@using Elektrifikatsiya.Models; @using Elektrifikatsiya.Models;
@using System.Net @using System.Net
@using Elektrifikatsiya.Services @using Elektrifikatsiya.Services
@@ -7,9 +8,13 @@
@using System.Diagnostics @using System.Diagnostics
@using Elektrifikatsiya.Services.Implementations @using Elektrifikatsiya.Services.Implementations
@inject IVersionProvider VersionProvider @inject IVersionProvider VersionProvider
@inject IDeviceStatusService DeviceStatusService
@inject IEventService EventService
@inject IDeviceStatusService DeviceStatusService;
@inject IDeviceManagmentService DeviceManagmentService;
@inject IEventService EventService;
@inject MainDatabaseContext MainDatabaseContext;
<Div>
<Row Padding="Padding.Is3"> <Row Padding="Padding.Is3">
<Div Display="Display.Flex.Row.OnDesktop" Margin=" Margin.Is3.FromBottom" Width="Width.Is100"> <Div Display="Display.Flex.Row.OnDesktop" Margin=" Margin.Is3.FromBottom" Width="Width.Is100">
<Column ColumnSize="ColumnSize.Is6.OnDesktop.Is12"> <Column ColumnSize="ColumnSize.Is6.OnDesktop.Is12">
@@ -29,7 +34,7 @@
Mode="ListGroupMode.Static" Mode="ListGroupMode.Static"
Style="border-radius: 0px 0px"> Style="border-radius: 0px 0px">
<ItemTemplate> <ItemTemplate>
<ListGroupItem Border="Border.OnBottom"> <ListGroupItem>
<Row> <Row>
<Column ColumnSize="ColumnSize.Is8"> <Column ColumnSize="ColumnSize.Is8">
<Row> <Row>
@@ -49,8 +54,8 @@
</Row> </Row>
</Column> </Column>
<Column ColumnSize="ColumnSize.Is4"> <Column ColumnSize="ColumnSize.Is4">
<Button Position="Position.Absolute.Top.Is50.Start.Is50.Translate.Middle" Color="Color.Dark" Outline> <Button Clicked="() => Switch(context.Item)" Position="Position.Absolute.Top.Is50.Start.Is50.Translate.Middle" Color="Color.Primary" Primary Outline>
<BarIcon IconName="IconName.Bolt" /> <BarIcon TextColor="(context.Item.Enabled?TextColor.Success:TextColor.Danger)" IconName="IconName.Bolt" />
</Button> </Button>
</Column> </Column>
</Row> </Row>
@@ -74,13 +79,12 @@
ValueField="@((_)=>(""))" ValueField="@((_)=>(""))"
Mode="ListGroupMode.Static" Mode="ListGroupMode.Static"
Style="border-radius: 0px 0px"> Style="border-radius: 0px 0px">
<ItemTemplate> <ItemTemplate>
<Div Flex="Flex.InlineFlex.JustifyContent.Between" Width="Width.Is100"> <Div Flex="Flex.InlineFlex.JustifyContent.Between" Width="Width.Is100">
<Heading Size="HeadingSize.Is6" Margin="Margin.Is2.FromBottom">@context.Item.EventName</Heading> <Heading Size="HeadingSize.Is6" Margin="Margin.Is2.FromBottom">@context.Item.EventName</Heading>
<Small>@context.Item.Date</Small> <Small>@context.Item.Date</Small>
</Div> </Div>
<Paragraph Border="Border.OnBottom" Margin="Margin.Is2.FromBottom">@context.Item.Description</Paragraph> <Paragraph Margin="Margin.Is2.FromBottom">@context.Item.Description</Paragraph>
</ItemTemplate> </ItemTemplate>
</ListView> </ListView>
</Column> </Column>
@@ -89,6 +93,7 @@
<Row Padding="Padding.Is3"> <Row Padding="Padding.Is3">
<Column> <Column>
<Button Color="Color.Primary" Style="border-radius: 0px" Clicked="@(async () => await HandleRedraw())">Aktualisieren</Button> <Button Color="Color.Primary" Style="border-radius: 0px" Clicked="@(async () => await HandleRedraw())">Aktualisieren</Button>
<LineChart @ref="lineChart" TItem="double" /> <LineChart Height="Height.Is100" Width="Width.Is100" @ref="lineChart" TItem="double" />
</Column> </Column>
</Row> </Row>
</Div>
@@ -5,17 +5,31 @@ using Elektrifikatsiya.Utilities;
using System.Diagnostics; using System.Diagnostics;
using System.Text; using System.Text;
using Elektrifikatsiya.Services.Implementations;
using Elektrifikatsiya.Database;
namespace Elektrifikatsiya.Pages; namespace Elektrifikatsiya.Pages;
public partial class Dashboard public partial class Dashboard
{ {
//TODO: insert new event here if plug produces one //TODO: insert new event here if plug produces one
List<Event> events = new List<Event>() { new Event("Text", "Text", DateTime.Today, null ) }; private List<Event> events = new List<Event>() { new Event("Text", "Text", DateTime.Today, null) };
//TODO: insert new Device here if user adds one
List<Device> plugs = new List<Device>(); private List<string> labels = new List<string>();
//code for graph //code for graph
LineChart<double> lineChart; private LineChart<double> lineChart;
//TODO: insert new Device here if user adds one
private List<Device> plugs = new List<Device>();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await HandleRedraw();
}
}
protected override void OnInitialized() protected override void OnInitialized()
{ {
@@ -32,37 +46,7 @@ public partial class Dashboard
}; };
} }
protected override async Task OnAfterRenderAsync(bool firstRender) private async Task<List<double>> GetData()
{
if (firstRender)
{
await HandleRedraw();
}
}
async Task HandleRedraw()
{
labels.Clear();
await lineChart.Clear();
await lineChart.AddLabelsDatasetsAndUpdate(labels, await GetLineChartDataset());
}
//TODO: insert dataset of current and last voltage usages
async Task<LineChartDataset<double>> GetLineChartDataset()
{
return new LineChartDataset<double>
{
Label = "Wattage",
Data = await RandomizeData(),
Fill = true,
PointRadius = 3,
CubicInterpolationMode = "monotone",
};
}
List<string> labels = new List<string>();
async Task<List<double>> RandomizeData()
{ {
if (plugs.Count == 0) if (plugs.Count == 0)
{ {
@@ -77,9 +61,12 @@ public partial class Dashboard
} }
plugnames = plugnames[0..^1]; plugnames = plugnames[0..^1];
Debug.WriteLine($$"""sum(power{sensor=~"{{plugnames}}"})[1h:1m]"""); double energyPrice = MainDatabaseContext.EnergyPriceChanges.OrderByDescending(e =>e.DateTime).FirstOrDefault()?.EnergyPrice ?? 0;
PrometheusDataWrapper? deviceData = (await promQueryer.Query($$"""sum(power{sensor=~"{{plugnames}}"})[1h:1m]"""))?.Data; PrometheusDataWrapper? deviceData = (await promQueryer.Query($$"""sum(power{sensor=~"{{plugnames}}"})[1h:1m]"""))?.Data;
PrometheusDataWrapper? priceData = (await promQueryer.Query($$"""sum(sum_over_time(power{sensor=~"{{plugnames}}"}[1y])*{{energyPrice}})"""))?.Data;
Console.WriteLine(priceData.VectorTypeToTimestampFloatTuple());
var r = new Random(DateTime.Now.Millisecond); var r = new Random(DateTime.Now.Millisecond);
@@ -89,4 +76,30 @@ public partial class Dashboard
return x.Item2; return x.Item2;
}).ToList() ?? new List<double>(); }).ToList() ?? new List<double>();
} }
//TODO: insert dataset of current and last voltage usages
private async Task<LineChartDataset<double>> GetLineChartDataset()
{
return new LineChartDataset<double>
{
Label = "Wattage",
Data = await GetData(),
Fill = true,
PointRadius = 3,
CubicInterpolationMode = "monotone",
};
}
private async Task HandleRedraw()
{
labels.Clear();
await lineChart.Clear();
await lineChart.AddLabelsDatasetsAndUpdate(labels, await GetLineChartDataset());
}
private async Task Switch(Device device)
{
device.Enabled = !device.Enabled;
_ = await DeviceManagmentService.UpdateDevice(device);
}
} }
@@ -1,5 +1,6 @@
@page "/Settings" @page "/Settings"
@using Blazorise.Components; @using Blazorise.Components;
@using Elektrifikatsiya.Database;
@using Elektrifikatsiya.Models; @using Elektrifikatsiya.Models;
@using System.Net @using System.Net
@using System.Text.Json @using System.Text.Json
@@ -9,6 +10,7 @@
@inject IDeviceManagmentService DeviceManagmentService @inject IDeviceManagmentService DeviceManagmentService
@inject IMessageService MessageService @inject IMessageService MessageService
@inject MainDatabaseContext MainDatabaseContext
<Div> <Div>
<Row Style="width: 100%; height: 100%" Margin="Margin.Is3.FromTop.OnMobile" Padding="Padding.Is4.FromStart.OnMobile"> <Row Style="width: 100%; height: 100%" Margin="Margin.Is3.FromTop.OnMobile" Padding="Padding.Is4.FromStart.OnMobile">
@@ -124,7 +126,7 @@
Here you enter your electricity price. This is gonna calculate the overall Price of your System Here you enter your electricity price. This is gonna calculate the overall Price of your System
</Paragraph> </Paragraph>
</FieldLabel> </FieldLabel>
<TextEdit MaxLength="8" Placeholder="Enter Electricity Price" /> <NumericEdit @bind-Value="electricityPrice" MaxLength="8" Placeholder="Enter Electricity Price" />
</Field> </Field>
</Div> </Div>
<Column ColumnSize="ColumnSize.IsFull" TextAlignment="TextAlignment.End"> <Column ColumnSize="ColumnSize.IsFull" TextAlignment="TextAlignment.End">
@@ -139,7 +141,9 @@
@code { @code {
List<Device> plugs = new List<Device>(); List<Device> plugs = new List<Device>();
private bool hideButtonSettings = true; bool hideButtonSettings = true;
double electricityPrice = 0;
Device? SelectedDevice = null; Device? SelectedDevice = null;
Device? DeviceCopy = null; Device? DeviceCopy = null;
@@ -152,6 +156,8 @@
{ {
plugs = getDevicesResult.Value; plugs = getDevicesResult.Value;
} }
electricityPrice = MainDatabaseContext.EnergyPriceChanges.OrderByDescending(e=>e.DateTime).FirstOrDefault()?.EnergyPrice ?? 0;
} }
private void Toggle(Device device) private void Toggle(Device device)
@@ -161,16 +167,19 @@
DeviceCopy = device.CopyDevice(); DeviceCopy = device.CopyDevice();
} }
private void OnSave() private async void OnSave()
{ {
if (hideButtonSettings || DeviceCopy is null || SelectedDevice is null) if (hideButtonSettings)
{ {
MainDatabaseContext.EnergyPriceChanges.Add(new EnergyPriceChange(electricityPrice));
await MainDatabaseContext.SaveChangesAsync();
} }
else else if(DeviceCopy is not null && SelectedDevice is not null)
{ {
SelectedDevice.OverwiteDevice(DeviceCopy); SelectedDevice.OverwiteDevice(DeviceCopy);
DeviceManagmentService.UpdateDevice(SelectedDevice); await DeviceManagmentService.UpdateDevice(SelectedDevice);
} }
} }
@@ -15,7 +15,8 @@ using HiveMQtt.Client.Options;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Prometheus;
using Prometheus.HttpMetrics;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args); WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
@@ -60,7 +61,6 @@ builder.Services.AddBlazorise(options =>
options.Immediate = true; options.Immediate = true;
}); });
AddBlazorise(builder.Services); AddBlazorise(builder.Services);
WebApplication app = builder.Build(); WebApplication app = builder.Build();
@@ -81,6 +81,9 @@ app.UseRouting();
app.MapBlazorHub(); app.MapBlazorHub();
app.MapFallbackToPage("/_Host"); app.MapFallbackToPage("/_Host");
app.MapControllers(); app.MapControllers();
app.MapMetrics();
app.UseHttpMetrics();
app.Services.GetRequiredService<IOptions<EmailSettings>>().Value.CompileTemplates(); app.Services.GetRequiredService<IOptions<EmailSettings>>().Value.CompileTemplates();
@@ -98,7 +101,7 @@ if (!mainDatabase.Users.Any())
app.Run(); app.Run();
void AddBlazorise(IServiceCollection services) static void AddBlazorise(IServiceCollection services)
{ {
_ = services.AddBlazorise(); _ = services.AddBlazorise();
_ = services.AddMaterialProviders(); _ = services.AddMaterialProviders();
@@ -4,7 +4,7 @@ namespace Elektrifikatsiya.Services.Implementations;
public class NotifcationService : INotifcationService public class NotifcationService : INotifcationService
{ {
public TimeSpan ExecutionRepeatDelay => TimeSpan.FromSeconds(30); public TimeSpan ExecutionRepeatDelay => TimeSpan.FromDays(1);
public DateTime FirstExecutionTime => DateTime.Now.AddDays(0); public DateTime FirstExecutionTime => DateTime.Now.AddDays(0);
private readonly IEmailService emailService; private readonly IEmailService emailService;
private readonly ILogger<NotifcationService> logger; private readonly ILogger<NotifcationService> logger;