Innovenergy_trunk/csharp/app/TestBatteryDbus/Program.cs

196 lines
7.1 KiB
C#
Raw Normal View History

2023-02-16 12:57:06 +00:00
using System.Diagnostics;
using System.Net.Sockets;
using CliWrap;
using CliWrap.Buffered;
using InnovEnergy.Lib.Protocols.DBus;
using InnovEnergy.Lib.Protocols.DBus.Daemon;
using InnovEnergy.Lib.Protocols.DBus.Transport;
using InnovEnergy.Lib.Utils;
using InnovEnergy.Lib.Victron.VeDBus;
namespace InnovEnergy.TestBatteryDbus;
//Setting up properties
internal static class Props
{
public static VeProperties Properties = new VeProperties();
}
public static class Program
{
public static Int32 Help()
{
Console.WriteLine("Usage: TestDbus name [args]");
Console.WriteLine("");
Console.WriteLine("Allowed args:");
Console.WriteLine(" -f forces the name. only used for com.victronenergy.settings");
Console.WriteLine(" -h displays this text");
Console.WriteLine("");
Console.WriteLine("This program allows you to \"fake\" a process with dbus-connection.");
Console.WriteLine("It overtakes and duplicates an existing service specified by the first argument name");
Console.WriteLine("");
Console.WriteLine("Allowed Commands:");
Console.WriteLine(" /exit exits the program");
Console.WriteLine(" /get name gets the value at name");
Console.WriteLine(" /set name value sets the value at name to value");
return 0;
}
public static async Task<Int32> Main(String[] args)
{
if (args.Contains("-h"))
{
return Help();
}
var dev = "Release"; //for Debuging change to Debug
//Setup DBUS connection
Console.WriteLine("Setting up Dbus-connection");
var dbus = new DBusConnection(Bus.System);
//Todo Remove me
if (dev == "Debug")
{
var ep = new UnixDomainSocketEndPoint("/home/kim/graber_dbus.sock");
var auth = AuthenticationMethod.ExternalAsRoot();
var dbusAddress = new Bus(ep, auth);
dbus = new DBusConnection(dbusAddress);
}
//Taking name from args or giving a list of named services to choose from
var name = args.FirstOrDefault(predicate: (arg) => !arg.StartsWith("-"), await ChooseFromNames(dbus));
//catch settings
if (name == "com.victronenergy.settings" && !args.Contains("-f"))
{
Console.WriteLine("com.victronenergy.settings cannot be simulated as the watchdog would force reboot the system.");
Console.WriteLine("Use -f to overwrite");
}
// var properties = new VeProperties();
//Grab up-to-date dbus items and build mirrored VeProperties
Console.WriteLine("Success...Grabbing newest settings from:");
Console.WriteLine(name);
// fill properties with preexisting values of the replaced task
var values = await dbus
.GetAllValues(name);
var texts = await dbus
.GetAllTexts(name);
var keys = values.Keys.Intersect(texts.Keys);
foreach (var key in keys)
{
//writable true is so our new process will correctly handle set requests
Props.Properties.Set(key, values[key], text: texts[key], writable: true);
}
//Catch com.victronenergy.settings name
Console.WriteLine("Success...Catching name and publishing under: ");
Console.WriteLine(name);
//Grabbing process name :1.xx and getting the task process id from that
var processIdNameOwner = await dbus.GetNameOwner(name);
var processIdTask = dbus.GetConnectionUnixProcessId(processIdNameOwner);
Int32 processId = (Int32)await processIdTask;
Console.WriteLine("pid: " + processId);
//Setup command accepting loop
//Queue our task for the name and then kill the old task carrying that name. This should allow us to grab said name and publish to it.
await dbus.RequestName(name, RequestNameOptions.None);
var usurpedProcess = new Process();
if (dev == "Debug")
{
var result = await Cli.Wrap("ssh").WithArguments($"root@beaglebone kill -9 {processId}").ExecuteBufferedAsync();
// usurpedProcess = Process.GetProcessById(processId);
}
else
{
usurpedProcess = Process.GetProcessById(processId);
usurpedProcess.Kill();
}
// var commandHandler = new Task(() => {
// Console.WriteLine("Enter Commands or exit with /exit: ");
// while (true)
// {
// Console.WriteLine("");
//
// var cmd = Console.ReadLine()?.ToUpper().Trim();
//
// //Get out if the command is invalid or none
// if (StringUtils.IsNullOrEmpty(cmd)) continue;
// if (!cmd!.StartsWith("/")) {Help(); continue;}
//
// //Handle command and if requested end the program, restart the original service we overtook
// var exit = ProcessLocalCommand(cmd);
// if (!exit) continue;
// if (dev == "Debug")
// {
// var result2 = Cli.Wrap("ssh")
// .WithArguments($"root@beaglebone cd /service && svc -u dbus-fronius") //{usurpedProcess.ProcessName}
// .ExecuteBufferedAsync();
// return;
// }
// usurpedProcess.Start();
// return;
// }});
var publishTask = await Props.Properties.PublishOnDBus(dbus);
//run publish and command-handler and end the program if exit is called or an exception occurs
// await Task.WhenAny(commandHandler, publishTask);
//TODO use second connection for second task
return 0;
}
private static async Task<String> ChooseFromNames(DBusConnection dbus)
{
var names = (await dbus.ListNames()).Where(name => !name.StartsWith(":") && name != "org.freedesktop.DBus").ToList();
var choice = "Choose name to test as:".ChooseFrom(chooseFrom: names);
if (choice == null) Environment.Exit(0);
return choice;
}
//
// private static Boolean ProcessLocalCommand(String cmd)
// {
// switch (cmd.Split(" "))
// {
// case { } a when a[0] == "/exit":
// //end program by ending the loop
// return true;
//
// case { } b when b[0] == ("/set"):
// //set property at first argument to value of second argument
// Props.Properties.Set(b[1], b[2]);
// break;
//
// case { } c when c[0] == ("/get"):
// //Get Value of property at first argument
// Console.WriteLine(Props.Properties.Get(c[1]));
// break;
// }
//
// //continue the loop
// return false;
// }
}