diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Models/DeviceStatusChagedEventArgs.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Models/DeviceStatusChangedEventArgs.cs similarity index 53% rename from src/Elektrifikatsiya/Elektrifikatsiya/Models/DeviceStatusChagedEventArgs.cs rename to src/Elektrifikatsiya/Elektrifikatsiya/Models/DeviceStatusChangedEventArgs.cs index 8b85cd5..caad485 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Models/DeviceStatusChagedEventArgs.cs +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Models/DeviceStatusChangedEventArgs.cs @@ -1,10 +1,10 @@ namespace Elektrifikatsiya.Models; -public class DeviceStatusChagedEventArgs : EventArgs +public class DeviceStatusChangedEventArgs : EventArgs { public string MacAddress { get; set; } - public DeviceStatusChagedEventArgs(string macAddress) + public DeviceStatusChangedEventArgs(string macAddress) { MacAddress = macAddress; } diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Models/Event.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Models/Event.cs index 40c67ac..7052b93 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Models/Event.cs +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Models/Event.cs @@ -11,14 +11,16 @@ namespace Elektrifikatsiya.Models public string EventName { get; set; } public string Description { get; set; } public DateTime Date { get; set; } - + public Device Plug { get; set; } //if Plug Class implemented -> Property for which plug this event is from - public Event(string eventName, string description, DateTime date) + public Event() { } + public Event(string eventName, string description, DateTime date, Device plug) { EventName = eventName; Description = description; Date = date; + Plug = plug; } } } diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Models/EventServiceEventArgs.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Models/EventServiceEventArgs.cs new file mode 100644 index 0000000..4065bb5 --- /dev/null +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Models/EventServiceEventArgs.cs @@ -0,0 +1,11 @@ +namespace Elektrifikatsiya.Models +{ + public class EventServiceEventArgs : EventArgs + { + public Event NewEvent { get; set; } = new Event(); + public EventServiceEventArgs(Event newEvent) + { + NewEvent = newEvent; + } + } +} diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor index 66a3051..70fc325 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor @@ -7,90 +7,88 @@ @using System.Diagnostics @using Elektrifikatsiya.Services.Implementations @inject IVersionProvider VersionProvider +@inject IDeviceStatusService DeviceStatusService +@inject IEventService EventService -@inject IDeviceStatusService DeviceStatusService; -@inject IDeviceManagmentService DeviceManagmentService; + +
+ + + + Plugs + + + + + + + + + + @context.Item.Name + + + + + User: @context.Item.User.Name +
+ Room: @context.Item.Room +
+ + @context.Item.PowerUsage W + +
+
+ + + +
+
+
+
+
+ + + + Logs + + + -
- -
- - - - Plugs - - - - - - - - - - @context.Item.Name - - - - - User: @context.Item.User.Name -
- Room: @context.Item.Room -
- - @context.Item.PowerUsage W - -
-
- - - -
-
-
-
-
- - - - Logs - - - - -
- @context.Item.EventName - @context.Item.Date -
- @context.Item.Description -
-
-
-
-
- - - - - - -
+ +
+ @context.Item.EventName + @context.Item.Date +
+ @context.Item.Description +
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor.cs index 3d70f26..f5dc2b6 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor.cs +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Dashboard.razor.cs @@ -10,88 +10,83 @@ namespace Elektrifikatsiya.Pages; public partial class Dashboard { - //TODO: insert new event here if plug produces one - private readonly List events = new List() { new Event("Placeholder", "Placeholder", DateTime.Now), new Event("Placeholder", "Placeholder", DateTime.Now), new Event("Placeholder", "Placeholder", DateTime.Now) }; + //TODO: insert new event here if plug produces one + List events = new List() { new Event("Text", "Text", DateTime.Today, null ) }; + //TODO: insert new Device here if user adds one + List plugs = new List(); + //code for graph + LineChart lineChart; - //TODO: insert new Device here if user adds one - private List plugs = new List(); + protected override void OnInitialized() + { + plugs = DeviceStatusService.GetDevices().ValueOrDefault ?? new List(); + events = EventService.Events; - //code for graph - private LineChart lineChart; + EventService.OnEventCalled += (_, e) => + { + _ = InvokeAsync(StateHasChanged); + }; + DeviceStatusService.OnDeviceStatusChanged += (_, e) => + { + _ = InvokeAsync(StateHasChanged); + }; + } - protected override void OnInitialized() - { - plugs = DeviceStatusService.GetDevices().ValueOrDefault ?? new List(); + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await HandleRedraw(); + } + } - DeviceStatusService.OnDeviceStatusChanged += (_, e) => - { - _ = InvokeAsync(StateHasChanged); - }; - } + async Task HandleRedraw() + { + labels.Clear(); + await lineChart.Clear(); + await lineChart.AddLabelsDatasetsAndUpdate(labels, await GetLineChartDataset()); + } - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await HandleRedraw(); - } - } + //TODO: insert dataset of current and last voltage usages + async Task> GetLineChartDataset() + { + return new LineChartDataset + { + Label = "Wattage", + Data = await RandomizeData(), + Fill = true, + PointRadius = 3, + CubicInterpolationMode = "monotone", + }; + } - private async Task Switch(Device device) - { - device.Enabled = !device.Enabled; - _ = await DeviceManagmentService.UpdateDevice(device); - } + List labels = new List(); - private async Task HandleRedraw() - { - labels.Clear(); - await lineChart.Clear(); - await lineChart.AddLabelsDatasetsAndUpdate(labels, await GetLineChartDataset()); - } + async Task> RandomizeData() + { + if (plugs.Count == 0) + { + return new(); + } + PrometheusQuery promQueryer = new PrometheusQuery("http://localhost:9090"); - //TODO: insert dataset of current and last voltage usages - private async Task> GetLineChartDataset() - { - return new LineChartDataset - { - Label = "Wattage", - Data = await DeviceData(), - Fill = true, - PointRadius = 3, - CubicInterpolationMode = "monotone", - }; - } + string plugnames = ""; + foreach (Device device in plugs) + { + plugnames += $"shellyplug-s-{device.MacAddress}/relay/0|"; + } + plugnames = plugnames[0..^1]; - private readonly List labels = new List(); + Debug.WriteLine($$"""sum(power{sensor=~"{{plugnames}}"})[1h:1m]"""); - private async Task> DeviceData() - { - PrometheusQuery promQueryer = new PrometheusQuery("http://localhost:9090"); + PrometheusDataWrapper? deviceData = (await promQueryer.Query($$"""sum(power{sensor=~"{{plugnames}}"})[1h:1m]"""))?.Data; - StringBuilder builder = new(); - foreach (Device device in plugs) - { - _ = builder.Append($"shellyplug-s-{device.MacAddress}/relay/0|"); - } + var r = new Random(DateTime.Now.Millisecond); - if (builder.Length <= 1) - { - return new(); - } - - string plugnames = builder.ToString()[..^1]; - - Debug.WriteLine($$"""sum(power{sensor=~"{{plugnames}}"})[1h:1m]"""); - - PrometheusDataWrapper? deviceData = (await promQueryer.Query($$"""sum(power{sensor=~"{{plugnames}}"})[1h:1m]"""))?.Data; - - Random r = new Random(DateTime.Now.Millisecond); - - return deviceData?.MatrixTypeToTimestampFloatTuple().ValueOrDefault?.Select(x => - { - labels.Add(DateTimeOffset.FromUnixTimeSeconds(long.Parse($"1{x.Item1}0")).UtcDateTime.ToLocalTime().ToShortTimeString()); - return x.Item2; - }).ToList() ?? new List(); - } -} \ No newline at end of file + return deviceData?.MatrixTypeToTimestampFloatTuple().ValueOrDefault?.Select(x => + { + labels.Add(DateTimeOffset.FromUnixTimeSeconds(long.Parse($"1{x.Item1}0")).UtcDateTime.ToLocalTime().ToShortTimeString()); + return x.Item2; + }).ToList() ?? new List(); + } +} diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Settings.razor b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Settings.razor index 263b2af..f55ddc8 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Settings.razor +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/Settings.razor @@ -90,21 +90,7 @@ Here you can change the name of your plug - - -
-
- - -
- Change Max Output -
- - Here you can limit how much power your plug uses - -
- - +


@@ -117,7 +103,7 @@ Here you select or change the room the plug belongs to. - + } @@ -138,7 +124,7 @@ Here you enter your electricity price. This is gonna calculate the overall Price of your System - + diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceStatusService.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceStatusService.cs index 61e1cc1..ef10788 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceStatusService.cs +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceStatusService.cs @@ -6,7 +6,7 @@ namespace Elektrifikatsiya.Services; public interface IDeviceStatusService { - public event EventHandler OnDeviceStatusChanged; + public event EventHandler OnDeviceStatusChanged; public Result> GetDevices(); diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Services/IEventService.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Services/IEventService.cs new file mode 100644 index 0000000..9445447 --- /dev/null +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/IEventService.cs @@ -0,0 +1,10 @@ +using Elektrifikatsiya.Models; + +namespace Elektrifikatsiya.Services +{ + public interface IEventService + { + public List Events { get; } + public event EventHandler OnEventCalled; + } +} diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceStatusService.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceStatusService.cs index becc6f4..4c4f35b 100644 --- a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceStatusService.cs +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceStatusService.cs @@ -1,5 +1,4 @@ using Elektrifikatsiya.Models; - using FluentResults; namespace Elektrifikatsiya.Services.Implementations; @@ -7,15 +6,14 @@ namespace Elektrifikatsiya.Services.Implementations; public class DeviceStatusService : IDeviceStatusService { private readonly ILogger logger; - - public event EventHandler? OnDeviceStatusChanged; + public event EventHandler? OnDeviceStatusChanged; private readonly Dictionary devices = new(); public DeviceStatusService(ILogger logger) { this.logger = logger; - } + } public Result> GetDevices() { @@ -36,7 +34,7 @@ public class DeviceStatusService : IDeviceStatusService modDevice.IpAddress = device.IpAddress; modDevice.Name = device.Name; - OnDeviceStatusChanged?.Invoke(this, new DeviceStatusChagedEventArgs(device.MacAddress)); + OnDeviceStatusChanged?.Invoke(this, new DeviceStatusChangedEventArgs(device.MacAddress)); return Result.Ok(); } diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/EventService.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/EventService.cs new file mode 100644 index 0000000..3fa5e9a --- /dev/null +++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/EventService.cs @@ -0,0 +1,55 @@ +using Elektrifikatsiya.Models; +using FluentResults; +using System.Reflection; + +namespace Elektrifikatsiya.Services.Implementations +{ + public class EventService : IEventService + { + private readonly ILogger logger; + public event EventHandler OnEventCalled; + public List Events { get; } = new(); + + public EventService(ILogger logger, IDeviceStatusService deviceStatusService, IDeviceManagmentService deviceManagmentService) + { + this.logger = logger; + List deviceList = deviceManagmentService.GetDevices().ValueOrDefault.Select(x=>x.CopyDevice()).ToList(); + + deviceStatusService.OnDeviceStatusChanged += (_, e) => + { + bool newDevice = true; + Device currentDevice = deviceManagmentService.GetDevice(e.MacAddress).ValueOrDefault; + + for (int i = 0; i < deviceList.Count; i++) + { + if (deviceList[i].MacAddress == currentDevice.MacAddress) + { + PropertyInfo[] properties = typeof(Device).GetProperties(); + + foreach(PropertyInfo property in properties) { + var currentvalue = property.GetValue(deviceList[i], null); + var newvalue = property.GetValue(currentDevice, null); + if(newvalue is not null && !newvalue.ToString().Equals(currentvalue.ToString())) + { + string eventName = $"Plug {deviceList[i].Name} changed: {property.Name}"; + string description = $"Changed {property.Name} of plug [{currentvalue}] to [{newvalue}]"; + DateTime dateTime = DateTime.Now; + + Event newEvent = new Event(eventName, description, dateTime, currentDevice); + Events.Insert(0,newEvent); + OnEventCalled?.Invoke(this, new EventServiceEventArgs(newEvent)); + } + + } + deviceList[i].OverwiteDevice(currentDevice); + newDevice = false; break; + } + } + if (newDevice) + { + deviceList.Add(deviceManagmentService.GetDevice(e.MacAddress).ValueOrDefault); + } + }; + } + } +}