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 System.Web;
using HandlebarsDotNet; using HandlebarsDotNet;
using InnovEnergy.App.RemoteSupportConsole; using InnovEnergy.App.RemoteSupportConsole;
using static System.Text.Json.JsonSerializer;
using InnovEnergy.App.VrmGrabber.Database; using InnovEnergy.App.VrmGrabber.Database;
using InnovEnergy.Lib.Victron.VictronVRM;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using FILE=System.IO.File; using FILE=System.IO.File;
using VrmInstallation = InnovEnergy.Lib.Victron.VictronVRM.Installation; using VrmInstallation = InnovEnergy.Lib.Victron.VictronVRM.Installation;
using Installation = InnovEnergy.App.VrmGrabber.DataTypes.Installation;
using System.Diagnostics.CodeAnalysis;
namespace InnovEnergy.App.VrmGrabber; 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] [Controller]
public class Controller : ControllerBase public class Controller : ControllerBase
{ {
@ -35,26 +44,45 @@ public class Controller : ControllerBase
letter-spacing: 1px; letter-spacing: 1px;
font-family: sans-serif; font-family: sans-serif;
font-size: 0.8rem; 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, td,
th { th {
border: 1px solid rgb(190, 190, 190); border: 1px solid rgb(190, 190, 190);
padding: 5px 10px; padding: 5px 10px;
position: sticky;
top: 0px;
background: white;
} }
td { td {
text-align: left; text-align: left;
}
#managerTable {
overflow: hidden;
}</style></head> }</style></head>
<div id='managerTable'>
<table> <table>
<tbody> <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}} {{#inst}}
{{> installations}} {{> installations}}
{{/inst}} {{/inst}}
</tbody> </tbody>
</table>"; </table>
<div id='managerTable'>";
String partialSource = String partialSource =
@"<tr><td>{{Name}}</td> @"<tr><td>{{Name}}</td>
@ -64,6 +92,8 @@ public class Controller : ControllerBase
<td>{{Identifier}}</td> <td>{{Identifier}}</td>
<td>{{LastSeen}}</td> <td>{{LastSeen}}</td>
<td>{{Serial}}</td> <td>{{Serial}}</td>
<td>{{NumBatteries}}</td>
<td>{{BatteryVersion}}</td>
</tr>"; </tr>";
@ -74,27 +104,23 @@ public class Controller : ControllerBase
Content = "<p>Please wait page is still loading</p>" Content = "<p>Please wait page is still loading</p>"
}; };
Handlebars.RegisterTemplate("installations", partialSource); Handlebars.RegisterTemplate("installations", partialSource);
var template = Handlebars.Compile(source); var template = Handlebars.Compile(source);
// var insts = instList.Select(i => var insts = instList.Select(i => new Install(
// { i.Name,
// var ip = Ip(i); i.Ip,
// return new Install( i.Vrm,
// i.Name, i.Identifier,
// ip[0], i.Serial,
// i.Vrm, i.EscapedName,
// i.Identifier, i.Online,
// i.Serial, DateTimeOffset.FromUnixTimeSeconds(Convert.ToInt64(i.LastSeen)).ToString(),
// i.EscapedName, i.NumberOfBatteries,
// ip[1], i.BatteryFirmwareVersion));
// LastSeen(i));
// });
var data = new var data = new
{ {
inst = instList inst = insts
}; };
var result = template(data); 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))] // [HttpGet(nameof(GetInstallation))]
// [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>")]
// public Object GetInstallation(UInt64 serialNumber) // public Object GetInstallation(UInt64 serialNumber)

View File

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

View File

@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Web; using System.Web;
using CliWrap; using CliWrap;
using CliWrap.Buffered; using CliWrap.Buffered;
@ -69,7 +70,7 @@ public static partial class Db
var installations = await user.GetInstallations(); var installations = await user.GetInstallations();
// var returnDictionary = new Dictionary<VrmInstallation, InstallationDetails>(); // 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); Console.WriteLine(installation.Name);
var details = await GetInstallationDetails(installation); var details = await GetInstallationDetails(installation);
@ -83,7 +84,9 @@ public static partial class Db
HttpUtility.UrlEncode(installation.Name), HttpUtility.UrlEncode(installation.Name),
ip[1], ip[1],
details.Details.Last().Json["timestamp"].ToString(), 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) 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) private static String?[] Ip(InstallationDetails details)
{ {
var online = "❌"; var online = "❌";
@ -207,3 +240,11 @@ public class AccToken
public UInt64 idUser { get; init;} public UInt64 idUser { get; init;}
public String token { 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

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

Binary file not shown.