Fixed a bug that stopped the updating of installations
This commit is contained in:
parent
5eb373b78e
commit
c969b72a82
|
@ -1,16 +1,15 @@
|
|||
using System.Data.Common;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Web;
|
||||
using CliWrap;
|
||||
using CliWrap.Buffered;
|
||||
using HandlebarsDotNet;
|
||||
using InnovEnergy.App.RemoteSupportConsole;
|
||||
using InnovEnergy.App.VrmGrabber.Database;
|
||||
using InnovEnergy.Lib.Utils;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using FILE=System.IO.File;
|
||||
using VrmInstallation = InnovEnergy.Lib.Victron.VictronVRM.Installation;
|
||||
|
||||
namespace InnovEnergy.App.VrmGrabber;
|
||||
|
||||
public record Install(
|
||||
public record InstallationToHtmlInterface(
|
||||
String Name,
|
||||
String Ip,
|
||||
Int64 Vrm,
|
||||
|
@ -26,12 +25,17 @@ public record Install(
|
|||
[Controller]
|
||||
public class Controller : ControllerBase
|
||||
{
|
||||
|
||||
//Todo automatically grab newest version?
|
||||
private const String FirmwareVersion = "VERSION";
|
||||
|
||||
|
||||
[HttpGet]
|
||||
[Route("/")]
|
||||
[Produces("text/html")]
|
||||
public ActionResult Index()
|
||||
{
|
||||
String source = @"<head>
|
||||
const String source = @"<head>
|
||||
<style>
|
||||
tbody {
|
||||
background-color: #e4f0f5;
|
||||
|
@ -84,8 +88,9 @@ public class Controller : ControllerBase
|
|||
</table>
|
||||
<div id='managerTable'>";
|
||||
|
||||
String partialSource =
|
||||
@"<tr><td>{{Name}}</td>
|
||||
|
||||
|
||||
const String partialSource = @"<tr><td>{{Name}}</td>
|
||||
<td><a target='_blank' href=http://{{Ip}}>{{online}} {{Ip}}</a></td>
|
||||
<td><a target='_blank' href=https://vrm.victronenergy.com/installation/{{Vrm}}/dashboard>VRM</a></td>
|
||||
<td><a target='_blank' href='https://salidomo.innovenergy.ch/d/ENkNRQXmk/installation?refresh=5s&orgId=1&var-Installation={{EscapedName}}&kiosk=tv'>Grafana</a></td>
|
||||
|
@ -94,11 +99,11 @@ public class Controller : ControllerBase
|
|||
<td>{{Serial}}</td>
|
||||
<td>{{NumBatteries}}</td>
|
||||
<td>{{BatteryVersion}}</td>
|
||||
<td><a target='_blank' href=http://{{serverIp}}/UpdateBatteryFirmware/{{Ip}}>⬆️{{firmwareVersion}}</a></td>
|
||||
</tr>";
|
||||
|
||||
|
||||
var instList = Db.Installations.ToList();
|
||||
if (instList.Count == 0) return new ContentResult
|
||||
var installationsInDb = Db.Installations.ToList();
|
||||
if (installationsInDb.Count == 0) return new ContentResult
|
||||
{
|
||||
ContentType = "text/html",
|
||||
Content = "<p>Please wait page is still loading</p>"
|
||||
|
@ -106,7 +111,7 @@ public class Controller : ControllerBase
|
|||
|
||||
Handlebars.RegisterTemplate("installations", partialSource);
|
||||
var template = Handlebars.Compile(source);
|
||||
var insts = instList.Select(i => new Install(
|
||||
var installsForHtml = installationsInDb.Select(i => new InstallationToHtmlInterface(
|
||||
i.Name,
|
||||
i.Ip,
|
||||
i.Vrm,
|
||||
|
@ -120,7 +125,9 @@ public class Controller : ControllerBase
|
|||
|
||||
var data = new
|
||||
{
|
||||
inst = insts
|
||||
inst = installsForHtml,
|
||||
serverIp = "10.2.0.1",
|
||||
firmwareVersion = FirmwareVersion
|
||||
};
|
||||
|
||||
var result = template(data);
|
||||
|
@ -132,6 +139,32 @@ public class Controller : ControllerBase
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
[HttpGet(nameof(UpdateBatteryFirmware))]
|
||||
public async Task<ActionResult> UpdateBatteryFirmware(String installationIp, Int64 numOfBatteries)
|
||||
{
|
||||
//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");
|
||||
|
||||
if (pathToBattery == "Failed") return new BadRequestResult();
|
||||
|
||||
SendNewBatteryFirmware(installationIp);
|
||||
|
||||
for (var batteryId = 0; batteryId < numOfBatteries; batteryId++)
|
||||
{
|
||||
var updateCommand = await Db.ExecuteBufferedAsyncCommandOnIp(installationIp, $"/opt/innovenergy/scripts/upload-bms-firmware {pathToBattery} {batteryId} /opt/innovenergy/bms-firmware/{FirmwareVersion}.bin");
|
||||
if (updateCommand == "Failed") return new BadRequestResult();
|
||||
}
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
private void SendNewBatteryFirmware(String installationIp)
|
||||
{
|
||||
Cli.Wrap("scp")
|
||||
.WithArguments($@"{FirmwareVersion}.bin")
|
||||
.AppendArgument($@"root@{installationIp}:/opt/innovenergy/bms-firmware/{FirmwareVersion}.bin")
|
||||
.WithValidation(CommandResultValidation.None).ExecuteBufferedAsync();
|
||||
}
|
||||
// [HttpGet(nameof(GetInstallation))]
|
||||
// [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
||||
// public Object GetInstallation(UInt64 serialNumber)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Reactive.Concurrency;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Threading.Tasks;
|
||||
using System.Web;
|
||||
using CliWrap;
|
||||
using CliWrap.Buffered;
|
||||
|
@ -33,7 +35,7 @@ public static partial class Db
|
|||
public static Dictionary<Installation, InstallationDetails> InstallationsAndDetails;
|
||||
|
||||
|
||||
internal const String DbPath = "./db.sqlite";
|
||||
private const String DbPath = "./db.sqlite";
|
||||
|
||||
private static SQLiteConnection Connection { get; } = new SQLiteConnection(DbPath);
|
||||
|
||||
|
@ -54,10 +56,10 @@ public static partial class Db
|
|||
|
||||
public static async Task UpdateDetailsAndInstallations()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
do {
|
||||
await UpdateInstallationsAndDetailsFromVrm(0);
|
||||
}
|
||||
while (true) ;
|
||||
}
|
||||
|
||||
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
||||
|
@ -70,7 +72,7 @@ public static partial class Db
|
|||
var installations = await user.GetInstallations();
|
||||
|
||||
// var returnDictionary = new Dictionary<VrmInstallation, InstallationDetails>();
|
||||
foreach (var installation in installations.Take(70)) //TODO REMOVE TAKE
|
||||
foreach (var installation in installations) //TODO REMOVE TAKE
|
||||
{
|
||||
Console.WriteLine(installation.Name);
|
||||
var details = await GetInstallationDetails(installation);
|
||||
|
@ -85,8 +87,8 @@ public static partial class Db
|
|||
ip[1],
|
||||
details.Details.Last().Json["timestamp"].ToString(),
|
||||
Serialize(details.Details),
|
||||
await NumberOfBatteries(ip[0]),
|
||||
await BatteryFirmwareVersion(ip[0]));
|
||||
await NumberOfBatteries(ip[0], ip[1]),
|
||||
await BatteryFirmwareVersion(ip[0], ip[1]));
|
||||
|
||||
if (GetInstallationByIdentifier(installation.Identifier) == null)
|
||||
{
|
||||
|
@ -99,34 +101,41 @@ public static partial class Db
|
|||
}
|
||||
}
|
||||
|
||||
private static async Task<String> BatteryFirmwareVersion(String? ip)
|
||||
private static async Task<String> BatteryFirmwareVersion(String? ip, String? online)
|
||||
{
|
||||
if (ip is null or "Unknown") return "Unknown";
|
||||
if (ip is null or "Unknown" || online == "❌") return "Unknown";
|
||||
var pathToBattery = await ExecuteBufferedAsyncCommandOnIp(ip, "dbus-send --system --dest=com.victronenergy.system --type=method_call --print-reply /ServiceMapping/com_victronenergy_battery_1 com.victronenergy.BusItem.GetText");
|
||||
|
||||
if (pathToBattery.StartsWith("Error")) return "Unknown";
|
||||
|
||||
|
||||
var command = $"dbus-send --system --dest={pathToBattery} --type=method_call --print-reply /FirmwareVersion com.victronenergy.BusItem.GetText";
|
||||
return await ExecuteBufferedAsyncCommandOnIp(ip, command); //todo fill me
|
||||
return await ExecuteBufferedAsyncCommandOnIp(ip, command);
|
||||
}
|
||||
|
||||
private static async Task<Int64> NumberOfBatteries(String? ip)
|
||||
private static async Task<Int64> NumberOfBatteries(String? ip, String? online)
|
||||
{
|
||||
if (ip is null or "Unknown") return 0;
|
||||
if (ip is null or "Unknown" || online == "❌") return 0;
|
||||
var pathToBattery = await ExecuteBufferedAsyncCommandOnIp(ip, "dbus-send --system --dest=com.victronenergy.system --type=method_call --print-reply /ServiceMapping/com_victronenergy_battery_1 com.victronenergy.BusItem.GetText");
|
||||
|
||||
if (pathToBattery.StartsWith("Error")) return 0;
|
||||
|
||||
var cmd = await ExecuteBufferedAsyncCommandOnIp(ip,$"dbus-send --system --dest={pathToBattery} --type=method_call --print-reply /NbOfBatteries com.victronenergy.BusItem.GetText" );
|
||||
|
||||
return cmd == "Unknown" ? 0 : Int64.Parse(cmd); //No Batteries can be found
|
||||
return cmd == "Failed" ? 0 : Int64.Parse(cmd); //No Batteries can be found
|
||||
}
|
||||
|
||||
|
||||
private static async Task<String> ExecuteBufferedAsyncCommandOnIp(String? ip, String command)
|
||||
public static async Task<String> ExecuteBufferedAsyncCommandOnIp(String? ip, String command)
|
||||
{
|
||||
if (ip is null or "Unknown") return "Unknown";
|
||||
if (ip is null or "Unknown") return "Failed";
|
||||
|
||||
var cmd = await Cli.Wrap("ssh")
|
||||
.WithArguments($@"root@{ip}")
|
||||
.AppendArgument("-o StrictHostKeyChecking=accept-new")
|
||||
.AppendArgument(command)
|
||||
.WithValidation(CommandResultValidation.None).ExecuteBufferedAsync();
|
||||
return cmd.StandardOutput.Split('"')[1];
|
||||
return cmd.ExitCode == 0 ? cmd.StandardOutput.Split('"')[1] : cmd.StandardError;
|
||||
}
|
||||
|
||||
private static String?[] Ip(InstallationDetails details)
|
||||
|
|
Loading…
Reference in New Issue