༼ つ ◕_◕ ༽つ Some backend stuff mostly for Registration 🪵🪵

This commit is contained in:
Stefan
2023-03-01 11:16:06 +01:00
parent ba6fdb3fde
commit 22c4fe1a26
9 changed files with 189 additions and 14 deletions
@@ -18,12 +18,21 @@
</PropertyGroup>
<ItemGroup>
<Compile Remove="Middleware\**" />
<Compile Remove="Model\**" />
<Content Remove="Middleware\**" />
<Content Remove="Model\**" />
<EmbeddedResource Remove="Middleware\**" />
<EmbeddedResource Remove="Model\**" />
<None Remove="Middleware\**" />
<None Remove="Model\**" />
</ItemGroup>
<ItemGroup>
<None Remove="Models\NewFile.txt" />
<None Remove="Models\ShellyResponse" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Blazorise" Version="1.2.0" />
<PackageReference Include="Blazorise.Charts" Version="1.2.0" />
@@ -35,10 +44,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Middleware\" />
<PackageReference Include="Tmds.MDns" Version="0.7.1" />
</ItemGroup>
</Project>
@@ -0,0 +1,73 @@
using System.Text.Json.Serialization;
namespace Elektrifikatsiya.Models;
public enum Status
{
Success,
Error
}
public enum ResultType
{
Matrix,
Vector,
Scalar,
String
}
public class PrometheusQueryResult
{
public Status Status { get; set; }
public string? ErrorType { get; set; }
public string? Error { get; set; }
public List<string>? Warnings { get; set; }
public PrometheusQueryResult(Status status, string? errorType, string? error, List<string>? warnings)
{
Status = status;
ErrorType = errorType;
Error = error;
Warnings = warnings;
}
}
internal class PrometheusDataWrapper
{
public ResultType ResultType { get; set; }
public List<PrometheusData> Result { get; set; }
public PrometheusDataWrapper(ResultType resultType, List<PrometheusData> result)
{
ResultType = resultType;
Result = result;
}
}
internal class PrometheusDataMetric
{
[JsonPropertyName("__name__")] public string Name { get; set; }
public string Job { get; set; }
public string Instance { get; set; }
public PrometheusDataMetric(string name, string job, string instance)
{
Name = name;
Job = job;
Instance = instance;
}
}
internal class PrometheusData
{
public PrometheusDataMetric Metric { get; set; }
public object Value { get; set; }
public PrometheusData(PrometheusDataMetric metric, object value)
{
Metric = metric;
Value = value;
}
}
@@ -0,0 +1,13 @@
namespace Elektrifikatsiya.Models;
public class ShellyResponse
{
public string Type { get; set; }
public string Mac { get; set; }
public ShellyResponse(string type, string mac)
{
Type = type;
Mac = mac;
}
}
@@ -10,7 +10,7 @@ public interface IDeviceManagmentService
{
public Task<Result<Device>> Register(IPAddress ip, User user, string? name = null, string room = "default");
public Task<Result> UnRegister(string macAdress);
public Task<Result> Unregister(string macAdress);
public Result<Device> GetDevice(string macAdress);
@@ -13,4 +13,6 @@ public interface IDeviceStatusService
public Result UpdateDeviceStatus(Device device);
public Result TrackDevice(Device device);
public Result UntrackDevice(string macAddress);
}
@@ -4,6 +4,7 @@ using Elektrifikatsiya.Models;
using FluentResults;
using System.Net;
using System.Net.NetworkInformation;
namespace Elektrifikatsiya.Services.Implementations;
@@ -11,11 +12,13 @@ public class DeviceManagmentService : IDeviceManagmentService
{
private readonly DeviceManagmentDatabaseContext deviceManagmentDatabaseContext;
private readonly IDeviceStatusService deviceStatusService;
private readonly HttpClient httpClient;
public DeviceManagmentService(DeviceManagmentDatabaseContext deviceManagmentDatabaseContext, IDeviceStatusService deviceStatusService)
public DeviceManagmentService(DeviceManagmentDatabaseContext deviceManagmentDatabaseContext, IDeviceStatusService deviceStatusService, HttpClient httpClient)
{
this.deviceManagmentDatabaseContext = deviceManagmentDatabaseContext;
this.deviceStatusService = deviceStatusService;
this.httpClient = httpClient;
}
public Result<Device> GetDevice(string macAdress)
@@ -73,13 +76,50 @@ public class DeviceManagmentService : IDeviceManagmentService
return getDevicesResult.Value.Where(d => d.User.Id == userId).ToList();
}
public Task<Result<Device>> Register(IPAddress ip, User user, string? name = null, string room = "default")
public async Task<Result<Device>> Register(IPAddress ip, User user, string? name = null, string room = "default")
{
throw new NotImplementedException();
ShellyResponse? shellyResponse = await httpClient.GetFromJsonAsync<ShellyResponse>($"{ip}/shelly");
if(shellyResponse is null || shellyResponse.Type != "SHPLG-S")
{
return Result.Fail("Device is not a \"SHPLG-S\" or not reachable!");
}
string mac = shellyResponse.Mac;
if(PhysicalAddress.TryParse(mac, out _))
{
return Result.Fail("Invalid mac address!");
}
Device device = new Device(mac, name ?? mac, ip, user, room);
deviceManagmentDatabaseContext.Add(device);
Result saveDatabaseChangesResult = await Result.Try(async Task () => await deviceManagmentDatabaseContext.SaveChangesAsync());
Result trackDeviceResult = deviceStatusService.TrackDevice(device);
return Result.Merge(saveDatabaseChangesResult, trackDeviceResult).ToResult(device);
}
public Task<Result> UnRegister(string macAdress)
public async Task<Result> Unregister(string macAdress)
{
throw new NotImplementedException();
Result<Device> getDeviceResult = GetDevice(macAdress);
if (getDeviceResult.IsFailed)
{
return getDeviceResult.ToResult();
}
Result untrackDeviceResult = deviceStatusService.UntrackDevice(macAdress);
if (untrackDeviceResult.IsFailed)
{
return untrackDeviceResult;
}
deviceManagmentDatabaseContext.Remove(getDeviceResult.Value);
return await Result.Try(async Task () => await deviceManagmentDatabaseContext.SaveChangesAsync());
}
}
@@ -45,4 +45,9 @@ public class DeviceStatusService : IDeviceStatusService
return Result.Ok();
}
public Result UntrackDevice(string macAddress)
{
return devices.Remove(macAddress) ? Result.Ok() : Result.Fail("Device is not tracked!");
}
}
@@ -1,7 +1,8 @@
using Elektrifikatsiya.Database;
using Elektrifikatsiya.Models;
using FluentResults;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
namespace Elektrifikatsiya.Services.Implementations;
@@ -28,14 +29,24 @@ public class UpdateService : IHostedService, IDisposable
_ = deviceStatusService.TrackDevice(device);
}
timer = new Timer(Update, null, TimeSpan.Zero, TimeSpan.FromSeconds(15));
timer = new Timer(async (_) => await Update(), null, TimeSpan.Zero, TimeSpan.FromSeconds(15));
logger.LogInformation("Update service started.");
}
private void Update(object? state)
private async Task Update()
{
//TODO: Update all devices.
Result<List<Device>> getDeviceStatusResult = deviceStatusService.GetDevices();
if (getDeviceStatusResult.IsFailed)
{
logger.LogError("Updating devices failed!");
}
foreach(Device device in getDeviceStatusResult.Value)
{
//TODO: Some update magic
}
}
public Task StopAsync(CancellationToken cancellationToken)
@@ -0,0 +1,25 @@
using System.Net;
using System.Net.Sockets;
using System.Text.Encodings.Web;
using System.Text.Json;
using Elektrifikatsiya.Models;
using FluentResults;
namespace Elektrifikatsiya.Utilities;
public class PrometheusQuery
{
private string connectionString;
private readonly HttpClient client = new();
public PrometheusQuery(string connectionString)
{
this.connectionString = connectionString;
client.BaseAddress = new Uri(connectionString);
}
public Task<PrometheusQueryResult?> Query(string query)
{
return client.GetFromJsonAsync<PrometheusQueryResult>($"/v1/query?{UrlEncoder.Create().Encode(query)}");
}
}