96 lines
2.6 KiB
C#
96 lines
2.6 KiB
C#
|
using CliWrap;
|
||
|
using CliWrap.Buffered;
|
||
|
using InnovEnergy.Lib.Utils;
|
||
|
using static InnovEnergy.App.BmsTunnel.CliPrograms;
|
||
|
|
||
|
namespace InnovEnergy.App.BmsTunnel;
|
||
|
|
||
|
using Nodes = IReadOnlyList<Byte>;
|
||
|
|
||
|
public static class BatteryTty
|
||
|
{
|
||
|
const String DevDir = "/dev";
|
||
|
|
||
|
public static async Task<String?> GetTty()
|
||
|
{
|
||
|
Console.WriteLine("searching battery connection...");
|
||
|
|
||
|
return await GetTtyFromDBus()
|
||
|
?? await GetTtyFromDev();
|
||
|
}
|
||
|
|
||
|
private static async Task<String?> GetTtyFromDev()
|
||
|
{
|
||
|
var ttys = await FileSystem
|
||
|
.Local
|
||
|
.GetFiles(DevDir, FileType.CharacterDevice);
|
||
|
|
||
|
var candidateTtys = ttys
|
||
|
.Where(f => f.StartsWith(DevDir + "/ttyUSB"))
|
||
|
.NotNull()
|
||
|
.ToList();
|
||
|
|
||
|
if (!candidateTtys.Any())
|
||
|
{
|
||
|
Console.WriteLine("no USB converter cable attached!");
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
if (candidateTtys.Count == 1)
|
||
|
return candidateTtys[0];
|
||
|
|
||
|
return "Select TTY:".ChooseFrom(candidateTtys);
|
||
|
}
|
||
|
|
||
|
private static async Task<String?> GetTtyFromDBus()
|
||
|
{
|
||
|
var tty = await LsDBus
|
||
|
.ExecuteBufferedAsync()
|
||
|
.Select(ParseBatteryTty);
|
||
|
|
||
|
if (tty == null)
|
||
|
return null;
|
||
|
|
||
|
Console.WriteLine("found battery on DBus");
|
||
|
|
||
|
return $"{DevDir}/{tty}";
|
||
|
}
|
||
|
|
||
|
private static CommandTask<Nodes> GetNodes(String tty)
|
||
|
{
|
||
|
const String defaultArgs = "--system --print-reply --type=method_call / com.victronenergy.BusItem.GetValue";
|
||
|
|
||
|
return DBusSend
|
||
|
.AppendArgument($"--dest=com.victronenergy.battery.{tty}")
|
||
|
.AppendArgument(defaultArgs)
|
||
|
.ExecuteBufferedAsync()
|
||
|
.Select(ParseBatteryNodes);
|
||
|
}
|
||
|
|
||
|
private static Nodes ParseBatteryNodes(BufferedCommandResult result)
|
||
|
{
|
||
|
return result
|
||
|
.StandardOutput
|
||
|
.Split(Environment.NewLine)
|
||
|
.Where(l => l.Contains("_Battery/"))
|
||
|
.Select(l => l.Split('/')[1])
|
||
|
.Where(n => Byte.TryParse(n, out _))
|
||
|
.Select(Byte.Parse)
|
||
|
.Distinct()
|
||
|
.OrderBy(n => n)
|
||
|
.ToList();
|
||
|
}
|
||
|
|
||
|
private static String? ParseBatteryTty(BufferedCommandResult result)
|
||
|
{
|
||
|
return result
|
||
|
.StandardOutput
|
||
|
.Split(Environment.NewLine)
|
||
|
.Where(l => l.Contains("com.victronenergy.battery."))
|
||
|
.SelectMany(l => l.Split('.'))
|
||
|
.LastOrDefault();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|