diff --git a/csharp/App/Backend/Program.cs b/csharp/App/Backend/Program.cs index 3b7979293..3373101be 100644 --- a/csharp/App/Backend/Program.cs +++ b/csharp/App/Backend/Program.cs @@ -7,9 +7,6 @@ namespace InnovEnergy.App.Backend; public static class Program { - - - public static void Main(String[] args) { //Db.CreateFakeRelations(); diff --git a/csharp/App/SaliMax/run (SalimnaxProto Meiringen).sh b/csharp/App/SaliMax/run (SalimnaxProto Meiringen).sh index 7c2defe21..b9c4614cb 100755 --- a/csharp/App/SaliMax/run (SalimnaxProto Meiringen).sh +++ b/csharp/App/SaliMax/run (SalimnaxProto Meiringen).sh @@ -9,8 +9,9 @@ set -e echo -e "\n============================ Build ============================\n" -dotnet publish \ +dotnet publish \ ./SaliMax.csproj \ + -p:PublishTrimmed=false \ -c Release \ -r linux-x64 diff --git a/csharp/App/SaliMax/src/Ess/Controller.cs b/csharp/App/SaliMax/src/Ess/Controller.cs index 063e80b10..64fe03b05 100644 --- a/csharp/App/SaliMax/src/Ess/Controller.cs +++ b/csharp/App/SaliMax/src/Ess/Controller.cs @@ -28,13 +28,19 @@ public static class Controller var mode = s.SelectControlMode(); mode.WriteLine(); - + if (mode is EssMode.Off or EssMode.NoGridMeter) - return new EssControl(mode, EssLimit.NoLimit, PowerCorrection: 0, PowerSetpoint: 0); + return EssControl.Default; var essDelta = s.ComputePowerDelta(mode); - var unlimitedControl = new EssControl(mode, EssLimit.NoLimit, essDelta, 0); + var unlimitedControl = new EssControl + { + Mode = mode, + LimitedBy = EssLimit.NoLimit, + PowerCorrection = essDelta, + PowerSetpoint = 0 + }; var limitedControl = unlimitedControl .LimitChargePower(s) diff --git a/csharp/App/SaliMax/src/Ess/EssControl.cs b/csharp/App/SaliMax/src/Ess/EssControl.cs index 6d362b5c5..4886974f1 100644 --- a/csharp/App/SaliMax/src/Ess/EssControl.cs +++ b/csharp/App/SaliMax/src/Ess/EssControl.cs @@ -3,13 +3,21 @@ using InnovEnergy.Lib.Units.Power; namespace InnovEnergy.App.SaliMax.Ess; public record EssControl -( - EssMode Mode, - EssLimit LimitedBy, - ActivePower PowerCorrection, - ActivePower PowerSetpoint -) { + public required EssMode Mode { get; init; } + public required EssLimit LimitedBy { get; init; } + public required ActivePower PowerCorrection { get; init; } + public required ActivePower PowerSetpoint { get; init; } + + public static EssControl Default { get; } = new() + { + Mode = EssMode.Off, + LimitedBy = EssLimit.NoLimit, + PowerCorrection = 0, + PowerSetpoint = 0 + }; + + public EssControl LimitChargePower(Double controlDelta, EssLimit reason) { var overload = PowerCorrection - controlDelta; diff --git a/csharp/App/SaliMax/src/Ess/StatusRecord.cs b/csharp/App/SaliMax/src/Ess/StatusRecord.cs index 7a2b2a447..53c50303d 100644 --- a/csharp/App/SaliMax/src/Ess/StatusRecord.cs +++ b/csharp/App/SaliMax/src/Ess/StatusRecord.cs @@ -12,20 +12,20 @@ namespace InnovEnergy.App.SaliMax.Ess; public record StatusRecord { - public AcDcDevicesRecord AcDc { get; init; } = null!; - public DcDcDevicesRecord DcDc { get; init; } = null!; - public Battery48TlRecords Battery { get; init; } = null!; - public EmuMeterRegisters? GridMeter { get; init; } - public EmuMeterRegisters? LoadOnAcIsland { get; init; } - public AcPowerDevice? LoadOnAcGrid { get; init; } = null!; - public AcPowerDevice? PvOnAcGrid { get; init; } = null!; - public AcPowerDevice? PvOnAcIsland { get; init; } = null!; - public AcPowerDevice? AcGridToAcIsland { get; init; } = null!; - public DcPowerDevice? LoadOnDc { get; init; } = null!; - public RelaysRecord? Relays { get; init; } - public AmptStatus PvOnDc { get; init; } = null!; - public Config Config { get; init; } = null!; - public EssControl EssControl { get; set; } = null!; - public StateMachine StateMachine { get; } = new StateMachine(); + public required AcDcDevicesRecord AcDc { get; init; } + public required DcDcDevicesRecord DcDc { get; init; } + public required Battery48TlRecords Battery { get; init; } + public required EmuMeterRegisters? GridMeter { get; init; } + public required EmuMeterRegisters? LoadOnAcIsland { get; init; } + public required AcPowerDevice? LoadOnAcGrid { get; init; } + public required AcPowerDevice? PvOnAcGrid { get; init; } + public required AcPowerDevice? PvOnAcIsland { get; init; } + public required AcPowerDevice? AcGridToAcIsland { get; init; } + public required DcPowerDevice? LoadOnDc { get; init; } + public required RelaysRecord? Relays { get; init; } + public required AmptStatus PvOnDc { get; init; } + public required Config Config { get; init; } + public required EssControl EssControl { get; set; } // TODO: init only + public required StateMachine StateMachine { get; init; } } diff --git a/csharp/App/SaliMax/src/Flow.cs b/csharp/App/SaliMax/src/Flow.cs index ddebc25fb..8b74b48c5 100644 --- a/csharp/App/SaliMax/src/Flow.cs +++ b/csharp/App/SaliMax/src/Flow.cs @@ -14,7 +14,7 @@ public static class Flow public static TextBlock Horizontal(Unit amount, Int32 width = 10) { - var label = amount.ToStringRounded(); + var label = amount.ToDisplayString(); var arrowChar = amount.Value < 0 ? LeftArrowChar : RightArrowChar; var arrow = Enumerable.Repeat(arrowChar, width).Join(); @@ -26,7 +26,7 @@ public static class Flow [SuppressMessage("ReSharper", "CoVariantArrayConversion")] public static TextBlock Vertical(Unit amount, Int32 height = 4) { - var label = amount.ToStringRounded(); + var label = amount.ToDisplayString(); var arrowChar = amount.Value < 0 ? UpArrowChar : DownArrowChar; var halfArrow = Enumerable.Repeat(arrowChar, height/2); diff --git a/csharp/App/SaliMax/src/Program.cs b/csharp/App/SaliMax/src/Program.cs index 368af1747..0f35bac07 100644 --- a/csharp/App/SaliMax/src/Program.cs +++ b/csharp/App/SaliMax/src/Program.cs @@ -148,7 +148,9 @@ internal static class Program LoadOnAcIsland = loadOnAcIsland, LoadOnDc = loadOnDc, - Config = Config.Load() // load from disk every iteration, so config can be changed while running + StateMachine = StateMachine.Default, + EssControl = EssControl.Default, + Config = Config.Load() // load from disk every iteration, so config can be changed while running }; } @@ -228,17 +230,17 @@ internal static class Program var islandToGridBusPower = inverterPower + islandLoadPower; var gridLoadPower = s.LoadOnAcGrid is null ? 0: s.LoadOnAcGrid.Power.Active; - var gridPowerByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Power.Active.ToStringRounded(), - s.GridMeter.Ac.L2.Power.Active.ToStringRounded(), - s.GridMeter.Ac.L3.Power.Active.ToStringRounded()); + var gridPowerByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Power.Active.ToDisplayString(), + s.GridMeter.Ac.L2.Power.Active.ToDisplayString(), + s.GridMeter.Ac.L3.Power.Active.ToDisplayString()); - var gridVoltageByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Voltage.ToStringRounded(), - s.GridMeter.Ac.L2.Voltage.ToStringRounded(), - s.GridMeter.Ac.L3.Voltage.ToStringRounded()); + var gridVoltageByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Voltage.ToDisplayString(), + s.GridMeter.Ac.L2.Voltage.ToDisplayString(), + s.GridMeter.Ac.L3.Voltage.ToDisplayString()); - var inverterPowerByPhase = TextBlock.AlignLeft(s.AcDc.Ac.L1.Power.Active.ToStringRounded(), - s.AcDc.Ac.L2.Power.Active.ToStringRounded(), - s.AcDc.Ac.L3.Power.Active.ToStringRounded()); + var inverterPowerByPhase = TextBlock.AlignLeft(s.AcDc.Ac.L1.Power.Active.ToDisplayString(), + s.AcDc.Ac.L2.Power.Active.ToDisplayString(), + s.AcDc.Ac.L3.Power.Active.ToDisplayString()); // ReSharper disable once CoVariantArrayConversion var inverterPowerByAcDc = TextBlock.AlignLeft(s.AcDc.Devices @@ -246,7 +248,7 @@ internal static class Program .ToArray()); var dcLinkVoltage = TextBlock.CenterHorizontal("", - s.DcDc.Dc.Link.Voltage.ToStringRounded(), + s.DcDc.Dc.Link.Voltage.ToDisplayString(), ""); //var inverterPowerByPhase = new ActivePower[(Int32)s.AcDc.Ac.L1.Power.Active, (Int32)s.AcDc.Ac.L2.Power.Active, (Int32)s.AcDc.Ac.L3.Power.Active]; @@ -273,7 +275,7 @@ internal static class Program var gridBox = TextBlock.AlignLeft(gridPowerByPhase).TitleBox("Grid"); var inverterBox = TextBlock.AlignLeft(inverterPowerByAcDc).TitleBox("Inverter"); var dcDcBox = TextBlock.AlignLeft(dc48Voltage).TitleBox("DC/DC"); - var batteryBox = TextBlock.AlignLeft(batteryVoltage.ToStringRounded(), batterySoc.ToStringRounded(), batteryCurrent.ToStringRounded(), batteryTemp.ToStringRounded()).TitleBox("Battery"); + var batteryBox = TextBlock.AlignLeft(batteryVoltage.ToDisplayString(), batterySoc.ToDisplayString(), batteryCurrent.ToDisplayString(), batteryTemp.ToDisplayString()).TitleBox("Battery"); diff --git a/csharp/App/SaliMax/src/S3Config.cs b/csharp/App/SaliMax/src/S3Config.cs index 2e04acd81..c0d2cd388 100644 --- a/csharp/App/SaliMax/src/S3Config.cs +++ b/csharp/App/SaliMax/src/S3Config.cs @@ -9,12 +9,12 @@ namespace InnovEnergy.App.SaliMax; public record S3Config { - public String Bucket { get; init; } = ""; - public String Region { get; init; } = ""; - public String Provider { get; init; } = ""; - public String Key { get; init; } = ""; - public String Secret { get; init; } = ""; - public String ContentType { get; init; } = ""; + public required String Bucket { get; init; } + public required String Region { get; init; } + public required String Provider { get; init; } + public required String Key { get; init; } + public required String Secret { get; init; } + public required String ContentType { get; init; } public String Host => $"{Bucket}.{Region}.{Provider}"; public String Url => $"https://{Host}"; diff --git a/csharp/App/SaliMax/src/System/StateMachine.cs b/csharp/App/SaliMax/src/System/StateMachine.cs index 75abc1ae8..a22afb483 100644 --- a/csharp/App/SaliMax/src/System/StateMachine.cs +++ b/csharp/App/SaliMax/src/System/StateMachine.cs @@ -1,7 +1,9 @@ namespace InnovEnergy.App.SaliMax.System; -public class StateMachine +public record StateMachine { - public String Message { get; set; } = "Panic: Unknown State!"; - public Int32 State { get; set; } = 100; + public required String Message { get; set; } // TODO: init only + public required Int32 State { get; set; } // TODO: init only + + public static StateMachine Default { get; } = new StateMachine { State = 100, Message = "Unknown State" }; } \ No newline at end of file diff --git a/csharp/InnovEnergy.props b/csharp/InnovEnergy.props index b1a90c16d..cc50081b0 100644 --- a/csharp/InnovEnergy.props +++ b/csharp/InnovEnergy.props @@ -6,7 +6,7 @@ preview true enable - net6.0 + net7.0 true false Please.reload.the.project.Rider.is.stupid diff --git a/csharp/Lib/Channels/Stages/Channel.cs b/csharp/Lib/Channels/Stages/Channel.cs index 6bed3881b..b595ba2ad 100644 --- a/csharp/Lib/Channels/Stages/Channel.cs +++ b/csharp/Lib/Channels/Stages/Channel.cs @@ -4,8 +4,8 @@ namespace InnovEnergy.Lib.Channels.Stages; public class Channel { - public AsyncAction Write { get; init; } = _ => throw new NotImplementedException(nameof(Write)); - public Async Read { get; init; } = () => throw new NotImplementedException(nameof(Read)); + public required AsyncAction Write { get; init; } + public required Async Read { get; init; } public Channel Map(Stage stage) { diff --git a/csharp/Lib/Channels/Stages/ConnectedChannel.cs b/csharp/Lib/Channels/Stages/ConnectedChannel.cs index 36298420e..568720eca 100644 --- a/csharp/Lib/Channels/Stages/ConnectedChannel.cs +++ b/csharp/Lib/Channels/Stages/ConnectedChannel.cs @@ -4,9 +4,9 @@ namespace InnovEnergy.Lib.Channels.Stages; public class ConnectedChannel : Channel, IAsyncDisposable { - public Func IsOpen { get; init; } = () => throw new NotImplementedException(nameof(IsOpen)); - public AsyncAction Open { get; init; } = () => throw new NotImplementedException(nameof(Open)); - public AsyncAction Close { get; init; } = () => throw new NotImplementedException(nameof(Close)); + public required Func IsOpen { get; init; } + public required AsyncAction Open { get; init; } + public required AsyncAction Close { get; init; } public async ValueTask DisposeAsync() => await Close(); } diff --git a/csharp/Lib/Devices/AMPT/AmptCommunicationUnitStatus.cs b/csharp/Lib/Devices/AMPT/AmptCommunicationUnitStatus.cs index e9a95ea44..7031d9e77 100644 --- a/csharp/Lib/Devices/AMPT/AmptCommunicationUnitStatus.cs +++ b/csharp/Lib/Devices/AMPT/AmptCommunicationUnitStatus.cs @@ -1,16 +1,18 @@ namespace InnovEnergy.Lib.Devices.AMPT; + +// not used ATM public class AmptCommunicationUnitStatus { - public UInt32 Sid { get; init; } // A well-known value 0x53756e53, uniquely identifies this as a SunSpec Modbus Map - public UInt16 IdSunSpec { get; init; } // A well-known value 1, uniquely identifies this as a SunSpec Common Model + public required UInt32 Sid { get; init; } // A well-known value 0x53756e53, uniquely identifies this as a SunSpec Modbus Map + public required UInt16 IdSunSpec { get; init; } // A well-known value 1, uniquely identifies this as a SunSpec Common Model - public String Manufacturer { get; init; } = "undefined"; // A well-known value registered with SunSpec for compliance: "Ampt" - public String Model { get; init; } = "undefined"; // Manufacturer specific value "Communication Unit" - public String Version { get; init; } = "undefined"; // Software Version - public String SerialNumber { get; init; } = "undefined"; // Manufacturer specific value - public Int16 DeviceAddress { get; init; } // Modbus Device ID - public UInt16 IdVendor { get; init; } // Ampt SunSpec Vendor Code 64050 + public required String Manufacturer { get; init; } // A well-known value registered with SunSpec for compliance: "Ampt" + public required String Model { get; init; } // Manufacturer specific value "Communication Unit" + public required String Version { get; init; } // Software Version + public required String SerialNumber { get; init; } // Manufacturer specific value + public required Int16 DeviceAddress { get; init; } // Modbus Device ID + public required UInt16 IdVendor { get; init; } // Ampt SunSpec Vendor Code 64050 - public IReadOnlyList Devices { get; init; } = Array.Empty(); + public required IReadOnlyList Devices { get; init; } } \ No newline at end of file diff --git a/csharp/Lib/Protocols/DBus/Daemon/MatchRule.cs b/csharp/Lib/Protocols/DBus/Daemon/MatchRule.cs index fb317807b..b42f8b03b 100644 --- a/csharp/Lib/Protocols/DBus/Daemon/MatchRule.cs +++ b/csharp/Lib/Protocols/DBus/Daemon/MatchRule.cs @@ -21,13 +21,13 @@ public interface IMatchRule public record MatchRule : IMatchRule { - public MessageType? Type { get; init; } = default; - public String? Interface { get; init; } = default; - public String? Member { get; init; } = default; - public ObjectPath? Path { get; init; } = default; - public ObjectPath? PathNamespace { get; init; } = default; - public String? Sender { get; init; } = default; - public String? Destination { get; init; } = default; + public MessageType? Type { get; init; } + public String? Interface { get; init; } + public String? Member { get; init; } + public ObjectPath? Path { get; init; } + public ObjectPath? PathNamespace { get; init; } + public String? Sender { get; init; } + public String? Destination { get; init; } public Boolean Eavesdrop { get; init; } = false; public override String ToString() => this.Rule(); diff --git a/csharp/Lib/Units/Composite/Ac1Bus.cs b/csharp/Lib/Units/Composite/Ac1Bus.cs index abdc15110..deff1105b 100644 --- a/csharp/Lib/Units/Composite/Ac1Bus.cs +++ b/csharp/Lib/Units/Composite/Ac1Bus.cs @@ -5,10 +5,10 @@ public sealed class Ac1Bus private Ac1Bus() {} - public Voltage Voltage { get; private init; } = null!; - public Current Current { get; private init; } = null!; - public AcPower Power { get; private init; } = null!; - public Frequency Frequency { get; private init; } = null!; + public required Voltage Voltage { get; init; } + public required Current Current { get; init; } + public required AcPower Power { get; init; } + public required Frequency Frequency { get; init; } public static Ac1Bus FromVoltageCurrentFrequencyPhi(Double voltageRms, Double currentRms, diff --git a/csharp/Lib/Units/Composite/Ac3Bus.cs b/csharp/Lib/Units/Composite/Ac3Bus.cs index 884fcc690..03d20825d 100644 --- a/csharp/Lib/Units/Composite/Ac3Bus.cs +++ b/csharp/Lib/Units/Composite/Ac3Bus.cs @@ -6,11 +6,11 @@ public sealed class Ac3Bus { private Ac3Bus() {} - public AcPhase L1 { get; private init; } = null!; - public AcPhase L2 { get; private init; } = null!; - public AcPhase L3 { get; private init; } = null!; - public AcPower Power { get; private init; } = null!; - public Frequency Frequency { get; private init; } = null!; + public required AcPhase L1 { get; init; } + public required AcPhase L2 { get; init; } + public required AcPhase L3 { get; init; } + public required AcPower Power { get; init; } + public required Frequency Frequency { get; init; } public static Ac3Bus FromPhasesAndFrequency(AcPhase l1, AcPhase l2, diff --git a/csharp/Lib/Units/Composite/AcPhase.cs b/csharp/Lib/Units/Composite/AcPhase.cs index acacd1343..4dcb6bca9 100644 --- a/csharp/Lib/Units/Composite/AcPhase.cs +++ b/csharp/Lib/Units/Composite/AcPhase.cs @@ -7,9 +7,9 @@ public sealed class AcPhase { private AcPhase(){} - public Voltage Voltage { get; private init; } = null!; - public Current Current { get; private init; } = null!; - public AcPower Power { get; private init; } = null!; + public required Voltage Voltage { get; init; } + public required Current Current { get; init; } + public required AcPower Power { get; init; } public static AcPhase FromVoltageCurrentPhi(Voltage voltageRms, Current currentRms, diff --git a/csharp/Lib/Units/Composite/AcPower.cs b/csharp/Lib/Units/Composite/AcPower.cs index e9de3a735..e525233fd 100644 --- a/csharp/Lib/Units/Composite/AcPower.cs +++ b/csharp/Lib/Units/Composite/AcPower.cs @@ -8,11 +8,11 @@ public sealed class AcPower { private AcPower(){} - public ApparentPower Apparent { get; private init; } = null!; - public ActivePower Active { get; private init; } = null!; - public ReactivePower Reactive { get; private init; } = null!; - public Angle Phi { get; private init; } = null!; - public Double CosPhi { get; private init; } + public required ApparentPower Apparent { get; init; } + public required ActivePower Active { get; init; } + public required ReactivePower Reactive { get; init; } + public required Angle Phi { get; init; } + public required Double CosPhi { get; init; } public static AcPower FromActiveReactiveApparent(ActivePower activePower, ReactivePower reactivePower, ApparentPower apparentPower) { diff --git a/csharp/Lib/Units/Composite/DcBus.cs b/csharp/Lib/Units/Composite/DcBus.cs index c75de28ed..28653ea3d 100644 --- a/csharp/Lib/Units/Composite/DcBus.cs +++ b/csharp/Lib/Units/Composite/DcBus.cs @@ -6,9 +6,9 @@ public sealed class DcBus { private DcBus() {} - public Voltage Voltage { get; private init; } = null!; - public Current Current { get; private init; } = null!; - public ActivePower Power { get; private init; } = null!; + public required Voltage Voltage { get; init; } + public required Current Current { get; init; } + public required ActivePower Power { get; init; } public static DcBus FromVoltageCurrent(Voltage voltage, Current current) => new() { diff --git a/csharp/Lib/Units/Energy.cs b/csharp/Lib/Units/Energy.cs index 0d5412244..fe62a1a55 100644 --- a/csharp/Lib/Units/Energy.cs +++ b/csharp/Lib/Units/Energy.cs @@ -2,7 +2,7 @@ namespace InnovEnergy.Lib.Units; public sealed class Energy : Unit { - public override String Symbol => "kWh"; + public override String Symbol => "Wh"; public Energy(Double value) : base(value) { diff --git a/csharp/Lib/Units/Power/ActivePower.cs b/csharp/Lib/Units/Power/ActivePower.cs index 92a82b431..f451d4f79 100644 --- a/csharp/Lib/Units/Power/ActivePower.cs +++ b/csharp/Lib/Units/Power/ActivePower.cs @@ -12,7 +12,6 @@ public sealed class ActivePower : AcPower public static implicit operator ActivePower(Double d) => new ActivePower(d); public static implicit operator Double(ActivePower d) => d.Value; - public static ActivePower operator -(ActivePower d) => -d.Value; } diff --git a/csharp/Lib/Units/Unit.cs b/csharp/Lib/Units/Unit.cs index e007f7f66..5e5997191 100644 --- a/csharp/Lib/Units/Unit.cs +++ b/csharp/Lib/Units/Unit.cs @@ -8,5 +8,35 @@ public abstract class Unit public Double Value { get; } public override String ToString() => $"{Value} {Symbol}"; - public String ToStringRounded() => $"{Math.Round(Value,3)} {Symbol}"; -} \ No newline at end of file + + public String ToDisplayString() + { + if (Value == 0) + return $"0 {Symbol}"; + + var a = Math.Abs(Value); + var s = Math.Sign(Value); + + var i = 8; + + while (a >= 10000) + { + a /= 1000; + i++; + } + while (a < 10) + { + a *= 1000; + i--; + } + + var r = a < 100 + ? Math.Floor(a * 10) / 10 + : Math.Floor(a); + + 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" }; +} + diff --git a/csharp/Lib/Units/Units.cs b/csharp/Lib/Units/Units.cs index 8d07d3bb6..161b52a0e 100644 --- a/csharp/Lib/Units/Units.cs +++ b/csharp/Lib/Units/Units.cs @@ -1,5 +1,4 @@ using System.Collections; -using System.Reflection; using InnovEnergy.Lib.Units.Power; using InnovEnergy.Lib.Utils; using static System.Reflection.BindingFlags; @@ -20,7 +19,8 @@ public static class Units public static Frequency Hz (this Double value) => value; public static Angle Rad (this Double value) => value; public static Temperature Celsius(this Double value) => value; - public static Energy KWh (this Double value) => value; + public static Energy KWh (this Double value) => value * 1000; + public static Energy Wh (this Double value) => value; public static String ToCsv(this Object thing) { @@ -88,87 +88,3 @@ public static class Units } } -public static class Prefixes -{ - private static readonly IReadOnlyList Big = new[] - { - "", - "k", - "M", - "G", - "T", - "P", - "E", - "Y", - }; - - private static readonly IReadOnlyList Small = new[] - { - "", - "m", - "µ", - "n", - "p", - "f", - "a", - "z", - "y", - }; - - public static String TestGetPrefix(Double v, String unit) - { - if (v == 0) - return ""; - - var log10 = Math.Log10(v / 10); - var l = (Int32)Math.Floor(log10 / 3); - var lookUp = l > 0 ? Big : Small; - var i = Math.Abs(l); - - return $"{v / Math.Pow(10.0, l * 3.0)} {lookUp[i]}{unit}"; - } - - - public static String TestGetPrefix(Decimal v, String unit) - { - if (v == 0m) - return ""; - - var d = (Double)v; - var log10 = Math.Log10(d / 10); - var l = (Int32)Math.Floor(log10 / 3); - var lookUp = l > 0 ? Big : Small; - var i = Math.Abs(l); - - return $"{d / Math.Pow(10.0, l * 3.0)} {lookUp[i]}{unit}"; - } - - public static String TestGetPrefix2(Decimal v, String unit) - { - if (v == 0m) - return ""; - - var a = Math.Abs(v); - var s = Math.Sign(v); - - var i = 0; - - while (a >= 10000m) - { - a /= 1000; - i++; - } - while (a < 10m) - { - a *= 1000; - i--; - } - - var lookUp = i >= 0 ? Big : Small; - - var r = Decimal.Floor(a * 10m) / 10m; - - return $"{r*s} {lookUp[Math.Abs(i)]}{unit}"; - } - -} diff --git a/csharp/Lib/WebServer/Default.cs b/csharp/Lib/WebServer/Default.cs index af8c7d638..98c210f8f 100644 --- a/csharp/Lib/WebServer/Default.cs +++ b/csharp/Lib/WebServer/Default.cs @@ -5,8 +5,8 @@ namespace InnovEnergy.Lib.WebServer; public static class Default { - public static IPEndPoint EndPoint { get; } = new IPEndPoint(0, 0); - public static Url Url { get; } = new Url(""); + public static IPEndPoint EndPoint { get; } = new IPEndPoint(0, 0); + public static Url Url { get; } = new Url(""); public static HttpResponse HttpNotFound { get; } = new HttpResponse { StatusCode = 404 }; public static HttpResponse HttpForbidden { get; } = new HttpResponse { StatusCode = 403 };