mirror of
https://github.com/Stefan-5422/-T5-Elektrifikatsiya.git
synced 2026-09-04 00:45:58 +02:00
Improve MdnsDiscovery
This commit is contained in:
@@ -47,8 +47,9 @@
|
|||||||
@code {
|
@code {
|
||||||
List<IPAddress> ipAddresses = new List<IPAddress>();
|
List<IPAddress> ipAddresses = new List<IPAddress>();
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
|
ipAddresses.AddRange(MdnsDiscovery.GetChachedDevices());
|
||||||
MdnsDiscovery.OnDeviceFound += address =>
|
MdnsDiscovery.OnDeviceFound += address =>
|
||||||
{
|
{
|
||||||
ipAddresses.Add(address);
|
ipAddresses.Add(address);
|
||||||
|
|||||||
+108
-97
@@ -10,138 +10,149 @@ namespace Elektrifikatsiya.Services.Implementations;
|
|||||||
|
|
||||||
public class DeviceManagmentService : IDeviceManagmentService
|
public class DeviceManagmentService : IDeviceManagmentService
|
||||||
{
|
{
|
||||||
private readonly DeviceManagmentDatabaseContext deviceManagmentDatabaseContext;
|
private readonly DeviceManagmentDatabaseContext deviceManagmentDatabaseContext;
|
||||||
private readonly IServiceScopeFactory serviceScopeFactory;
|
private readonly IServiceScopeFactory serviceScopeFactory;
|
||||||
private readonly IDeviceStatusService deviceStatusService;
|
private readonly IDeviceStatusService deviceStatusService;
|
||||||
private readonly HttpClient httpClient;
|
private readonly ILogger<DeviceManagmentService> logger;
|
||||||
|
private readonly HttpClient httpClient;
|
||||||
|
|
||||||
public DeviceManagmentService(IServiceScopeFactory serviceScopeFactory, IDeviceStatusService deviceStatusService, HttpClient httpClient)
|
public DeviceManagmentService(IServiceScopeFactory serviceScopeFactory, IDeviceStatusService deviceStatusService, ILogger<DeviceManagmentService> logger, HttpClient httpClient)
|
||||||
{
|
{
|
||||||
this.serviceScopeFactory = serviceScopeFactory;
|
this.serviceScopeFactory = serviceScopeFactory;
|
||||||
this.deviceStatusService = deviceStatusService;
|
this.deviceStatusService = deviceStatusService;
|
||||||
this.httpClient = httpClient;
|
this.logger = logger;
|
||||||
|
this.httpClient = httpClient;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<Device> GetDevice(string macAdress)
|
public Result<Device> GetDevice(string macAdress)
|
||||||
{
|
{
|
||||||
Result<List<Device>> getDevicesResult = deviceStatusService.GetDevices();
|
Result<List<Device>> getDevicesResult = deviceStatusService.GetDevices();
|
||||||
|
|
||||||
if (getDevicesResult.IsFailed)
|
if (getDevicesResult.IsFailed)
|
||||||
{
|
{
|
||||||
return getDevicesResult.ToResult();
|
return getDevicesResult.ToResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
Device? device = getDevicesResult.Value.FirstOrDefault(d => d.MacAddress == macAdress);
|
Device? device = getDevicesResult.Value.FirstOrDefault(d => d.MacAddress == macAdress);
|
||||||
|
|
||||||
if (device is null)
|
if (device is null)
|
||||||
{
|
{
|
||||||
return Result.Fail("Device does not exist!");
|
return Result.Fail("Device does not exist!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<List<Device>> GetDevices()
|
public Result<List<Device>> GetDevices()
|
||||||
{
|
{
|
||||||
Result<List<Device>> getDevicesResult = deviceStatusService.GetDevices();
|
Result<List<Device>> getDevicesResult = deviceStatusService.GetDevices();
|
||||||
|
|
||||||
if (getDevicesResult.IsFailed)
|
if (getDevicesResult.IsFailed)
|
||||||
{
|
{
|
||||||
return getDevicesResult.ToResult();
|
return getDevicesResult.ToResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
return getDevicesResult.Value.ToList();
|
return getDevicesResult.Value.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<List<Device>> GetDevicesInRoom(string room)
|
public Result<List<Device>> GetDevicesInRoom(string room)
|
||||||
{
|
{
|
||||||
Result<List<Device>> getDevicesResult = deviceStatusService.GetDevices();
|
Result<List<Device>> getDevicesResult = deviceStatusService.GetDevices();
|
||||||
|
|
||||||
if (getDevicesResult.IsFailed)
|
if (getDevicesResult.IsFailed)
|
||||||
{
|
{
|
||||||
return getDevicesResult.ToResult();
|
return getDevicesResult.ToResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
return getDevicesResult.Value.Where(d => d.Room == room).ToList();
|
return getDevicesResult.Value.Where(d => d.Room == room).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<List<Device>> GetDevicesOfUser(int userId)
|
public Result<List<Device>> GetDevicesOfUser(int userId)
|
||||||
{
|
{
|
||||||
Result<List<Device>> getDevicesResult = deviceStatusService.GetDevices();
|
Result<List<Device>> getDevicesResult = deviceStatusService.GetDevices();
|
||||||
|
|
||||||
if (getDevicesResult.IsFailed)
|
if (getDevicesResult.IsFailed)
|
||||||
{
|
{
|
||||||
return getDevicesResult.ToResult();
|
return getDevicesResult.ToResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
return getDevicesResult.Value.Where(d => d.User.Id == userId).ToList();
|
return getDevicesResult.Value.Where(d => d.User.Id == userId).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Result<Device>> RegisterDevice(IPAddress ip, User user, string? name = null, string room = "default")
|
public async Task<Result<Device>> RegisterDevice(IPAddress ip, User user, string? name = null, string room = "default")
|
||||||
{
|
{
|
||||||
using IServiceScope scope = serviceScopeFactory.CreateScope();
|
using IServiceScope scope = serviceScopeFactory.CreateScope();
|
||||||
DeviceManagmentDatabaseContext deviceManagmentDatabaseContext = scope.ServiceProvider.GetRequiredService<DeviceManagmentDatabaseContext>();
|
DeviceManagmentDatabaseContext deviceManagmentDatabaseContext = scope.ServiceProvider.GetRequiredService<DeviceManagmentDatabaseContext>();
|
||||||
|
|
||||||
ShellyResponse? shellyResponse = await httpClient.GetFromJsonAsync<ShellyResponse>($"http://{ip}/shelly");
|
ShellyResponse? shellyResponse = null;
|
||||||
|
|
||||||
if (shellyResponse is null || shellyResponse.Type != "SHPLG-S")
|
try
|
||||||
{
|
{
|
||||||
return Result.Fail("Device is not reachable or not a \"SHPLG-S\"!");
|
shellyResponse = await httpClient.GetFromJsonAsync<ShellyResponse>($"http://{ip}/shelly");
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError("HTTP request failed! {message}", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
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 _))
|
string mac = shellyResponse.Mac;
|
||||||
{
|
|
||||||
return Result.Fail("Invalid mac address!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Device device = new Device(mac, name ?? mac, ip, user, room);
|
if (!PhysicalAddress.TryParse(mac, out _))
|
||||||
|
{
|
||||||
|
return Result.Fail("Invalid mac address!");
|
||||||
|
}
|
||||||
|
|
||||||
deviceManagmentDatabaseContext.Add(device);
|
Device device = new Device(mac, name ?? mac, ip, user, room);
|
||||||
Result saveDatabaseChangesResult = await Result.Try(Task () => deviceManagmentDatabaseContext.SaveChangesAsync());
|
|
||||||
|
|
||||||
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<Result> UnregisterDevice(string macAdress)
|
return Result.Merge(saveDatabaseChangesResult, trackDeviceResult).ToResult(device);
|
||||||
{
|
}
|
||||||
using IServiceScope scope = serviceScopeFactory.CreateScope();
|
|
||||||
DeviceManagmentDatabaseContext deviceManagmentDatabaseContext = scope.ServiceProvider.GetRequiredService<DeviceManagmentDatabaseContext>();
|
public async Task<Result> UnregisterDevice(string macAdress)
|
||||||
|
{
|
||||||
|
using IServiceScope scope = serviceScopeFactory.CreateScope();
|
||||||
|
DeviceManagmentDatabaseContext deviceManagmentDatabaseContext = scope.ServiceProvider.GetRequiredService<DeviceManagmentDatabaseContext>();
|
||||||
|
|
||||||
Result<Device> getDeviceResult = GetDevice(macAdress);
|
Result<Device> getDeviceResult = GetDevice(macAdress);
|
||||||
|
|
||||||
if (getDeviceResult.IsFailed)
|
if (getDeviceResult.IsFailed)
|
||||||
{
|
{
|
||||||
return getDeviceResult.ToResult();
|
return getDeviceResult.ToResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result untrackDeviceResult = deviceStatusService.UntrackDevice(macAdress);
|
Result untrackDeviceResult = deviceStatusService.UntrackDevice(macAdress);
|
||||||
|
|
||||||
if (untrackDeviceResult.IsFailed)
|
if (untrackDeviceResult.IsFailed)
|
||||||
{
|
{
|
||||||
return untrackDeviceResult;
|
return untrackDeviceResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceManagmentDatabaseContext.Remove(getDeviceResult.Value);
|
_ = deviceManagmentDatabaseContext.Remove(getDeviceResult.Value);
|
||||||
|
|
||||||
return await Result.Try(Task () => deviceManagmentDatabaseContext.SaveChangesAsync());
|
return await Result.Try(Task () => deviceManagmentDatabaseContext.SaveChangesAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Result> UpdateDevice(Device device)
|
public async Task<Result> UpdateDevice(Device device)
|
||||||
{
|
{
|
||||||
Result result = deviceStatusService.UpdateDeviceStatus(device);
|
Result result = deviceStatusService.UpdateDeviceStatus(device);
|
||||||
|
|
||||||
if (result.IsFailed)
|
if (result.IsFailed)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceManagmentDatabaseContext.Update(device);
|
_ = deviceManagmentDatabaseContext.Update(device);
|
||||||
|
|
||||||
return await Result.Try(Task () => deviceManagmentDatabaseContext.SaveChangesAsync());
|
return await Result.Try(Task () => deviceManagmentDatabaseContext.SaveChangesAsync());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,25 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using FluentResults;
|
|
||||||
using Tmds.MDns;
|
using Tmds.MDns;
|
||||||
|
|
||||||
namespace Elektrifikatsiya.Utilities;
|
namespace Elektrifikatsiya.Utilities;
|
||||||
|
|
||||||
public static class MdnsDiscovery
|
public static class MdnsDiscovery
|
||||||
{
|
{
|
||||||
public static event Action<IPAddress> OnDeviceFound;
|
public static event Action<IPAddress> OnDeviceFound = null!;
|
||||||
|
|
||||||
static ServiceBrowser serviceBrowser = new ServiceBrowser();
|
private static readonly ServiceBrowser serviceBrowser = new ServiceBrowser();
|
||||||
|
|
||||||
static MdnsDiscovery()
|
static MdnsDiscovery()
|
||||||
{
|
{
|
||||||
serviceBrowser.StartBrowse("_http._tcp");
|
serviceBrowser.StartBrowse("_http._tcp");
|
||||||
serviceBrowser.ServiceAdded += (_, eventArgs) => OnDeviceFound?.Invoke(eventArgs.Announcement.Addresses.First());
|
serviceBrowser.ServiceAdded += (_, eventArgs) => OnDeviceFound?.Invoke(eventArgs.Announcement.Addresses.First());
|
||||||
serviceBrowser.ServiceChanged += (_, 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());
|
serviceBrowser.ServiceRemoved += (_, eventArgs) => OnDeviceFound?.Invoke(eventArgs.Announcement.Addresses.First());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<IPAddress> GetChachedDevices()
|
||||||
|
{
|
||||||
|
return serviceBrowser.Services.Select(s => s.Addresses.First());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user