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 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 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 "/"
@using Blazorise.Components;
@using Elektrifikatsiya.Database;
@using Elektrifikatsiya.Models;
@using System.Net
@using Elektrifikatsiya.Services
@@ -7,11 +8,15 @@
@using System.Diagnostics
@using Elektrifikatsiya.Services.Implementations
@inject IVersionProvider VersionProvider
@inject IDeviceStatusService DeviceStatusService
@inject IEventService EventService
<Row Padding="Padding.Is3">
<Div Display="Display.Flex.Row.OnDesktop" Margin="Margin.Is3.FromBottom" Width="Width.Is100">
@inject IDeviceStatusService DeviceStatusService;
@inject IDeviceManagmentService DeviceManagmentService;
@inject IEventService EventService;
@inject MainDatabaseContext MainDatabaseContext;
<Div>
<Row Padding="Padding.Is3">
<Div Display="Display.Flex.Row.OnDesktop" Margin=" Margin.Is3.FromBottom" Width="Width.Is100">
<Column ColumnSize="ColumnSize.Is6.OnDesktop.Is12">
<Bar Breakpoint="Breakpoint.Desktop"
Background="Background.White"
@@ -29,7 +34,7 @@
Mode="ListGroupMode.Static"
Style="border-radius: 0px 0px">
<ItemTemplate>
<ListGroupItem Border="Border.OnBottom">
<ListGroupItem>
<Row>
<Column ColumnSize="ColumnSize.Is8">
<Row>
@@ -49,8 +54,8 @@
</Row>
</Column>
<Column ColumnSize="ColumnSize.Is4">
<Button Position="Position.Absolute.Top.Is50.Start.Is50.Translate.Middle" Color="Color.Dark" Outline>
<BarIcon IconName="IconName.Bolt" />
<Button Clicked="() => Switch(context.Item)" Position="Position.Absolute.Top.Is50.Start.Is50.Translate.Middle" Color="Color.Primary" Primary Outline>
<BarIcon TextColor="(context.Item.Enabled?TextColor.Success:TextColor.Danger)" IconName="IconName.Bolt" />
</Button>
</Column>
</Row>
@@ -74,21 +79,21 @@
ValueField="@((_)=>(""))"
Mode="ListGroupMode.Static"
Style="border-radius: 0px 0px">
<ItemTemplate>
<Div Flex="Flex.InlineFlex.JustifyContent.Between" Width="Width.Is100">
<Heading Size="HeadingSize.Is6" Margin="Margin.Is2.FromBottom">@context.Item.EventName</Heading>
<Small>@context.Item.Date</Small>
</Div>
<Paragraph Border="Border.OnBottom" Margin="Margin.Is2.FromBottom">@context.Item.Description</Paragraph>
<Paragraph Margin="Margin.Is2.FromBottom">@context.Item.Description</Paragraph>
</ItemTemplate>
</ListView>
</Column>
</Div>
</Row>
<Row Padding="Padding.Is3">
</Row>
<Row Padding="Padding.Is3">
<Column>
<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>
</Row>
</Row>
</Div>
@@ -5,17 +5,31 @@ using Elektrifikatsiya.Utilities;
using System.Diagnostics;
using System.Text;
using Elektrifikatsiya.Services.Implementations;
using Elektrifikatsiya.Database;
namespace Elektrifikatsiya.Pages;
public partial class Dashboard
{
//TODO: insert new event here if plug produces one
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<Event> events = new List<Event>() { new Event("Text", "Text", DateTime.Today, null) };
private List<string> labels = new List<string>();
//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()
{
@@ -32,37 +46,7 @@ public partial class Dashboard
};
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
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()
private async Task<List<double>> GetData()
{
if (plugs.Count == 0)
{
@@ -77,9 +61,12 @@ public partial class Dashboard
}
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? 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);
@@ -89,4 +76,30 @@ public partial class Dashboard
return x.Item2;
}).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"
@using Blazorise.Components;
@using Elektrifikatsiya.Database;
@using Elektrifikatsiya.Models;
@using System.Net
@using System.Text.Json
@@ -9,6 +10,7 @@
@inject IDeviceManagmentService DeviceManagmentService
@inject IMessageService MessageService
@inject MainDatabaseContext MainDatabaseContext
<Div>
<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
</Paragraph>
</FieldLabel>
<TextEdit MaxLength="8" Placeholder="Enter Electricity Price" />
<NumericEdit @bind-Value="electricityPrice" MaxLength="8" Placeholder="Enter Electricity Price" />
</Field>
</Div>
<Column ColumnSize="ColumnSize.IsFull" TextAlignment="TextAlignment.End">
@@ -139,7 +141,9 @@
@code {
List<Device> plugs = new List<Device>();
private bool hideButtonSettings = true;
bool hideButtonSettings = true;
double electricityPrice = 0;
Device? SelectedDevice = null;
Device? DeviceCopy = null;
@@ -152,6 +156,8 @@
{
plugs = getDevicesResult.Value;
}
electricityPrice = MainDatabaseContext.EnergyPriceChanges.OrderByDescending(e=>e.DateTime).FirstOrDefault()?.EnergyPrice ?? 0;
}
private void Toggle(Device device)
@@ -161,16 +167,19 @@
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);
DeviceManagmentService.UpdateDevice(SelectedDevice);
await DeviceManagmentService.UpdateDevice(SelectedDevice);
}
}
@@ -15,7 +15,8 @@ using HiveMQtt.Client.Options;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Prometheus;
using Prometheus.HttpMetrics;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
@@ -32,7 +33,7 @@ builder.Services.AddSingleton<IUpdateService, UpdateService>();
builder.Services.AddSingleton<IDeviceStatusService, DeviceStatusService>();
builder.Services.AddSingleton<INotificationService, NotifcationService>();
builder.Services.AddSingleton<IScheduledService>(s => s.GetRequiredService<IUpdateService>());
builder.Services.AddSingleton<IScheduledService>(s=>s.GetRequiredService<INotificationService>());
builder.Services.AddSingleton<IScheduledService>(s => s.GetRequiredService<INotificationService>());
builder.Services.AddSingleton<IEmailService, EmailService>();
builder.Services.AddSingleton<IEventService, EventService>();
builder.Services.AddSingleton<IHiveMQClient, HiveMQClient>((provider)=>
@@ -60,7 +61,6 @@ builder.Services.AddBlazorise(options =>
options.Immediate = true;
});
AddBlazorise(builder.Services);
WebApplication app = builder.Build();
@@ -81,6 +81,9 @@ app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.MapControllers();
app.MapMetrics();
app.UseHttpMetrics();
app.Services.GetRequiredService<IOptions<EmailSettings>>().Value.CompileTemplates();
@@ -98,7 +101,7 @@ if (!mainDatabase.Users.Any())
app.Run();
void AddBlazorise(IServiceCollection services)
static void AddBlazorise(IServiceCollection services)
{
_ = services.AddBlazorise();
_ = services.AddMaterialProviders();
@@ -4,7 +4,7 @@ namespace Elektrifikatsiya.Services.Implementations;
public class NotifcationService : INotifcationService
{
public TimeSpan ExecutionRepeatDelay => TimeSpan.FromSeconds(30);
public TimeSpan ExecutionRepeatDelay => TimeSpan.FromDays(1);
public DateTime FirstExecutionTime => DateTime.Now.AddDays(0);
private readonly IEmailService emailService;
private readonly ILogger<NotifcationService> logger;