diff --git a/csharp/App/SaliMax/deploy.sh b/csharp/App/SaliMax/deploy.sh index b55e6e141..0b31506d6 100755 --- a/csharp/App/SaliMax/deploy.sh +++ b/csharp/App/SaliMax/deploy.sh @@ -18,5 +18,5 @@ echo -e "\n============================ Deploy ============================\n" rsync -v \ ./bin/Release/$dotnet_version/linux-x64/publish/* \ - $username@$salimax_ip:~/salimax + $username@"$salimax_ip":~/salimax diff --git a/csharp/App/SaliMax/src/Program.cs b/csharp/App/SaliMax/src/Program.cs index 2df4ddbf3..5ab9a4011 100644 --- a/csharp/App/SaliMax/src/Program.cs +++ b/csharp/App/SaliMax/src/Program.cs @@ -96,7 +96,7 @@ internal static class Program StatusRecord ReadStatus() { - var battery = batteryDevices.Read().WriteLine(); + var battery = batteryDevices.Read(); var acDc = acDcDevices.Read(); var dcDc = dcDcDevices.Read(); var relays = saliMaxRelaysDevice.Read(); @@ -190,12 +190,9 @@ internal static class Program var t = UnixTime.Now; var record = ReadStatus(); - record.Relays?.ToCsv().LogInfo(); - record.ControlConstants(); record.ControlSystemState(); - (t + "\n").LogInfo(); $"{record.StateMachine.State}: {record.StateMachine.Message}".LogInfo(); var essControl = record.ControlEss().LogInfo(); @@ -210,7 +207,9 @@ internal static class Program WriteControl(record); Topology.From(record).WriteLine(); - + + //record.ToCsv().WriteLine(); + //await UploadCsv(record, t); record.Config.Save(); diff --git a/csharp/App/SaliMax/src/Topology.cs b/csharp/App/SaliMax/src/Topology.cs index 37aa0b70a..463c4476d 100644 --- a/csharp/App/SaliMax/src/Topology.cs +++ b/csharp/App/SaliMax/src/Topology.cs @@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis; using InnovEnergy.App.SaliMax.Ess; using InnovEnergy.Lib.Devices.Battery48TL; using InnovEnergy.Lib.Units; -using InnovEnergy.Lib.Units.Composite; using InnovEnergy.Lib.Units.Power; using InnovEnergy.Lib.Utils; using Ac3Bus = InnovEnergy.Lib.Units.Composite.Ac3Bus; @@ -31,7 +30,7 @@ public static class Topology var dcBusLoad = 0.W(); // TODO var dcLinkVoltage = s.DcDc.Dc.Link.Voltage.ToDisplayString(); - + var pvOnDcPower = s.PvOnDc.Dc!.Power; // TODO ! var dcBusColumn = ColumnBox("Pv" , pvOnDcPower, "Dc Bus", dcLinkVoltage, @@ -60,6 +59,13 @@ public static class Topology var individualBatteries = batteryBoxes.Any() ? TextBlock.AlignLeft(batteryBoxes) : TextBlock.Empty; + + var batteries = TextBlock + .AlignCenterVertical + ( + batteryAvgBox //, + //individualBatteries // TODO + ); var islandTopology = TextBlock .AlignCenterVertical @@ -68,8 +74,7 @@ public static class Topology inverterBox , Flow.Horizontal(inverterPower), dcBusColumn , Flow.Horizontal(dcdcPower), dcDcBox , Flow.Horizontal(dcBatteryPower), - batteryAvgBox, - individualBatteries + batteries ); if (s.GridMeter is null) diff --git a/csharp/App/SaliMax/src/Watchdog.cs b/csharp/App/SaliMax/src/Watchdog.cs index b304cb6dd..e93bac272 100644 --- a/csharp/App/SaliMax/src/Watchdog.cs +++ b/csharp/App/SaliMax/src/Watchdog.cs @@ -3,6 +3,7 @@ using System.Runtime.InteropServices; namespace InnovEnergy.App.SaliMax; // https://www.freedesktop.org/software/systemd/man/sd_notify.html + public static class Watchdog { // "it is generally recommended to ignore the return value of this call. " diff --git a/csharp/App/SaliMax/tunnelstoSalimaxX.sh b/csharp/App/SaliMax/tunnelstoSalimaxX.sh index 9d3cd62c4..f7c65bea5 100755 --- a/csharp/App/SaliMax/tunnelstoSalimaxX.sh +++ b/csharp/App/SaliMax/tunnelstoSalimaxX.sh @@ -8,7 +8,7 @@ tunnel() { rPort=$3 lPort=$4 - echo -n "localhost:$lPort $name " + echo -n "$name @ $ip mapped to localhost:$lPort " ssh -nNTL "$lPort:$ip:$rPort" "$host" 2> /dev/null & until nc -vz 127.0.0.1 $lPort 2> /dev/null @@ -22,12 +22,11 @@ tunnel() { echo "" -tunnel "Trumpf Inverter (http) " 10.0.2.1 80 7001 -tunnel "Trumpf DCDC (http) " 10.0.3.1 80 7002 -tunnel "Ext Emu Meter (http) " 10.0.4.1 80 7003 -tunnel "Int Emu Meter (http) " 10.0.4.2 80 7004 -tunnel "AMPT (http) " 10.0.5.1 8080 7005 - +tunnel "Trumpf Inverter (http) " 10.0.2.1 80 8001 +tunnel "Trumpf DCDC (http) " 10.0.3.1 80 8002 +tunnel "Ext Emu Meter (http) " 10.0.4.1 80 8003 +tunnel "Int Emu Meter (http) " 10.0.4.2 80 8004 +tunnel "AMPT (http) " 10.0.5.1 8080 8005 tunnel "Trumpf Inverter (modbus)" 10.0.2.1 502 5001 tunnel "Trumpf DCDC (modbus) " 10.0.3.1 502 5002 @@ -35,11 +34,11 @@ tunnel "Ext Emu Meter (modbus) " 10.0.4.1 502 5003 tunnel "Int Emu Meter " 10.0.4.2 502 5004 tunnel "AMPT (modbus) " 10.0.5.1 502 5005 tunnel "Adam " 10.0.1.1 502 5006 -tunnel "Batteries " 127.0.0.1 6855 5007 - +tunnel "Batteries " 127.0.0.1 6855 5007 echo echo "press any key to close the tunnels ..." read -r -n 1 -s kill $(jobs -p) echo "done" + diff --git a/csharp/Lib/Channels/Framed/Channel.cs b/csharp/Lib/Channels/Framed/Channel.cs index e5ac24f1a..6137ff595 100644 --- a/csharp/Lib/Channels/Framed/Channel.cs +++ b/csharp/Lib/Channels/Framed/Channel.cs @@ -3,7 +3,7 @@ using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Channels.Framed; -public class Channel : Connection +public class Channel : Connection { private readonly AsyncAction _Transmit; private readonly Async _Receive; diff --git a/csharp/Lib/Devices/Battery48TL/Battery48TLDevice.cs b/csharp/Lib/Devices/Battery48TL/Battery48TLDevice.cs index b22f5d2e5..58e0b9144 100644 --- a/csharp/Lib/Devices/Battery48TL/Battery48TLDevice.cs +++ b/csharp/Lib/Devices/Battery48TL/Battery48TLDevice.cs @@ -7,7 +7,7 @@ using static System.IO.Ports.Parity; namespace InnovEnergy.Lib.Devices.Battery48TL; -public class Battery48TlDevice: ModbusDevice +public class Battery48TlDevice : ModbusDevice { public const Parity Parity = Odd; public const Int32 StopBits = 1; diff --git a/csharp/Lib/Devices/Battery48TL/Battery48TlDevices.cs b/csharp/Lib/Devices/Battery48TL/Battery48TlDevices.cs index 866d4a49d..7a2c3cb45 100644 --- a/csharp/Lib/Devices/Battery48TL/Battery48TlDevices.cs +++ b/csharp/Lib/Devices/Battery48TL/Battery48TlDevices.cs @@ -20,7 +20,7 @@ public class Battery48TlDevices } catch (Exception e) { - Console.WriteLine( "Failed to read Battery data \n"+ e.Message ); + Console.WriteLine("Failed to read Battery data \n" + e.Message); // TODO: log return Battery48TlRecords.Null; diff --git a/csharp/Lib/Protocols/Modbus/Slaves/ModbusDevice.cs b/csharp/Lib/Protocols/Modbus/Slaves/ModbusDevice.cs index e04c4bef7..3f69f29a8 100644 --- a/csharp/Lib/Protocols/Modbus/Slaves/ModbusDevice.cs +++ b/csharp/Lib/Protocols/Modbus/Slaves/ModbusDevice.cs @@ -35,11 +35,11 @@ public class ModbusDevice<[DynamicallyAccessedMembers(All)] R> where R : notnull return Read(r); } - public R Read(R record) + public R Read(R record) { foreach (var batch in _Batches) batch.Read(record); - + return record; } diff --git a/csharp/Lib/Units/Unit.cs b/csharp/Lib/Units/Unit.cs index efe0986f1..d478e179f 100644 --- a/csharp/Lib/Units/Unit.cs +++ b/csharp/Lib/Units/Unit.cs @@ -9,6 +9,11 @@ public abstract class Unit public override String ToString() => $"{Value} {Symbol}"; + private static readonly IReadOnlyList Prefix = new[] { "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Y" }; + + private static Int32 MaxPrefix { get; } = Prefix.Count - 1; + private static Int32 DefaultIndex { get; } = Prefix.TakeWhile(e => e != "").Count(); + public String ToDisplayString() { if (Value == 0) @@ -17,7 +22,7 @@ public abstract class Unit var a = Math.Abs(Value); var s = Math.Sign(Value); - var i = 8; + var i = DefaultIndex; while (a >= 10000 && i < MaxPrefix) { @@ -37,8 +42,6 @@ public abstract class Unit return $"{r * s} {Prefix[i]}{Symbol}"; } - private static readonly IReadOnlyList Prefix = new[] { "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Y" }; - - private static Int32 MaxPrefix { get; } = Prefix.Count - 1; + } diff --git a/csharp/Lib/Utils/TextBlock.cs b/csharp/Lib/Utils/TextBlock.cs index 1b3ccc709..383925a61 100644 --- a/csharp/Lib/Utils/TextBlock.cs +++ b/csharp/Lib/Utils/TextBlock.cs @@ -14,6 +14,7 @@ public class TextBlock { var lines = things .SelectMany(GetLines) + .Where(l => !String.IsNullOrEmpty(l)) .ToList(); if (!lines.Any()) @@ -32,6 +33,7 @@ public class TextBlock { var lines = things .SelectMany(GetLines) + .Where(l => !String.IsNullOrEmpty(l)) .ToList(); if (!lines.Any()) @@ -50,8 +52,12 @@ public class TextBlock { var lines = things .SelectMany(GetLines) + .Where(l => !String.IsNullOrEmpty(l)) .ToList(); + if (!lines.Any()) + return Empty; + var width = lines.Max(l => l.Length); var alignedLines = lines @@ -65,8 +71,12 @@ public class TextBlock { var columns = things .Select(GetLines) + .Where(c => c.Count > 0) .ToList(); + if (!columns.Any()) + return Empty; + var height = columns.Max(l => l.Count); var alignedLines = Enumerable @@ -82,8 +92,12 @@ public class TextBlock { var columns = things .Select(GetLines) + .Where(c => c.Count > 0) .ToList(); + if (!columns.Any()) + return Empty; + var height = columns.Max(l => l.Count); var alignedLines = Enumerable @@ -99,8 +113,12 @@ public class TextBlock { var columns = things .Select(GetLines) + .Where(c => c.Count > 0) .ToList(); + if (!columns.Any()) + return Empty; + var height = columns.Max(l => l.Count); var alignedLines = Enumerable @@ -122,7 +140,7 @@ public class TextBlock public TextBlock Box() { - var width = _Lines.Max(l => l.Length); + var width = _Lines.Any() ? _Lines.Max(l => l.Length) : 0; var hLine = "".PadRight(width + 2, '─'); var top = "┌" + hLine + "┐"; @@ -140,7 +158,7 @@ public class TextBlock public TextBlock TitleBox(String title) { - var linesWidth = _Lines.Max(l => l.Length); + var linesWidth = _Lines.Any() ? _Lines.Max(l => l.Length) : 0; var titleWidth = title.Length; var width = Math.Max(linesWidth, titleWidth); diff --git a/csharp/Lib/Utils/Utils.cs b/csharp/Lib/Utils/Utils.cs index 5fa0c4a12..40b7be82f 100644 --- a/csharp/Lib/Utils/Utils.cs +++ b/csharp/Lib/Utils/Utils.cs @@ -60,9 +60,15 @@ public static class Utils return t; } + // Below does not work ;( + // [DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)] + // public static R Apply(this T t, Func f) where T : S + // { + // return f(t); + // } + [DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)] public static R Apply(this T t, Func f) => f(t); - [DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)] public static R Apply(this (T1 p1, T2 p2) t, Func f) => f(t.p1, t.p2);