added automatic tags setters for vrm

This commit is contained in:
Kim 2023-06-01 15:29:39 +02:00
parent 92f0e400e1
commit 149f89f89f
6 changed files with 92 additions and 24 deletions

View File

@ -2,6 +2,7 @@ using CliWrap;
using CliWrap.Buffered; using CliWrap.Buffered;
using HandlebarsDotNet; using HandlebarsDotNet;
using InnovEnergy.App.VrmGrabber.Database; using InnovEnergy.App.VrmGrabber.Database;
using InnovEnergy.App.VrmGrabber.DataTypes;
using InnovEnergy.Lib.Utils; using InnovEnergy.Lib.Utils;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using FILE=System.IO.File; using FILE=System.IO.File;
@ -168,21 +169,54 @@ th { /* header cell */
//We need the DeviceName of the battery (ttyUSB?) //We need the DeviceName of the battery (ttyUSB?)
var pathToBattery = await Db.ExecuteBufferedAsyncCommandOnIp(installationIp, "dbus-send --system --dest=com.victronenergy.system --type=method_call --print-reply /ServiceMapping/com_victronenergy_battery_1 com.victronenergy.BusItem.GetText"); var pathToBattery = await Db.ExecuteBufferedAsyncCommandOnIp(installationIp, "dbus-send --system --dest=com.victronenergy.system --type=method_call --print-reply /ServiceMapping/com_victronenergy_battery_1 com.victronenergy.BusItem.GetText");
if (pathToBattery.Split('"')[1] == "Failed" || pathToBattery.Split(' ')[0] == "Error") return "Update failed"; var split = pathToBattery.Split('"');
var split2 = pathToBattery.Split(' ');
if (split.Length < 2 || split2.Length < 1)
{
Console.WriteLine(pathToBattery + " Split failed ");
return "Update failed";
}
if (split[1] == "Failed" || split2[0] == "Error") return "Update failed";
await UpdateVrmTagsToNewFirmware(installationIp);
SendNewBatteryFirmware(installationIp); SendNewBatteryFirmware(installationIp);
for (var batteryId = 2; batteryId <= Int64.Parse(numberOfBatteries) + 1; batteryId++) for (var batteryId = 2; batteryId <= Int64.Parse(numberOfBatteries) + 1; batteryId++)
{ {
var batteryTtyName = pathToBattery.Split('"')[1].Split(".").Last(); var batteryTtyName = split[1].Split(".").Last();
var localCommand = $"/opt/innovenergy/scripts/upload-bms-firmware {batteryTtyName} {batteryId} /opt/innovenergy/bms-firmware/{FirmwareVersion}.bin"; var localCommand = $"/opt/innovenergy/scripts/upload-bms-firmware {batteryTtyName} {batteryId} /opt/innovenergy/bms-firmware/{FirmwareVersion}.bin";
var remoteUpdateCommandResult = await Db.ExecuteBufferedAsyncCommandOnIp(installationIp, localCommand); #pragma warning disable CS4014
Db.ExecuteBufferedAsyncCommandOnIp(installationIp, localCommand);
#pragma warning restore CS4014
// Console.WriteLine(remoteUpdateCommandResult); // Console.WriteLine(remoteUpdateCommandResult);
} }
return "Battery update is successfully initiated! You can close this page now."; return "Battery update is successfully initiated! You can close this page now.";
} }
private static async Task UpdateVrmTagsToNewFirmware(String installationIp)
{
var vrmInstallation = await FindVrmInstallationByIp(installationIp);
var tags = await vrmInstallation.GetTags();
async void RemoveTag(String t) => await vrmInstallation.RemoveTags(t);
tags.Where(tag => tag.StartsWith("FM-"))
.Do(RemoveTag);
await vrmInstallation.AddTags("FM-" + FirmwareVersion);
}
private static async Task<VrmInstallation> FindVrmInstallationByIp(String installationIp)
{
var installationId = Db.Installations.Where(i => i.Ip == installationIp).Select(i => i.Vrm).First();
var vrmAccount = await Db.GetVrmAccount();
return await vrmAccount.GetInstallation(installationId!);
}
private static void SendNewBatteryFirmware(String installationIp) private static void SendNewBatteryFirmware(String installationIp)
{ {
Cli.Wrap("scp") Cli.Wrap("scp")

View File

@ -1,24 +1,27 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Reactive.Concurrency; using System.Runtime.InteropServices;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
using System.Web; using System.Web;
using CliWrap; using CliWrap;
using CliWrap.Buffered; using CliWrap.Buffered;
using InnovEnergy.App.RemoteSupportConsole; using InnovEnergy.App.RemoteSupportConsole;
using InnovEnergy.Lib.Utils; using InnovEnergy.Lib.Utils;
using InnovEnergy.Lib.Victron.VictronVRM; using InnovEnergy.Lib.Victron.VictronVRM;
using Microsoft.AspNetCore.Mvc.TagHelpers.Cache;
using SQLite; using SQLite;
using static System.Text.Json.JsonSerializer; using static System.Text.Json.JsonSerializer;
using static InnovEnergy.App.VrmGrabber.Database.Systemd;
using Installation = InnovEnergy.App.VrmGrabber.DataTypes.Installation; using Installation = InnovEnergy.App.VrmGrabber.DataTypes.Installation;
using VrmInstallation = InnovEnergy.Lib.Victron.VictronVRM.Installation; using VrmInstallation = InnovEnergy.Lib.Victron.VictronVRM.Installation;
using FILE=System.IO.File; using FILE=System.IO.File;
namespace InnovEnergy.App.VrmGrabber.Database; namespace InnovEnergy.App.VrmGrabber.Database;
public static class Systemd
{
[DllImport("libsystemd.so.0", CharSet = CharSet.Unicode)]
public static extern Int32 sd_notify(Int32 unsetEnvironment, String state);
}
public class InstallationDetails public class InstallationDetails
{ {
public InstallationDetails(String? ip, IReadOnlyList<Detail> details) public InstallationDetails(String? ip, IReadOnlyList<Detail> details)
@ -57,6 +60,7 @@ public static partial class Db
public static async Task UpdateDetailsAndInstallations() public static async Task UpdateDetailsAndInstallations()
{ {
sd_notify(0, "READY=1");
do { do {
await UpdateInstallationsAndDetailsFromVrm(0); await UpdateInstallationsAndDetailsFromVrm(0);
} }
@ -66,10 +70,8 @@ public static partial class Db
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")] [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
private static async Task UpdateInstallationsAndDetailsFromVrm(Int32 _) private static async Task UpdateInstallationsAndDetailsFromVrm(Int32 _)
{ {
var fileContent = await File.ReadAllTextAsync("./token.json"); sd_notify(0, "WATCHDOG=1");
var user = await GetVrmAccount();
var acc = Deserialize<AccToken>(fileContent);
var user = VrmAccount.Token(acc!.idUser, acc.token);
var installations = await user.GetInstallations(); var installations = await user.GetInstallations();
// var returnDictionary = new Dictionary<VrmInstallation, InstallationDetails>(); // var returnDictionary = new Dictionary<VrmInstallation, InstallationDetails>();
@ -105,6 +107,14 @@ public static partial class Db
} }
} }
public static async Task<VrmAccount> GetVrmAccount()
{
var fileContent = await File.ReadAllTextAsync("./token.json");
var acc = Deserialize<AccToken>(fileContent);
var user = VrmAccount.Token(acc!.idUser, acc.token);
return user;
}
private static async Task<String> BatteryFirmwareVersion(String? ip, String? online) private static async Task<String> BatteryFirmwareVersion(String? ip, String? online)
{ {
if (ip is null or "Unknown" || online == "❌") return "Unknown"; if (ip is null or "Unknown" || online == "❌") return "Unknown";
@ -138,7 +148,7 @@ public static partial class Db
var cmd = await Cli.Wrap("ssh") var cmd = await Cli.Wrap("ssh")
.WithArguments($@"root@{ip}") .WithArguments($@"root@{ip}")
.AppendArgument("-o StrictHostKeyChecking=accept-new") .AppendArgument("-o StrictHostKeyChecking=no")
.AppendArgument(command) .AppendArgument(command)
.WithValidation(CommandResultValidation.None).ExecuteBufferedAsync(); .WithValidation(CommandResultValidation.None).ExecuteBufferedAsync();
return cmd.ExitCode == 0 ? cmd.StandardOutput : cmd.StandardError; return cmd.ExitCode == 0 ? cmd.StandardOutput : cmd.StandardError;

View File

@ -11,16 +11,16 @@ public static class Program
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(); builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c => // builder.Services.AddSwaggerGen(c =>
{ // {
c.UseAllOfToExtendReferenceSchemas(); // c.UseAllOfToExtendReferenceSchemas();
c.SupportNonNullableReferenceTypes(); // c.SupportNonNullableReferenceTypes();
}); // });
var app = builder.Build(); var app = builder.Build();
app.UseSwagger(); // app.UseSwagger();
app.UseSwaggerUI(); // app.UseSwaggerUI();
app.UseHttpsRedirection(); // app.UseHttpsRedirection();
app.MapControllers(); app.MapControllers();
// app.MapGet("/", () => Controller.Index()); // app.MapGet("/", () => Controller.Index());
var webTask = app.RunAsync(); var webTask = app.RunAsync();

Binary file not shown.

View File

@ -31,6 +31,16 @@ public static class Requests
.WithHeader("X-Authorization", account.Auth); .WithHeader("X-Authorization", account.Auth);
} }
public static IFlurlRequest SpecificInstallationRequest(this VrmAccount account, UInt64 installationId)
{
return ApiRoot
.AppendPathSegment("users")
.AppendPathSegment(account.UserId)
.AppendPathSegment("installations")
.AppendPathSegment(installationId)
.WithHeader("X-Authorization", account.Auth);
}
public static IFlurlRequest AllInstallationsRequest(this VrmAccount account) public static IFlurlRequest AllInstallationsRequest(this VrmAccount account)
{ {
return ApiRoot return ApiRoot

View File

@ -50,6 +50,20 @@ public class VrmAccount : IDisposable
.ToArray(vrmReply.Records.Count); .ToArray(vrmReply.Records.Count);
} }
public async Task<Installation> GetInstallation(Int64 installationId)
{
var reply = await this.SpecificInstallationRequest((UInt64)installationId).TryGetJson();
var vrmReply = new Reply(reply);
if (!vrmReply.Success)
throw new Exception(nameof(GetInstallations) + " failed");
return vrmReply
.Records
.Select(r => new Installation(this, r!))
.First();
}
public void Dispose() public void Dispose()
{ {
if (IsLoggedIn) if (IsLoggedIn)