diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Elektrifikatsiya.csproj b/src/Elektrifikatsiya/Elektrifikatsiya/Elektrifikatsiya.csproj
index 9d16e3c..4dca5d7 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Elektrifikatsiya.csproj
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Elektrifikatsiya.csproj
@@ -18,12 +18,21 @@
+
+
+
+
+
+
+
+
+
@@ -35,10 +44,7 @@
-
-
-
-
+
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Models/PrometheusQueryResult.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Models/PrometheusQueryResult.cs
new file mode 100644
index 0000000..9732592
--- /dev/null
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Models/PrometheusQueryResult.cs
@@ -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? Warnings { get; set; }
+
+ public PrometheusQueryResult(Status status, string? errorType, string? error, List? warnings)
+ {
+ Status = status;
+ ErrorType = errorType;
+ Error = error;
+ Warnings = warnings;
+ }
+}
+
+internal class PrometheusDataWrapper
+{
+ public ResultType ResultType { get; set; }
+ public List Result { get; set; }
+
+ public PrometheusDataWrapper(ResultType resultType, List 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;
+ }
+}
\ No newline at end of file
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Models/ShellyResponse.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Models/ShellyResponse.cs
new file mode 100644
index 0000000..bf6cd03
--- /dev/null
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Models/ShellyResponse.cs
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceManagmentService.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceManagmentService.cs
index 1da0c91..bda0e67 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceManagmentService.cs
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceManagmentService.cs
@@ -10,7 +10,7 @@ public interface IDeviceManagmentService
{
public Task> Register(IPAddress ip, User user, string? name = null, string room = "default");
- public Task UnRegister(string macAdress);
+ public Task Unregister(string macAdress);
public Result GetDevice(string macAdress);
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceStatusService.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceStatusService.cs
index ef7fab3..61e1cc1 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceStatusService.cs
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/IDeviceStatusService.cs
@@ -13,4 +13,6 @@ public interface IDeviceStatusService
public Result UpdateDeviceStatus(Device device);
public Result TrackDevice(Device device);
+
+ public Result UntrackDevice(string macAddress);
}
\ 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 75e9a65..b659cf1 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceManagmentService.cs
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceManagmentService.cs
@@ -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 GetDevice(string macAdress)
@@ -73,13 +76,50 @@ public class DeviceManagmentService : IDeviceManagmentService
return getDevicesResult.Value.Where(d => d.User.Id == userId).ToList();
}
- public Task> Register(IPAddress ip, User user, string? name = null, string room = "default")
+ public async Task> Register(IPAddress ip, User user, string? name = null, string room = "default")
{
- throw new NotImplementedException();
+ ShellyResponse? shellyResponse = await httpClient.GetFromJsonAsync($"{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 UnRegister(string macAdress)
+ public async Task Unregister(string macAdress)
{
- throw new NotImplementedException();
+ Result 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());
}
}
\ 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 8b4263e..3574cec 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceStatusService.cs
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/DeviceStatusService.cs
@@ -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!");
+ }
}
\ No newline at end of file
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/UpdateService.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/UpdateService.cs
index 6271a23..980826d 100644
--- a/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/UpdateService.cs
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Services/Implementations/UpdateService.cs
@@ -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> 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)
diff --git a/src/Elektrifikatsiya/Elektrifikatsiya/Utilities/PrometheusQuery.cs b/src/Elektrifikatsiya/Elektrifikatsiya/Utilities/PrometheusQuery.cs
new file mode 100644
index 0000000..a635857
--- /dev/null
+++ b/src/Elektrifikatsiya/Elektrifikatsiya/Utilities/PrometheusQuery.cs
@@ -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 Query(string query)
+ {
+ return client.GetFromJsonAsync($"/v1/query?{UrlEncoder.Create().Encode(query)}");
+ }
+}
\ No newline at end of file