diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/AddPlug.razor b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/AddPlug.razor
index efabc58..c6e1f26 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Pages/AddPlug.razor
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Pages/AddPlug.razor
@@ -2,13 +2,18 @@
@using Blazorise.Components;
@using Elektrifikatsiya.Models;
@using System.Net
+@using Elektrifikatsiya.Services
+@using Elektrifikatsiya.Services.Implementations
+@using Elektrifikatsiya.Utilities
@inject IVersionProvider VersionProvider
+@inject IDeviceManagmentService DeviceManagmentService
+@inject IAuthenticationService AuthenticationService
@@ -18,17 +23,17 @@
- @context.Item.Name
+ @context.Item
- IP: @context.Item.IpAddress
+ IP: @context.Item
-
@@ -40,5 +45,14 @@
@code {
- List plugs = new List() { new Device("ffff:ffff:ffff:ffff", "Huso", IPAddress.Broadcast, new User("Joe", "qiowruioewjfopa", Role.Admin), "Raum"), new Device("ffff:ffff:ffff:ffff", "Huso", IPAddress.Broadcast, new User("Joe", "qiowruioewjfopa", Role.Admin), "Raum"), new Device("ffff:ffff:ffff:ffff", "Huso", IPAddress.Broadcast, new User("Joe", "qiowruioewjfopa", Role.Admin), "Raum"), };
+ List ipAddresses = new List();
+
+ protected override async Task OnInitializedAsync()
+ {
+ MdnsDiscovery.OnDeviceFound += address =>
+ {
+ ipAddresses.Add(address);
+ InvokeAsync(StateHasChanged);
+ };
+ }
}
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Program.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Program.cs
index 4f9d13e..3c21487 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Program.cs
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Program.cs
@@ -15,16 +15,20 @@ WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
+builder.Services.AddHttpContextAccessor();
builder.Services.AddHostedService();
builder.Services.AddSingleton();
builder.Services.AddTransient();
+builder.Services.AddScoped();
+builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddDbContext(options => options.UseSqlite("Data Source=./UserDatabase.sqlite"));
builder.Services.AddDbContext((options) => options.UseSqlite("Data Source=./DeviceManagement.sqlite"));
builder.Services.AddBootstrapProviders();
builder.Services.AddHttpClient();
builder.Services.AddBlazorise(options =>
{
- options.Immediate = true;
+ options.Immediate = true;
});
AddBlazorise(builder.Services);
@@ -34,9 +38,9 @@ WebApplication app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
- _ = app.UseExceptionHandler("/Error");
- // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
- _ = app.UseHsts();
+ _ = app.UseExceptionHandler("/Error");
+ // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+ _ = app.UseHsts();
}
app.UseHttpsRedirection();
@@ -46,12 +50,11 @@ app.UseStaticFiles();
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
+app.MapControllers();
IServiceScope serviceScope = app.Services.GetRequiredService().CreateScope();
serviceScope.ServiceProvider.GetRequiredService().Database.EnsureCreated();
-app.MapControllers();
-
AsyncServiceScope scope = app.Services.CreateAsyncScope();
scope.ServiceProvider.GetRequiredService().Database.EnsureCreated();
@@ -59,7 +62,7 @@ app.Run();
void AddBlazorise(IServiceCollection services)
{
- _ = services.AddBlazorise();
- _ = services.AddMaterialProviders();
- _ = services.AddMaterialIcons();
+ _ = services.AddBlazorise();
+ _ = services.AddMaterialProviders();
+ _ = services.AddMaterialIcons();
}
\ No newline at end of file
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Properties/launchSettings.json b/src/Elektrifikatsiya/Elektrifikatsiya/Properties/launchSettings.json
index 71c02c5..fe359ad 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Properties/launchSettings.json
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Properties/launchSettings.json
@@ -7,7 +7,7 @@
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
- "applicationUrl": "https://localhost:7297;http://localhost:5255"
+ "applicationUrl": "https://localhost:56656;http://localhost:5255"
},
"IIS Express": {
"commandName": "IISExpress",
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceManagmentService.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceManagmentService.cs
index bda0e67..764ee22 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceManagmentService.cs
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceManagmentService.cs
@@ -8,9 +8,9 @@ namespace Elektrifikatsiya.Services;
public interface IDeviceManagmentService
{
- public Task> Register(IPAddress ip, User user, string? name = null, string room = "default");
+ public Task> RegisterDevice(IPAddress ip, User user, string? name = null, string room = "default");
- public Task Unregister(string macAdress);
+ public Task UnregisterDevice(string macAdress);
public Result GetDevice(string macAdress);
@@ -19,4 +19,6 @@ public interface IDeviceManagmentService
public Result> GetDevicesInRoom(string room);
public Result> GetDevicesOfUser(int userId);
+
+ public Task UpdateDevice(Device device);
}
\ No newline at end of file
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceManagmentService.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceManagmentService.cs
index 7cb9954..11937e6 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceManagmentService.cs
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceManagmentService.cs
@@ -10,123 +10,138 @@ namespace Elektrifikatsiya.Services.Implementations;
public class DeviceManagmentService : IDeviceManagmentService
{
- private readonly DeviceManagmentDatabaseContext deviceManagmentDatabaseContext;
- private readonly IDeviceStatusService deviceStatusService;
- private readonly IServiceScopeFactory serviceScopeFactory;
- private readonly HttpClient httpClient;
+ private readonly DeviceManagmentDatabaseContext deviceManagmentDatabaseContext;
+ private readonly IServiceScopeFactory serviceScopeFactory;
+ private readonly IDeviceStatusService deviceStatusService;
+ private readonly HttpClient httpClient;
- public DeviceManagmentService(IServiceScopeFactory serviceScopeFactory, IDeviceStatusService deviceStatusService, HttpClient httpClient)
- {
- this.deviceManagmentDatabaseContext = deviceManagmentDatabaseContext;
- this.deviceStatusService = deviceStatusService;
- this.httpClient = httpClient;
- }
+ public DeviceManagmentService(IServiceScopeFactory serviceScopeFactory, IDeviceStatusService deviceStatusService, HttpClient httpClient)
+ {
+ this.serviceScopeFactory = serviceScopeFactory;
+ this.deviceStatusService = deviceStatusService;
+ this.httpClient = httpClient;
- public Result GetDevice(string macAdress)
- {
- Result> getDevicesResult = deviceStatusService.GetDevices();
+ }
- if (getDevicesResult.IsFailed)
- {
- return getDevicesResult.ToResult();
- }
+ public Result GetDevice(string macAdress)
+ {
+ Result> getDevicesResult = deviceStatusService.GetDevices();
- Device? device = getDevicesResult.Value.FirstOrDefault(d => d.MacAddress == macAdress);
+ if (getDevicesResult.IsFailed)
+ {
+ return getDevicesResult.ToResult();
+ }
- if (device is null)
- {
- return Result.Fail("Device does not exist!");
- }
+ Device? device = getDevicesResult.Value.FirstOrDefault(d => d.MacAddress == macAdress);
- return device;
- }
+ if (device is null)
+ {
+ return Result.Fail("Device does not exist!");
+ }
- public Result> GetDevices()
- {
- Result> getDevicesResult = deviceStatusService.GetDevices();
+ return device;
+ }
- if (getDevicesResult.IsFailed)
- {
- return getDevicesResult.ToResult();
- }
+ public Result> GetDevices()
+ {
+ Result> getDevicesResult = deviceStatusService.GetDevices();
- return getDevicesResult.Value.ToList();
- }
+ if (getDevicesResult.IsFailed)
+ {
+ return getDevicesResult.ToResult();
+ }
- public Result> GetDevicesInRoom(string room)
- {
- Result> getDevicesResult = deviceStatusService.GetDevices();
+ return getDevicesResult.Value.ToList();
+ }
- if (getDevicesResult.IsFailed)
- {
- return getDevicesResult.ToResult();
- }
+ public Result> GetDevicesInRoom(string room)
+ {
+ Result> getDevicesResult = deviceStatusService.GetDevices();
- return getDevicesResult.Value.Where(d => d.Room == room).ToList();
- }
+ if (getDevicesResult.IsFailed)
+ {
+ return getDevicesResult.ToResult();
+ }
- public Result> GetDevicesOfUser(int userId)
- {
- Result> getDevicesResult = deviceStatusService.GetDevices();
+ return getDevicesResult.Value.Where(d => d.Room == room).ToList();
+ }
- if (getDevicesResult.IsFailed)
- {
- return getDevicesResult.ToResult();
- }
+ public Result> GetDevicesOfUser(int userId)
+ {
+ Result> getDevicesResult = deviceStatusService.GetDevices();
- return getDevicesResult.Value.Where(d => d.User.Id == userId).ToList();
- }
+ if (getDevicesResult.IsFailed)
+ {
+ return getDevicesResult.ToResult();
+ }
- public async Task> Register(IPAddress ip, User user, string? name = null, string room = "default")
- {
- using IServiceScope scope = serviceScopeFactory.CreateScope();
- DeviceManagmentDatabaseContext deviceManagmentDatabaseContext = scope.ServiceProvider.GetRequiredService();
+ return getDevicesResult.Value.Where(d => d.User.Id == userId).ToList();
+ }
- ShellyResponse? shellyResponse = await httpClient.GetFromJsonAsync($"{ip}/shelly");
+ public async Task> RegisterDevice(IPAddress ip, User user, string? name = null, string room = "default")
+ {
+ using IServiceScope scope = serviceScopeFactory.CreateScope();
+ DeviceManagmentDatabaseContext deviceManagmentDatabaseContext = scope.ServiceProvider.GetRequiredService();
- if (shellyResponse is null || shellyResponse.Type != "SHPLG-S")
- {
- return Result.Fail("Device is not a \"SHPLG-S\" or not reachable!");
- }
+ ShellyResponse? shellyResponse = await httpClient.GetFromJsonAsync($"http://{ip}/shelly");
- string mac = shellyResponse.Mac;
+ if (shellyResponse is null || shellyResponse.Type != "SHPLG-S")
+ {
+ return Result.Fail("Device is not reachable or not a \"SHPLG-S\"!");
+ }
- if (PhysicalAddress.TryParse(mac, out _))
- {
- return Result.Fail("Invalid mac address!");
- }
+ string mac = shellyResponse.Mac;
- Device device = new Device(mac, name ?? mac, ip, user, room);
+ if (!PhysicalAddress.TryParse(mac, out _))
+ {
+ return Result.Fail("Invalid mac address!");
+ }
- deviceManagmentDatabaseContext.Add(device);
- Result saveDatabaseChangesResult = await Result.Try(async Task () => await deviceManagmentDatabaseContext.SaveChangesAsync());
+ Device device = new Device(mac, name ?? mac, ip, user, room);
- Result trackDeviceResult = deviceStatusService.TrackDevice(device);
+ deviceManagmentDatabaseContext.Add(device);
+ Result saveDatabaseChangesResult = await Result.Try(Task () => deviceManagmentDatabaseContext.SaveChangesAsync());
- return Result.Merge(saveDatabaseChangesResult, trackDeviceResult).ToResult(device);
- }
+ Result trackDeviceResult = deviceStatusService.TrackDevice(device);
- public async Task Unregister(string macAdress)
- {
- using IServiceScope scope = serviceScopeFactory.CreateScope();
- DeviceManagmentDatabaseContext deviceManagmentDatabaseContext = scope.ServiceProvider.GetRequiredService();
+ return Result.Merge(saveDatabaseChangesResult, trackDeviceResult).ToResult(device);
+ }
+
+ public async Task UnregisterDevice(string macAdress)
+ {
+ using IServiceScope scope = serviceScopeFactory.CreateScope();
+ DeviceManagmentDatabaseContext deviceManagmentDatabaseContext = scope.ServiceProvider.GetRequiredService();
Result getDeviceResult = GetDevice(macAdress);
- if (getDeviceResult.IsFailed)
- {
- return getDeviceResult.ToResult();
- }
+ if (getDeviceResult.IsFailed)
+ {
+ return getDeviceResult.ToResult();
+ }
- Result untrackDeviceResult = deviceStatusService.UntrackDevice(macAdress);
+ Result untrackDeviceResult = deviceStatusService.UntrackDevice(macAdress);
- if (untrackDeviceResult.IsFailed)
- {
- return untrackDeviceResult;
- }
+ if (untrackDeviceResult.IsFailed)
+ {
+ return untrackDeviceResult;
+ }
- deviceManagmentDatabaseContext.Remove(getDeviceResult.Value);
+ deviceManagmentDatabaseContext.Remove(getDeviceResult.Value);
- return await Result.Try(async Task () => await deviceManagmentDatabaseContext.SaveChangesAsync());
- }
+ return await Result.Try(Task () => deviceManagmentDatabaseContext.SaveChangesAsync());
+ }
+
+ public async Task UpdateDevice(Device device)
+ {
+ Result result = deviceStatusService.UpdateDeviceStatus(device);
+
+ if (result.IsFailed)
+ {
+ return result;
+ }
+
+ deviceManagmentDatabaseContext.Update(device);
+
+ return await Result.Try(Task () => deviceManagmentDatabaseContext.SaveChangesAsync());
+ }
}
\ No newline at end of file
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceStatusService.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceStatusService.cs
index 3574cec..2e6e904 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceStatusService.cs
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceStatusService.cs
@@ -6,10 +6,15 @@ namespace Elektrifikatsiya.Services.Implementations;
public class DeviceStatusService : IDeviceStatusService
{
- public event EventHandler? OnDeviceStatusChanged;
+ private readonly ILogger logger;
+ public event EventHandler? OnDeviceStatusChanged;
private readonly Dictionary devices = new();
-
+
+ public DeviceStatusService(ILogger logger)
+ {
+ this.logger = logger;
+ }
public Result> GetDevices()
{
return devices.Values.ToList();
@@ -41,6 +46,8 @@ public class DeviceStatusService : IDeviceStatusService
return Result.Fail("Device already tracked!");
}
+ logger.LogInformation("Tracking new Device {device}", device.IpAddress);
+
devices[device.MacAddress] = device;
return Result.Ok();
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Utilities/MdnsDiscovery.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Utilities/MdnsDiscovery.cs
new file mode 100644
index 0000000..8b9c46a
--- /dev/null
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Utilities/MdnsDiscovery.cs
@@ -0,0 +1,20 @@
+using System.Net;
+using FluentResults;
+using Tmds.MDns;
+
+namespace Elektrifikatsiya.Utilities;
+
+public static class MdnsDiscovery
+{
+ public static event Action OnDeviceFound;
+
+ static ServiceBrowser serviceBrowser = new ServiceBrowser();
+
+ static MdnsDiscovery()
+ {
+ serviceBrowser.StartBrowse("_http._tcp");
+ serviceBrowser.ServiceAdded += (_, eventArgs) => OnDeviceFound?.Invoke(eventArgs.Announcement.Addresses.First());
+ serviceBrowser.ServiceChanged += (_, eventArgs) => OnDeviceFound?.Invoke(eventArgs.Announcement.Addresses.First());
+ serviceBrowser.ServiceRemoved += (_, eventArgs) => OnDeviceFound?.Invoke(eventArgs.Announcement.Addresses.First());
+ }
+}
\ No newline at end of file