added automatic tags setters for vrm
This commit is contained in:
parent
92f0e400e1
commit
149f89f89f
|
@ -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;
|
||||||
|
@ -167,22 +168,55 @@ 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");
|
||||||
|
|
||||||
|
var split = pathToBattery.Split('"');
|
||||||
|
var split2 = pathToBattery.Split(' ');
|
||||||
|
|
||||||
if (pathToBattery.Split('"')[1] == "Failed" || pathToBattery.Split(' ')[0] == "Error") return "Update failed";
|
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")
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -54,9 +57,10 @@ public static partial class Db
|
||||||
|
|
||||||
Connection.RunInTransaction(() => { Connection.CreateTable<Installation>(); });
|
Connection.RunInTransaction(() => { Connection.CreateTable<Installation>(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -7,20 +7,20 @@ public static class Program
|
||||||
{
|
{
|
||||||
public static async Task Main(String[] args)
|
public static async Task Main(String[] args)
|
||||||
{
|
{
|
||||||
var updateTask =Db.UpdateDetailsAndInstallations();
|
var updateTask = Db.UpdateDetailsAndInstallations();
|
||||||
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.
|
@ -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
|
||||||
|
|
|
@ -49,6 +49,20 @@ public class VrmAccount : IDisposable
|
||||||
.Select(r => new Installation(this, r!))
|
.Select(r => new Installation(this, r!))
|
||||||
.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()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue