diff --git a/csharp/App/VrmGrabber/Controller.cs b/csharp/App/VrmGrabber/Controller.cs new file mode 100644 index 000000000..e1a10b42d --- /dev/null +++ b/csharp/App/VrmGrabber/Controller.cs @@ -0,0 +1,35 @@ +using System.ComponentModel.Design; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using Flurl.Util; +using InnovEnergy.App.Backend.Database; +using InnovEnergy.Lib.Victron.VictronVRM; +using Microsoft.AspNetCore.Mvc; + +namespace InnovEnergy.App.Backend.Controllers; + +using Token = String; + +[ApiController] +[Route("api/")] +public class Controller : ControllerBase +{ + [HttpPost(nameof(GetInstallation))] + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "")] + public Object GetInstallation(String serialNumber) + { + + foreach (var detailList in Db.InstallationsAndDetails.Values.ToList().Select((Value, Index) => new {Value, Index})) + { + if (detailList.Value.All(detail => detail.FormattedValue != serialNumber)) continue; + var retour = JsonSerializer.Serialize(Db.InstallationsAndDetails.Keys.ToList()[detailList.Index]); + retour += JsonSerializer.Serialize(detailList.Value); + return retour; + } + + return new NotFoundResult(); + } +} + + + diff --git a/csharp/App/VrmGrabber/DataTypes/Installation.cs b/csharp/App/VrmGrabber/DataTypes/Installation.cs new file mode 100644 index 000000000..215125a08 --- /dev/null +++ b/csharp/App/VrmGrabber/DataTypes/Installation.cs @@ -0,0 +1,18 @@ +using InnovEnergy.Lib.Victron.VictronVRM; +using SQLite; + +namespace InnovEnergy.App.Backend.DataTypes; + + +public class Installation : TreeNode +{ + + + public Installation() + { + } + + public String Name { get; set; } + // Settings + public IReadOnlyList Notes { get; set; } +} \ No newline at end of file diff --git a/csharp/App/VrmGrabber/DataTypes/Methods/Installation.cs b/csharp/App/VrmGrabber/DataTypes/Methods/Installation.cs new file mode 100644 index 000000000..965d14203 --- /dev/null +++ b/csharp/App/VrmGrabber/DataTypes/Methods/Installation.cs @@ -0,0 +1,7 @@ +namespace InnovEnergy.App.Backend.DataTypes.Methods; + + +public static class InstallationMethods +{ +} + diff --git a/csharp/App/VrmGrabber/DataTypes/TreeNode.cs b/csharp/App/VrmGrabber/DataTypes/TreeNode.cs new file mode 100644 index 000000000..20b741853 --- /dev/null +++ b/csharp/App/VrmGrabber/DataTypes/TreeNode.cs @@ -0,0 +1,11 @@ +using SQLite; + +namespace InnovEnergy.App.Backend.DataTypes; + +public abstract partial class TreeNode +{ + [PrimaryKey, AutoIncrement] + public virtual Int64 Id { get; set; } + public String Information { get; set; } = ""; // unstructured random info + +} \ No newline at end of file diff --git a/csharp/App/VrmGrabber/Database/Create.cs b/csharp/App/VrmGrabber/Database/Create.cs new file mode 100644 index 000000000..3af2c275b --- /dev/null +++ b/csharp/App/VrmGrabber/Database/Create.cs @@ -0,0 +1,14 @@ +using InnovEnergy.App.Backend.DataTypes; + + +namespace InnovEnergy.App.Backend.Database; + + +public static partial class Db +{ + public static Boolean Create(Installation installation) + { + // SQLite wrapper is smart and *modifies* t's Id to the one generated (autoincrement) by the insertion + return Connection.Insert(installation) > 0; + } +} \ No newline at end of file diff --git a/csharp/App/VrmGrabber/Database/Db.cs b/csharp/App/VrmGrabber/Database/Db.cs new file mode 100644 index 000000000..bf3fc547a --- /dev/null +++ b/csharp/App/VrmGrabber/Database/Db.cs @@ -0,0 +1,70 @@ + +using System.Diagnostics.CodeAnalysis; +using System.Reactive.Concurrency; +using System.Reactive.Linq; +using System.Reactive.Threading.Tasks; +using System.Text.Json; +using Flurl.Util; +using InnovEnergy.Lib.Utils; +using InnovEnergy.Lib.Victron.VictronVRM; + +using SQLite; +using Installation = InnovEnergy.App.Backend.DataTypes.Installation; + + +namespace InnovEnergy.App.Backend.Database; + + +public static partial class Db +{ + public static Dictionary> InstallationsAndDetails; + internal const String DbPath = "./db.sqlite"; + + + private static SQLiteConnection Connection { get; } = new SQLiteConnection(DbPath); + public static TableQuery Installations => Connection.Table(); + public static void Init() + { + // used to force static constructor + } + + static Db() + { + // on startup create/migrate tables + + Connection.RunInTransaction(() => + { + // Connection.CreateTable(); + }); + + InstallationsAndDetails = new Dictionary>(); + + Observable.Interval(TimeSpan.FromMinutes(5)) + .ObserveOn(TaskPoolScheduler.Default) + .SubscribeOn(TaskPoolScheduler.Default) + .StartWith(0) // Do it right away (on startup) + .Select(UpdateInstallationsAndDetailsFromVrm) + .Select(t => t.ToObservable()) + .Concat() + .Subscribe(d => InstallationsAndDetails = d, exception => exception.WriteLine()); + } + + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "")] + private static async Task>> UpdateInstallationsAndDetailsFromVrm(Int64 _) + { + var content = await File.ReadAllTextAsync("./token.json"); + + var acc = JsonSerializer.Deserialize(content)!; + using var user = VrmAccount.Token(acc.idUser, acc.token); + var installations = await user.GetInstallations(); + return installations + .Do(i=>i.Name.WriteLine()) + .ToDictionary(i => i, i => i.GetDetails().Result); + } +} + +public class AccToken +{ + public UInt64 idUser; + public String token; +} \ No newline at end of file diff --git a/csharp/App/VrmGrabber/Database/Delete.cs b/csharp/App/VrmGrabber/Database/Delete.cs new file mode 100644 index 000000000..cfa4fcff6 --- /dev/null +++ b/csharp/App/VrmGrabber/Database/Delete.cs @@ -0,0 +1,15 @@ +using InnovEnergy.App.Backend.DataTypes; + + + +namespace InnovEnergy.App.Backend.Database; + + +public static partial class Db +{ + + public static Boolean Delete(Installation installation) + { + return Installations.Delete(i => i.Id == installation.Id) > 0; + } +} \ No newline at end of file diff --git a/csharp/App/VrmGrabber/Database/Read.cs b/csharp/App/VrmGrabber/Database/Read.cs new file mode 100644 index 000000000..4d084355a --- /dev/null +++ b/csharp/App/VrmGrabber/Database/Read.cs @@ -0,0 +1,16 @@ +using InnovEnergy.App.Backend.DataTypes; + + + +namespace InnovEnergy.App.Backend.Database; + + +public static partial class Db +{ + + public static Installation? GetInstallationById(Int64? id) + { + return Installations + .FirstOrDefault(i => i.Id == id); + } +} \ No newline at end of file diff --git a/csharp/App/VrmGrabber/Program.cs b/csharp/App/VrmGrabber/Program.cs new file mode 100644 index 000000000..ce467e44a --- /dev/null +++ b/csharp/App/VrmGrabber/Program.cs @@ -0,0 +1,41 @@ +using InnovEnergy.App.Backend.Database; +using Microsoft.OpenApi.Models; + +namespace InnovEnergy.App.Backend; + +public static class Program +{ + + + + public static void Main(String[] args) + { + //Db.CreateFakeRelations(); + Db.Init(); + + var builder = WebApplication.CreateBuilder(args); + + builder.Services.AddControllers(); + builder.Services.AddSwaggerGen(c => + { + c.SwaggerDoc("v1", OpenApiInfo); + c.UseAllOfToExtendReferenceSchemas(); + c.SupportNonNullableReferenceTypes(); + }); + + var app = builder.Build(); + app.UseSwagger(); + app.UseSwaggerUI(); + + app.UseHttpsRedirection(); + app.MapControllers(); + app.Run(); + } + + private static OpenApiInfo OpenApiInfo { get; } = new OpenApiInfo + { + Title = "InnovEnergy VRM Grabber", + Version = "v1" + }; + +} \ No newline at end of file diff --git a/csharp/App/VrmGrabber/VrmGrabber.csproj b/csharp/App/VrmGrabber/VrmGrabber.csproj new file mode 100644 index 000000000..e49b745c3 --- /dev/null +++ b/csharp/App/VrmGrabber/VrmGrabber.csproj @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + Never + + + + diff --git a/csharp/App/VrmGrabber/db.sqlite b/csharp/App/VrmGrabber/db.sqlite new file mode 100644 index 000000000..8294c39d2 Binary files /dev/null and b/csharp/App/VrmGrabber/db.sqlite differ diff --git a/csharp/App/VrmGrabber/token.json b/csharp/App/VrmGrabber/token.json new file mode 100644 index 000000000..9a0fbea24 --- /dev/null +++ b/csharp/App/VrmGrabber/token.json @@ -0,0 +1 @@ +{"idUser":55450,"token":"909379784fa601a52ab4756c1cc9690ecc769db4b661214f9b165eda20be9913"} \ No newline at end of file diff --git a/csharp/InnovEnergy.sln b/csharp/InnovEnergy.sln index bababc313..90de295af 100644 --- a/csharp/InnovEnergy.sln +++ b/csharp/InnovEnergy.sln @@ -73,6 +73,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Meta", "Meta", "{AED84693-C ../.gitignore = ../.gitignore EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VrmGrabber", "App\VrmGrabber\VrmGrabber.csproj", "{4F9BB20B-8030-48AB-A37B-23796459D516}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -184,6 +186,10 @@ Global {B816BB44-E97E-4E02-B80A-BEDB5B923A96}.Debug|Any CPU.Build.0 = Debug|Any CPU {B816BB44-E97E-4E02-B80A-BEDB5B923A96}.Release|Any CPU.ActiveCfg = Release|Any CPU {B816BB44-E97E-4E02-B80A-BEDB5B923A96}.Release|Any CPU.Build.0 = Release|Any CPU + {4F9BB20B-8030-48AB-A37B-23796459D516}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F9BB20B-8030-48AB-A37B-23796459D516}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F9BB20B-8030-48AB-A37B-23796459D516}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F9BB20B-8030-48AB-A37B-23796459D516}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {CF4834CB-91B7-4172-AC13-ECDA8613CD17} = {145597B4-3E30-45E6-9F72-4DD43194539A} @@ -216,5 +222,6 @@ Global {C04FB6DA-23C6-46BB-9B21-8F4FBA32FFF7} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} {4A67D79F-F0C9-4BBC-9601-D5948E6C05D3} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} {B816BB44-E97E-4E02-B80A-BEDB5B923A96} = {DDDBEFD0-5DEA-4C7C-A9F2-FDB4636CF092} + {4F9BB20B-8030-48AB-A37B-23796459D516} = {145597B4-3E30-45E6-9F72-4DD43194539A} EndGlobalSection EndGlobal diff --git a/csharp/Lib/Victron/VictronVRM/Requests.cs b/csharp/Lib/Victron/VictronVRM/Requests.cs index c97be8350..5ec6c4214 100644 --- a/csharp/Lib/Victron/VictronVRM/Requests.cs +++ b/csharp/Lib/Victron/VictronVRM/Requests.cs @@ -37,7 +37,7 @@ public static class Requests .AppendPathSegment("users") .AppendPathSegment(account.UserId) .AppendPathSegment("installations") - .WithHeader("X-Authorization", account.Auth); + .WithHeader("x-authorization", account.Auth); } public static IFlurlRequest TagsRequest(this VrmAccount account, UInt64 installationId)