added battery number and firmware version

This commit is contained in:
Kim 2023-05-18 12:38:34 +02:00
parent 24684ccb09
commit 5eb373b78e
5 changed files with 107 additions and 39 deletions

View File

@ -3,17 +3,26 @@ using System.IdentityModel.Tokens.Jwt;
using System.Web;
using HandlebarsDotNet;
using InnovEnergy.App.RemoteSupportConsole;
using static System.Text.Json.JsonSerializer;
using InnovEnergy.App.VrmGrabber.Database;
using InnovEnergy.Lib.Victron.VictronVRM;
using Microsoft.AspNetCore.Mvc;
using FILE=System.IO.File;
using VrmInstallation = InnovEnergy.Lib.Victron.VictronVRM.Installation;
using Installation = InnovEnergy.App.VrmGrabber.DataTypes.Installation;
using System.Diagnostics.CodeAnalysis;
namespace InnovEnergy.App.VrmGrabber;
public record Install(
String Name,
String Ip,
Int64 Vrm,
String Identifier,
String Serial,
String EscapedName,
String Online,
String LastSeen,
Int64 NumBatteries,
String BatteryVersion
);
[Controller]
public class Controller : ControllerBase
{
@ -35,26 +44,45 @@ public class Controller : ControllerBase
letter-spacing: 1px;
font-family: sans-serif;
font-size: 0.8rem;
position: absolute; top: 0; bottom: 0; left: 0; right: 0;
position: relative; top: 0; bottom: 0; left: 0; right: 0;
}
td,
th {
border: 1px solid rgb(190, 190, 190);
padding: 5px 10px;
position: sticky;
top: 0px;
background: white;
}
td {
text-align: left;
}
#managerTable {
overflow: hidden;
}</style></head>
<div id='managerTable'>
<table>
<tbody>
<tr>
<th>Name</th>
<th>Gui</th>
<th>VRM</th>
<th>Grafana</th>
<th>Identifier</th>
<th>Last Seen</th>
<th>Serial</th>
<th>#Batteries</th>
<th>Firmware-Version</th>
</tr>
{{#inst}}
{{> installations}}
{{/inst}}
</tbody>
</table>";
</table>
<div id='managerTable'>";
String partialSource =
@"<tr><td>{{Name}}</td>
@ -64,6 +92,8 @@ public class Controller : ControllerBase
<td>{{Identifier}}</td>
<td>{{LastSeen}}</td>
<td>{{Serial}}</td>
<td>{{NumBatteries}}</td>
<td>{{BatteryVersion}}</td>
</tr>";
@ -74,27 +104,23 @@ public class Controller : ControllerBase
Content = "<p>Please wait page is still loading</p>"
};
Handlebars.RegisterTemplate("installations", partialSource);
var template = Handlebars.Compile(source);
// var insts = instList.Select(i =>
// {
// var ip = Ip(i);
// return new Install(
// i.Name,
// ip[0],
// i.Vrm,
// i.Identifier,
// i.Serial,
// i.EscapedName,
// ip[1],
// LastSeen(i));
// });
var insts = instList.Select(i => new Install(
i.Name,
i.Ip,
i.Vrm,
i.Identifier,
i.Serial,
i.EscapedName,
i.Online,
DateTimeOffset.FromUnixTimeSeconds(Convert.ToInt64(i.LastSeen)).ToString(),
i.NumberOfBatteries,
i.BatteryFirmwareVersion));
var data = new
{
inst = instList
inst = insts
};
var result = template(data);
@ -106,17 +132,6 @@ public class Controller : ControllerBase
};
}
private String? LastSeen(Installation installation)
{
return Db.GetInstallationByIdentifier(installation.Identifier)?.Details.ToString();
}
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
public static String? Serial(Installation installation)
{
return Deserialize<IEnumerable<Detail>>(installation.Details).MachineSerial();
}
// [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)

View File

@ -6,7 +6,7 @@ namespace InnovEnergy.App.VrmGrabber.DataTypes;
public class Installation
{
public Installation(String? argName, String? argIp, Int64 argVrm, String? argIdentifier, String? serial, String? urlEncode, String? online, String? lastSeen, String details)
public Installation(String? argName, String? argIp, Int64 argVrm, String? argIdentifier, String? serial, String? urlEncode, String? online, String? lastSeen, String details, Int64 numberOfBatteries, String batteryFirmwareVersion)
{
Name = argName;
Ip = argIp;
@ -17,6 +17,8 @@ public class Installation
Online = online;
LastSeen = lastSeen;
Details = details;
NumberOfBatteries = numberOfBatteries;
BatteryFirmwareVersion = batteryFirmwareVersion;
}
public Installation()
@ -26,11 +28,15 @@ public class Installation
public String? Name { get; set;}
public String? Ip { get; set;}
public Int64 Vrm { get; set;}
[PrimaryKey]
public String? Identifier { get; set;}
public String? Serial { get; set;}
public String? EscapedName { get; set;}
public String? Online { get; set;}
public String? LastSeen { get; set;}
public Int64 NumberOfBatteries { get; set;}
public String? BatteryFirmwareVersion { get; set;}
public String? Details { get; set; } //JSON
}

View File

@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Web;
using CliWrap;
using CliWrap.Buffered;
@ -69,7 +70,7 @@ public static partial class Db
var installations = await user.GetInstallations();
// var returnDictionary = new Dictionary<VrmInstallation, InstallationDetails>();
foreach (var installation in installations.Take(20)) //TODO REMOVE TAKE
foreach (var installation in installations.Take(70)) //TODO REMOVE TAKE
{
Console.WriteLine(installation.Name);
var details = await GetInstallationDetails(installation);
@ -83,7 +84,9 @@ public static partial class Db
HttpUtility.UrlEncode(installation.Name),
ip[1],
details.Details.Last().Json["timestamp"].ToString(),
Serialize(details.Details));
Serialize(details.Details),
await NumberOfBatteries(ip[0]),
await BatteryFirmwareVersion(ip[0]));
if (GetInstallationByIdentifier(installation.Identifier) == null)
{
@ -96,6 +99,36 @@ public static partial class Db
}
}
private static async Task<String> BatteryFirmwareVersion(String? ip)
{
if (ip is null or "Unknown") 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");
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
}
private static async Task<Int64> NumberOfBatteries(String? ip)
{
if (ip is null or "Unknown") 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");
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
}
private static async Task<String> ExecuteBufferedAsyncCommandOnIp(String? ip, String command)
{
if (ip is null or "Unknown") return "Unknown";
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];
}
private static String?[] Ip(InstallationDetails details)
{
var online = "❌";
@ -207,3 +240,11 @@ public class AccToken
public UInt64 idUser { get; init;}
public String token { get; init;}
}
/*
dbus-send --system --dest=com.victronenergy.battery.ttyUSB1 --print-reply /FirmwareVersion \
org.freedesktop.DBus.Properties.Get string:com.victronenergy.battery.ttyUSB1
*
*
*/

View File

@ -38,4 +38,10 @@
<_ContentIncludedByDefault Remove="wwwroot\index.html" />
</ItemGroup>
<ItemGroup>
<None Update="db.sqlite">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

Binary file not shown.