diff --git a/csharp/InnovEnergy.sln b/csharp/InnovEnergy.sln
index b3c6b3b26..3a0fa6fcd 100644
--- a/csharp/InnovEnergy.sln
+++ b/csharp/InnovEnergy.sln
@@ -61,7 +61,7 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Backend", "App/Backend/Backend.csproj", "{A56F58C2-B265-435B-A985-53B4D6F49B1A}"
EndProject
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatusData", "Lib\StatusData\StatusData.csproj", "{C04FB6DA-23C6-46BB-9B21-8F4FBA32FFF7}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Units", "Lib\Units\Units.csproj", "{C04FB6DA-23C6-46BB-9B21-8F4FBA32FFF7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Meta", "Meta", "{AED84693-C389-44C9-B2C0-ACB560189CF2}"
ProjectSection(SolutionItems) = preProject
diff --git a/csharp/InnovEnergy.sln.DotSettings b/csharp/InnovEnergy.sln.DotSettings
index 308df85e9..f48e450b2 100644
--- a/csharp/InnovEnergy.sln.DotSettings
+++ b/csharp/InnovEnergy.sln.DotSettings
@@ -1,6 +1,8 @@
- False
+
<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ False
+
True
True
True
@@ -34,4 +36,5 @@
True
True
True
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/BatteryStatus.cs b/csharp/Lib/StatusApi/BatteryStatus.cs
new file mode 100644
index 000000000..0b033b420
--- /dev/null
+++ b/csharp/Lib/StatusApi/BatteryStatus.cs
@@ -0,0 +1,7 @@
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+public abstract record BatteryStatus(DcPhase Dc) : DeviceStatus, IDcConnection;
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Connections/DcConnection.cs b/csharp/Lib/StatusApi/Connections/DcConnection.cs
deleted file mode 100644
index cac41968d..000000000
--- a/csharp/Lib/StatusApi/Connections/DcConnection.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Phases;
-namespace InnovEnergy.Lib.StatusApi.Connections;
-
-
-public record DcConnection(Decimal Voltage, Decimal Current) : Phase(Voltage, Current)
-{
- public Decimal Power => (Current * Voltage).Round3();
-}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Connections/IAc1Connection.cs b/csharp/Lib/StatusApi/Connections/IAc1Connection.cs
new file mode 100644
index 000000000..df3a472a1
--- /dev/null
+++ b/csharp/Lib/StatusApi/Connections/IAc1Connection.cs
@@ -0,0 +1,8 @@
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi.Connections;
+
+public interface IAc1Connection
+{
+ Ac1Phase Ac1 { get; }
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Connections/IAc3Connection.cs b/csharp/Lib/StatusApi/Connections/IAc3Connection.cs
new file mode 100644
index 000000000..231982cf0
--- /dev/null
+++ b/csharp/Lib/StatusApi/Connections/IAc3Connection.cs
@@ -0,0 +1,8 @@
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi.Connections;
+
+public interface IAc3Connection
+{
+ Ac1Phase Ac3 { get; }
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Connections/IDcConnection.cs b/csharp/Lib/StatusApi/Connections/IDcConnection.cs
new file mode 100644
index 000000000..6074a6750
--- /dev/null
+++ b/csharp/Lib/StatusApi/Connections/IDcConnection.cs
@@ -0,0 +1,9 @@
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi.Connections;
+
+
+public interface IDcConnection
+{
+ DcPhase Dc { get; }
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Connections/IPvConnection.cs b/csharp/Lib/StatusApi/Connections/IPvConnection.cs
new file mode 100644
index 000000000..a117f2d17
--- /dev/null
+++ b/csharp/Lib/StatusApi/Connections/IPvConnection.cs
@@ -0,0 +1,8 @@
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi.Connections;
+
+public interface IPvConnection
+{
+ IReadOnlyList Strings { get; }
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Connections/SinglePhaseAcConnection.cs b/csharp/Lib/StatusApi/Connections/SinglePhaseAcConnection.cs
deleted file mode 100644
index 6b8c57b2d..000000000
--- a/csharp/Lib/StatusApi/Connections/SinglePhaseAcConnection.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Phases;
-
-namespace InnovEnergy.Lib.StatusApi.Connections;
-
-public record SinglePhaseAcConnection
-(
- Decimal Voltage,
- Decimal Current,
- Decimal Phi,
- Decimal Frequency
-);
- //: AcPhase(Voltage, Current, Phi);
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Connections/ThreePhaseAcConnection.cs b/csharp/Lib/StatusApi/Connections/ThreePhaseAcConnection.cs
deleted file mode 100644
index f029b2fc4..000000000
--- a/csharp/Lib/StatusApi/Connections/ThreePhaseAcConnection.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Phases;
-
-namespace InnovEnergy.Lib.StatusApi.Connections;
-
-public record ThreePhaseAcConnection(AcPhase L1, AcPhase L2, AcPhase L3, Decimal Frequency)
-{
- public Decimal ApparentPower => L1.ApparentPower + L2.ApparentPower + L3.ApparentPower;
- public Decimal ReactivePower => L1.ReactivePower + L2.ReactivePower + L3.ReactivePower;
- public Decimal ActivePower => L1.ActivePower + L2.ActivePower + L3.ActivePower;
-}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/DcDcConverterStatus.cs b/csharp/Lib/StatusApi/DcDcConverterStatus.cs
new file mode 100644
index 000000000..cdda395d9
--- /dev/null
+++ b/csharp/Lib/StatusApi/DcDcConverterStatus.cs
@@ -0,0 +1,8 @@
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+public abstract record DcDcConverterStatus(DcPhase Left, DcPhase Right) : DeviceStatus;
+
+
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/Device.cs b/csharp/Lib/StatusApi/DeviceStatus.cs
similarity index 59%
rename from csharp/Lib/StatusApi/Devices/Device.cs
rename to csharp/Lib/StatusApi/DeviceStatus.cs
index 879e03326..f34a37d23 100644
--- a/csharp/Lib/StatusApi/Devices/Device.cs
+++ b/csharp/Lib/StatusApi/DeviceStatus.cs
@@ -1,6 +1,6 @@
-namespace InnovEnergy.Lib.StatusApi.Devices;
+namespace InnovEnergy.Lib.StatusApi;
-public abstract record Device
+public abstract record DeviceStatus
{
public String DeviceType
{
@@ -11,7 +11,7 @@ public abstract record Device
while (!t!.IsAbstract)
t = t.BaseType;
- return t.Name;
+ return t.Name.Replace("Status", "");
}
}
}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/DeviceType.cs b/csharp/Lib/StatusApi/DeviceType.cs
deleted file mode 100644
index 47b391875..000000000
--- a/csharp/Lib/StatusApi/DeviceType.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-namespace InnovEnergy.Lib.StatusApi;
-
-/// SIGN CONVENTION
-///
-/// Voltages have to be measured/indicated so that they are guaranteed to be never negative.
-/// In the case of AC this is accomplished by using the RMS measurement.
-/// The sign convention of the current (and hence power, since voltage defined to be never negative)
-/// depends on the type of the device.
-/// If the device can only produce (e.g. PV) or only consume (e.g. Loads),
-/// then the current has to be 0 or positive.
-/// If the device is a prosumer (e.g. inverter, battery, grid...)
-/// then a positive sign denotes current (power) flow away from the grid (to the "right")
-/// and a negative sign denotes current (power) flow towards the grid (to the "left")
-
-
-
-
-/// the currently known DeviceTypes, to be serialized as string in JSON
-public enum DeviceType
-{
- None,
- PvOnAcIn ,
- PvOnAcOut ,
- PvOnDc ,
- Load ,
- CriticalLoad,
- Battery ,
- Grid ,
- Inverter ,
- AcInToAcOut ,
- DcDc ,
- DcLoad ,
- Losses
-}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/Battery.cs b/csharp/Lib/StatusApi/Devices/Battery.cs
deleted file mode 100644
index 3b8b1d476..000000000
--- a/csharp/Lib/StatusApi/Devices/Battery.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-public abstract record Battery
- (
- DcConnection Dc,
- Decimal Soc,
- Decimal Temperature
- )
- : DcDevice(Dc);
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/DcDcConverter.cs b/csharp/Lib/StatusApi/Devices/DcDcConverter.cs
deleted file mode 100644
index dd754d1f1..000000000
--- a/csharp/Lib/StatusApi/Devices/DcDcConverter.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-public abstract record DcDcConverter
-(
- DcConnection Left,
- DcConnection Right
-)
- : Device;
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/DcDevice.cs b/csharp/Lib/StatusApi/Devices/DcDevice.cs
deleted file mode 100644
index 280086f26..000000000
--- a/csharp/Lib/StatusApi/Devices/DcDevice.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-public abstract record DcDevice(DcConnection Dc) : Device;
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/GridMeter.cs b/csharp/Lib/StatusApi/Devices/GridMeter.cs
deleted file mode 100644
index 32223244b..000000000
--- a/csharp/Lib/StatusApi/Devices/GridMeter.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-public abstract record GridMeter(ThreePhaseAcConnection Ac) : ThreePhaseAcDevice(Ac);
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/IPvCoupledDevice.cs b/csharp/Lib/StatusApi/Devices/IPvCoupledDevice.cs
deleted file mode 100644
index 53281d8ce..000000000
--- a/csharp/Lib/StatusApi/Devices/IPvCoupledDevice.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-public interface IPvCoupledDevice
-{
- IReadOnlyList Strings { get; }
-}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/Mppt.cs b/csharp/Lib/StatusApi/Devices/Mppt.cs
deleted file mode 100644
index 2e9630d22..000000000
--- a/csharp/Lib/StatusApi/Devices/Mppt.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-public abstract record Mppt
- (
- DcConnection Dc,
- IReadOnlyList Strings
- )
- : DcDevice(Dc), IPvCoupledDevice;
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/SinglePhaseAcDevice.cs b/csharp/Lib/StatusApi/Devices/SinglePhaseAcDevice.cs
deleted file mode 100644
index 4e259e05a..000000000
--- a/csharp/Lib/StatusApi/Devices/SinglePhaseAcDevice.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-
-public abstract record SinglePhaseAcDevice(SinglePhaseAcConnection Ac) : Device;
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/SinglePhaseInverter.cs b/csharp/Lib/StatusApi/Devices/SinglePhaseInverter.cs
deleted file mode 100644
index d63747161..000000000
--- a/csharp/Lib/StatusApi/Devices/SinglePhaseInverter.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-public abstract record SinglePhaseInverter(SinglePhaseAcConnection Ac, DcConnection Dc);
-
-
diff --git a/csharp/Lib/StatusApi/Devices/SinglePhasePvInverter.cs b/csharp/Lib/StatusApi/Devices/SinglePhasePvInverter.cs
deleted file mode 100644
index bf0a65c50..000000000
--- a/csharp/Lib/StatusApi/Devices/SinglePhasePvInverter.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-public abstract record SinglePhasePvInverter
- (
- SinglePhaseAcConnection Ac,
- IReadOnlyList Strings
- )
- : SinglePhaseAcDevice(Ac), IPvCoupledDevice;
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/ThreePhaseAcDevice.cs b/csharp/Lib/StatusApi/Devices/ThreePhaseAcDevice.cs
deleted file mode 100644
index 340218e09..000000000
--- a/csharp/Lib/StatusApi/Devices/ThreePhaseAcDevice.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-public abstract record ThreePhaseAcDevice(ThreePhaseAcConnection Ac) : Device;
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/ThreePhaseInverter.cs b/csharp/Lib/StatusApi/Devices/ThreePhaseInverter.cs
deleted file mode 100644
index 895a9edf2..000000000
--- a/csharp/Lib/StatusApi/Devices/ThreePhaseInverter.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-public abstract record ThreePhaseInverter
- (
- ThreePhaseAcConnection Ac,
- DcConnection Dc
- )
- : Device;
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Devices/ThreePhasePvInverter.cs b/csharp/Lib/StatusApi/Devices/ThreePhasePvInverter.cs
deleted file mode 100644
index ad07f5202..000000000
--- a/csharp/Lib/StatusApi/Devices/ThreePhasePvInverter.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using InnovEnergy.Lib.StatusApi.Connections;
-
-namespace InnovEnergy.Lib.StatusApi.Devices;
-
-public abstract record ThreePhasePvInverter
- (
- ThreePhaseAcConnection Ac,
- IReadOnlyList Strings
- )
- : ThreePhaseAcDevice(Ac), IPvCoupledDevice;
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/MpptStatus.cs b/csharp/Lib/StatusApi/MpptStatus.cs
new file mode 100644
index 000000000..bec31ddec
--- /dev/null
+++ b/csharp/Lib/StatusApi/MpptStatus.cs
@@ -0,0 +1,8 @@
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+public record MpptStatus(DcPhase Dc, IReadOnlyList Strings) : IDcConnection, IPvConnection;
+
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Phases/AcPhase.cs b/csharp/Lib/StatusApi/Phases/AcPhase.cs
deleted file mode 100644
index 068e19393..000000000
--- a/csharp/Lib/StatusApi/Phases/AcPhase.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using static DecimalMath.DecimalEx;
-
-namespace InnovEnergy.Lib.StatusApi.Phases;
-
-
-public record AcPhase(Decimal Voltage, Decimal Current, Decimal Phi)
- : Phase(Voltage, Current)
-{
-
- public Decimal ApparentPower => Voltage * Current;
- public Decimal ActivePower => ApparentPower * PowerFactor;
- public Decimal ReactivePower => ApparentPower * Sin(Phi);
- public Decimal PowerFactor => Cos(Phi);
-
- public static AcPhase FromActiveReactive
- (
- Decimal activePower,
- Decimal reactivePower,
- Decimal voltage,
- Decimal current
- )
- {
- var phi = ATan2(reactivePower, activePower);
-
- return new AcPhase
- (
- Voltage: voltage,
- Current: current,
- Phi: phi
- );
-
- }
-
-
-}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Phases/Phase.cs b/csharp/Lib/StatusApi/Phases/Phase.cs
deleted file mode 100644
index 236d6cf77..000000000
--- a/csharp/Lib/StatusApi/Phases/Phase.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace InnovEnergy.Lib.StatusApi.Phases;
-
-/// A phase must have at least a known Voltage and Current.
-/// For DC this is already enough.
-/// For AC the values have to be in RMS (not amplitude or P2P)
-/// Power can be inferred, P = UI
-
-public abstract record Phase
- (
- Decimal Voltage,
- Decimal Current
- );
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/PowerMeterStatus.cs b/csharp/Lib/StatusApi/PowerMeterStatus.cs
new file mode 100644
index 000000000..41038f4dc
--- /dev/null
+++ b/csharp/Lib/StatusApi/PowerMeterStatus.cs
@@ -0,0 +1,6 @@
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+public abstract record PowerMeterStatus(Ac1Phase Ac3) : DeviceStatus, IAc3Connection;
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/SinglePhaseInverterStatus.cs b/csharp/Lib/StatusApi/SinglePhaseInverterStatus.cs
new file mode 100644
index 000000000..a1b404bd6
--- /dev/null
+++ b/csharp/Lib/StatusApi/SinglePhaseInverterStatus.cs
@@ -0,0 +1,9 @@
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+public abstract record SinglePhaseInverterStatus(Ac1Phase Ac1, DcPhase Dc) :
+ DeviceStatus,
+ IAc1Connection,
+ IDcConnection;
diff --git a/csharp/Lib/StatusApi/SinglePhasePvInverterStatus.cs b/csharp/Lib/StatusApi/SinglePhasePvInverterStatus.cs
new file mode 100644
index 000000000..377f9f6f3
--- /dev/null
+++ b/csharp/Lib/StatusApi/SinglePhasePvInverterStatus.cs
@@ -0,0 +1,9 @@
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+public abstract record SinglePhasePvInverterStatus(Ac1Phase Ac1, IReadOnlyList Strings) :
+ DeviceStatus,
+ IAc1Connection,
+ IPvConnection;
diff --git a/csharp/Lib/StatusApi/StatusApi.csproj b/csharp/Lib/StatusApi/StatusApi.csproj
index f1e4bc0f8..88fda982e 100644
--- a/csharp/Lib/StatusApi/StatusApi.csproj
+++ b/csharp/Lib/StatusApi/StatusApi.csproj
@@ -3,6 +3,7 @@
+
diff --git a/csharp/Lib/StatusApi/ThreePhaseInverterStatus.cs b/csharp/Lib/StatusApi/ThreePhaseInverterStatus.cs
new file mode 100644
index 000000000..8c2fc424f
--- /dev/null
+++ b/csharp/Lib/StatusApi/ThreePhaseInverterStatus.cs
@@ -0,0 +1,10 @@
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+public abstract record ThreePhaseInverterStatus(Ac1Phase Ac3, DcPhase Dc) :
+ DeviceStatus,
+ IAc3Connection,
+ IDcConnection;
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/ThreePhasePvInverterStatus.cs b/csharp/Lib/StatusApi/ThreePhasePvInverterStatus.cs
new file mode 100644
index 000000000..c09471d4b
--- /dev/null
+++ b/csharp/Lib/StatusApi/ThreePhasePvInverterStatus.cs
@@ -0,0 +1,9 @@
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.Units.Composite;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+public abstract record ThreePhasePvInverterStatus(Ac1Phase Ac3, IReadOnlyList Strings) :
+ DeviceStatus,
+ IAc3Connection,
+ IPvConnection;
diff --git a/csharp/Lib/StatusData/Current.cs b/csharp/Lib/StatusData/Current.cs
deleted file mode 100644
index 2f65add3c..000000000
--- a/csharp/Lib/StatusData/Current.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-namespace InnovEnergy.Lib.StatusData;
-
-public readonly struct Current
-{
- public static String Unit => "A";
- public static String Symbol => "I";
-
- public Decimal Value { get; }
-
- public Current(Decimal value) => Value = value;
-
- public override String ToString() => Value + Unit;
-
-
- // parallel
- public static Current operator |(Current left, Current right) => new Current(left.Value + right.Value);
-
- // scalar multiplication
- public static Current operator *(Decimal scalar , Current current) => new Current(scalar * current.Value);
- public static Current operator *(Current current, Decimal scalar) => new Current(scalar * current.Value);
- public static Current operator *(Int32 scalar , Current current) => new Current(scalar * current.Value);
- public static Current operator *(Current current, Int32 scalar) => new Current(scalar * current.Value);
- public static Current operator /(Current current, Decimal scalar) => new Current(current.Value / scalar);
- public static Current operator /(Current current, Int32 scalar) => new Current(current.Value / scalar);
-
- // P=UI
- public static Power operator *(Current current, Voltage voltage) => new Power(current.Value * voltage.Value);
-
- // U=RI
- public static Voltage operator *(Current current, Resistance resistance) => new Voltage(resistance.Value* current.Value);
-
-}
\ No newline at end of file
diff --git a/csharp/Lib/StatusData/Json/Converters.cs b/csharp/Lib/StatusData/Json/Converters.cs
deleted file mode 100644
index ab6a4336b..000000000
--- a/csharp/Lib/StatusData/Json/Converters.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Text.Json.Serialization;
-using InnovEnergy.Lib.StatusData.Json;
-
-// ReSharper disable once CheckNamespace
-namespace InnovEnergy.Units;
-
-public static partial class Units
-{
- public static IReadOnlyList JsonConverters = new JsonConverter[]
- {
- new CurrentConverter(),
- new VoltageConverter(),
- new PowerConverter(),
- new ResistanceConverter()
- };
-}
\ No newline at end of file
diff --git a/csharp/Lib/StatusData/Power.cs b/csharp/Lib/StatusData/Power.cs
deleted file mode 100644
index 3a605dfca..000000000
--- a/csharp/Lib/StatusData/Power.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using InnovEnergy.Units;
-
-namespace InnovEnergy.Lib.StatusData;
-
-public readonly struct Power
-{
- public static String Unit => "W";
- public static String Symbol => "P";
-
- public Decimal Value { get; }
-
- public Power(Decimal value) => Value = value;
-
- public override String ToString() => Value + Unit;
-
-
- // parallel
- public static Power operator |(Power left, Power right) => new Power(left.Value + right.Value);
- // series
- public static Power operator +(Power left, Power right) => new Power(left.Value + right.Value);
-
- // scalar multiplication
- public static Power operator *(Decimal scalar, Power power ) => new Power(scalar * power.Value);
- public static Power operator *(Power power , Decimal scalar) => new Power(scalar * power.Value);
- public static Power operator *(Int32 scalar, Power power ) => new Power(scalar * power.Value);
- public static Power operator *(Power power , Int32 scalar) => new Power(scalar * power.Value);
- public static Power operator /(Power power , Decimal scalar) => new Power(power.Value / scalar);
- public static Power operator /(Power power , Int32 scalar) => new Power(power.Value / scalar);
-
- // P=UI
- public static Voltage operator /(Power power, Current current) => new Voltage(power.Value / current.Value);
- public static Current operator /(Power power, Voltage voltage) => new Current(power.Value / voltage.Value);
-}
\ No newline at end of file
diff --git a/csharp/Lib/StatusData/Resistance.cs b/csharp/Lib/StatusData/Resistance.cs
deleted file mode 100644
index d10573e77..000000000
--- a/csharp/Lib/StatusData/Resistance.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-namespace InnovEnergy.Lib.StatusData;
-
-public readonly struct Resistance
-{
- public static String Unit => "Ω";
- public static String Symbol => "R";
-
- public Decimal Value { get; }
-
- public Resistance(Decimal value) => Value = value;
-
- public override String ToString() => Value + Unit;
-
- // series
- public static Resistance operator +(Resistance left, Resistance right) => new Resistance(left.Value + right.Value);
- // parallel
- public static Resistance operator |(Resistance left, Resistance right) => new Resistance(1m / (1m / left.Value + 1m / right.Value));
-
- // scalar multiplication
- public static Resistance operator *(Decimal scalar , Resistance resistance) => new Resistance(scalar * resistance.Value);
- public static Resistance operator *(Resistance resistance, Decimal scalar ) => new Resistance(scalar * resistance.Value);
- public static Resistance operator *(Int32 scalar , Resistance resistance) => new Resistance(scalar * resistance.Value);
- public static Resistance operator *(Resistance resistance, Int32 scalar ) => new Resistance(scalar * resistance.Value);
- public static Resistance operator /(Resistance resistance, Decimal scalar ) => new Resistance(resistance.Value / scalar);
- public static Resistance operator /(Resistance resistance, Int32 scalar ) => new Resistance(resistance.Value / scalar);
-
-
- // U=RI
- public static Voltage operator *(Resistance resistance, Current current) => new Voltage(resistance.Value* current.Value);
-
-
-
- // public static Voltage operator /(Power power, Current current) => new Voltage(power.Value / current.Value);
- // public static Current operator /(Power power, Voltage voltage) => new Current(power.Value / voltage.Value);
-}
\ No newline at end of file
diff --git a/csharp/Lib/StatusData/Units.cs b/csharp/Lib/StatusData/Units.cs
deleted file mode 100644
index 4dacaa297..000000000
--- a/csharp/Lib/StatusData/Units.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace InnovEnergy.Lib.StatusData;
-
-public static partial class Units
-{
- public static Current A (this Decimal value) => new Current(value);
- public static Voltage V (this Decimal value) => new Voltage(value);
- public static Power W (this Decimal value) => new Power(value);
- public static Resistance Ohm(this Decimal value) => new Resistance(value);
-}
\ No newline at end of file
diff --git a/csharp/Lib/StatusData/Voltage.cs b/csharp/Lib/StatusData/Voltage.cs
deleted file mode 100644
index fa7c8a7fc..000000000
--- a/csharp/Lib/StatusData/Voltage.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-namespace InnovEnergy.Lib.StatusData;
-
-public readonly struct Voltage
-{
- public static String Unit => "V";
- public static String Symbol => "U";
-
- public Decimal Value { get; }
-
- public Voltage(Decimal value) => Value = value;
-
- public override String ToString() => Value + Unit;
-
-
- // series
- public static Voltage operator +(Voltage left, Voltage right) => new Voltage(left.Value + right.Value);
-
- public static Voltage operator *(Decimal scalar , Voltage voltage) => new Voltage(scalar * voltage.Value);
- public static Voltage operator *(Voltage voltage, Decimal scalar) => new Voltage(scalar * voltage.Value);
- public static Voltage operator *(Int32 scalar , Voltage voltage) => new Voltage(scalar * voltage.Value);
- public static Voltage operator *(Voltage voltage, Int32 scalar) => new Voltage(scalar * voltage.Value);
-
- public static Voltage operator /(Voltage voltage, Decimal scalar) => new Voltage(voltage.Value / scalar);
- public static Voltage operator /(Voltage voltage, Int32 scalar) => new Voltage(voltage.Value / scalar);
-
-
- // U=RI
- public static Current operator /(Voltage voltage, Resistance resistance) => new Current(voltage.Value / resistance.Value);
-
- // P=UI
- public static Power operator *(Voltage voltage, Current current) => new Power(current.Value * voltage.Value);
-}
\ No newline at end of file
diff --git a/csharp/Lib/Units/Angle.cs b/csharp/Lib/Units/Angle.cs
new file mode 100644
index 000000000..0f0aa7d8f
--- /dev/null
+++ b/csharp/Lib/Units/Angle.cs
@@ -0,0 +1,73 @@
+using DecimalMath;
+using InnovEnergy.Lib.Utils;
+
+namespace InnovEnergy.Lib.Units;
+
+using T = Angle;
+
+public readonly struct Angle
+{
+
+
+ public static String Unit => "rad";
+ public static String Symbol => "∠";
+
+ public static readonly Angle Pi = new Angle(DecimalEx.Pi);
+
+ public Decimal Value { get; }
+
+ public Angle(Decimal value)
+ {
+ var modulo = value.Modulo(DecimalEx.TwoPi);
+
+ Value = modulo > DecimalEx.Pi
+ ? modulo - DecimalEx.TwoPi
+ : modulo;
+ }
+
+ public override String ToString() => Value + Unit;
+
+
+ #region scalar multiplication
+
+ public static Angle operator *(Decimal scalar, Angle angle ) => new Angle(scalar * angle.Value);
+ public static Angle operator *(Angle angle , Decimal scalar) => new Angle(scalar * angle.Value);
+ public static Angle operator /(Angle angle , Decimal scalar) => new Angle(angle.Value / scalar);
+
+ #endregion
+
+ #region addition
+
+ public static T operator +(T left, T right) => new T(left.Value + right.Value);
+ public static T operator -(T left, T right) => new T(left.Value - right.Value);
+ public static T operator -(T t) => new T(-t.Value);
+
+ #endregion
+
+ #region compare
+
+ public static Boolean operator ==(T left, T right) => left.Value == right.Value;
+ public static Boolean operator !=(T left, T right) => left.Value != right.Value;
+ public static Boolean operator > (T left, T right) => left.Value > right.Value;
+ public static Boolean operator < (T left, T right) => left.Value < right.Value;
+ public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
+ public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
+
+ #endregion
+
+ #region conversion
+
+ public static implicit operator T(Decimal d) => new T(d);
+ public static implicit operator T(Double d) => new T((Decimal)d);
+ public static implicit operator T(Int32 i) => new T(i);
+ public static implicit operator Decimal(T t) => t.Value;
+
+ #endregion
+
+ #region equality
+
+ public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
+ public override Int32 GetHashCode() => Value.GetHashCode();
+
+ #endregion
+}
\ No newline at end of file
diff --git a/csharp/Lib/Units/Composite/Ac1Phase.cs b/csharp/Lib/Units/Composite/Ac1Phase.cs
new file mode 100644
index 000000000..e9970378b
--- /dev/null
+++ b/csharp/Lib/Units/Composite/Ac1Phase.cs
@@ -0,0 +1,10 @@
+namespace InnovEnergy.Lib.Units.Composite;
+
+public record Ac1Phase
+ (
+ Voltage Voltage,
+ Current Current,
+ Angle Phi,
+ Frequency Frequency
+ ) :
+ AcPhase(Voltage, Current, Phi);
\ No newline at end of file
diff --git a/csharp/Lib/Units/Composite/Ac3Phase.cs b/csharp/Lib/Units/Composite/Ac3Phase.cs
new file mode 100644
index 000000000..1fc44306f
--- /dev/null
+++ b/csharp/Lib/Units/Composite/Ac3Phase.cs
@@ -0,0 +1,8 @@
+namespace InnovEnergy.Lib.Units.Composite;
+
+public record Ac3Phase(AcPhase L1, AcPhase L2, AcPhase L3, Decimal Frequency)
+{
+ public Power ApparentPower => L1.ApparentPower + L2.ApparentPower + L3.ApparentPower;
+ public Power ReactivePower => L1.ReactivePower + L2.ReactivePower + L3.ReactivePower;
+ public Power ActivePower => L1.ActivePower + L2.ActivePower + L3.ActivePower;
+}
\ No newline at end of file
diff --git a/csharp/Lib/Units/Composite/AcPhase.cs b/csharp/Lib/Units/Composite/AcPhase.cs
new file mode 100644
index 000000000..c616b9c57
--- /dev/null
+++ b/csharp/Lib/Units/Composite/AcPhase.cs
@@ -0,0 +1,22 @@
+using static DecimalMath.DecimalEx;
+
+namespace InnovEnergy.Lib.Units.Composite;
+
+
+public record AcPhase : Phase
+{
+ protected AcPhase(Voltage voltage, Current current, Angle phi) : base(voltage, current)
+ {
+ if (voltage < 0) throw new ArgumentException("RMS value cannot be negative", nameof(voltage));
+ if (current < 0) throw new ArgumentException("RMS value cannot be negative", nameof(current));
+
+ Phi = phi;
+ }
+
+ public Angle Phi { get; }
+
+ public Power ApparentPower => Voltage * Current;
+ public Power ActivePower => ApparentPower * PowerFactor;
+ public Power ReactivePower => ApparentPower * Sin(Phi);
+ public Decimal PowerFactor => Cos(Phi);
+}
\ No newline at end of file
diff --git a/csharp/Lib/Units/Composite/DcPhase.cs b/csharp/Lib/Units/Composite/DcPhase.cs
new file mode 100644
index 000000000..8e73313bf
--- /dev/null
+++ b/csharp/Lib/Units/Composite/DcPhase.cs
@@ -0,0 +1,6 @@
+namespace InnovEnergy.Lib.Units.Composite;
+
+public record DcPhase(Voltage Voltage, Current Current) : Phase(Voltage, Current)
+{
+ public Power Power => Current * Voltage;
+}
\ No newline at end of file
diff --git a/csharp/Lib/Units/Composite/Phase.cs b/csharp/Lib/Units/Composite/Phase.cs
new file mode 100644
index 000000000..45a3ef86d
--- /dev/null
+++ b/csharp/Lib/Units/Composite/Phase.cs
@@ -0,0 +1,7 @@
+namespace InnovEnergy.Lib.Units.Composite;
+
+public abstract record Phase
+(
+ Voltage Voltage,
+ Current Current
+);
\ No newline at end of file
diff --git a/csharp/Lib/Units/Frequency.cs b/csharp/Lib/Units/Frequency.cs
new file mode 100644
index 000000000..91a3e3849
--- /dev/null
+++ b/csharp/Lib/Units/Frequency.cs
@@ -0,0 +1,59 @@
+namespace InnovEnergy.Lib.Units;
+
+using T = Frequency;
+
+public readonly struct Frequency
+{
+ public static String Unit => "Hz";
+ public static String Symbol => "f";
+
+ public Decimal Value { get; }
+
+ public Frequency(Decimal value) => Value = value;
+
+ public override String ToString() => Value + Unit;
+
+ #region scalar multiplication
+
+ public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
+ public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
+ public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
+
+ #endregion
+
+ #region addition
+
+ public static T operator +(T left, T right) => new T(left.Value + right.Value);
+ public static T operator -(T left, T right) => new T(left.Value - right.Value);
+ public static T operator -(T t) => new T(-t.Value);
+
+ #endregion
+
+ #region compare
+
+ public static Boolean operator ==(T left, T right) => left.Value == right.Value;
+ public static Boolean operator !=(T left, T right) => left.Value != right.Value;
+ public static Boolean operator > (T left, T right) => left.Value > right.Value;
+ public static Boolean operator < (T left, T right) => left.Value < right.Value;
+ public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
+ public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
+
+ #endregion
+
+ #region conversion
+
+ public static implicit operator T(Decimal d) => new T(d);
+ public static implicit operator T(Double d) => new T((Decimal)d);
+ public static implicit operator T(Int32 i) => new T(i);
+ public static implicit operator Decimal(T t) => t.Value;
+
+ #endregion
+
+ #region equality
+
+ public Boolean Equals(T other) => Value == other.Value;
+ public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
+ public override Int32 GetHashCode() => Value.GetHashCode();
+
+ #endregion
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusData/Json/CurrentConverter.cs b/csharp/Lib/Units/Json/CurrentConverter.cs
similarity index 91%
rename from csharp/Lib/StatusData/Json/CurrentConverter.cs
rename to csharp/Lib/Units/Json/CurrentConverter.cs
index 64707325f..b89ec4a90 100644
--- a/csharp/Lib/StatusData/Json/CurrentConverter.cs
+++ b/csharp/Lib/Units/Json/CurrentConverter.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace InnovEnergy.Lib.StatusData.Json;
+namespace InnovEnergy.Lib.Units.Json;
public class CurrentConverter : JsonConverter
{
diff --git a/csharp/Lib/StatusData/Json/PowerConverter.cs b/csharp/Lib/Units/Json/PowerConverter.cs
similarity index 90%
rename from csharp/Lib/StatusData/Json/PowerConverter.cs
rename to csharp/Lib/Units/Json/PowerConverter.cs
index 8c33d3eae..766f3636c 100644
--- a/csharp/Lib/StatusData/Json/PowerConverter.cs
+++ b/csharp/Lib/Units/Json/PowerConverter.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace InnovEnergy.Lib.StatusData.Json;
+namespace InnovEnergy.Lib.Units.Json;
public class PowerConverter : JsonConverter
{
diff --git a/csharp/Lib/StatusData/Json/ResistanceConverter.cs b/csharp/Lib/Units/Json/ResistanceConverter.cs
similarity index 91%
rename from csharp/Lib/StatusData/Json/ResistanceConverter.cs
rename to csharp/Lib/Units/Json/ResistanceConverter.cs
index a60d99009..67ec28a13 100644
--- a/csharp/Lib/StatusData/Json/ResistanceConverter.cs
+++ b/csharp/Lib/Units/Json/ResistanceConverter.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace InnovEnergy.Lib.StatusData.Json;
+namespace InnovEnergy.Lib.Units.Json;
public class ResistanceConverter : JsonConverter
{
diff --git a/csharp/Lib/StatusData/Json/VoltageConverter.cs b/csharp/Lib/Units/Json/VoltageConverter.cs
similarity index 91%
rename from csharp/Lib/StatusData/Json/VoltageConverter.cs
rename to csharp/Lib/Units/Json/VoltageConverter.cs
index b51ceabf5..290c6f38b 100644
--- a/csharp/Lib/StatusData/Json/VoltageConverter.cs
+++ b/csharp/Lib/Units/Json/VoltageConverter.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace InnovEnergy.Lib.StatusData.Json;
+namespace InnovEnergy.Lib.Units.Json;
public class VoltageConverter : JsonConverter
{
diff --git a/csharp/Lib/Units/Power.cs b/csharp/Lib/Units/Power.cs
new file mode 100644
index 000000000..4bc44a53a
--- /dev/null
+++ b/csharp/Lib/Units/Power.cs
@@ -0,0 +1,66 @@
+
+namespace InnovEnergy.Lib.Units;
+
+using T = Power;
+
+public readonly struct Power
+{
+ public static String Unit => "W";
+ public static String Symbol => "P";
+
+ public Decimal Value { get; }
+
+ public Power(Decimal value) => Value = value;
+
+ public override String ToString() => Value + Unit;
+
+
+ // P=UI
+ public static Voltage operator /(Power power, Current current) => new Voltage(power.Value / current.Value);
+ public static Current operator /(Power power, Voltage voltage) => new Current(power.Value / voltage.Value);
+
+ #region scalar multiplication
+
+ public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
+ public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
+ public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
+
+ #endregion
+
+ #region addition
+
+ public static T operator +(T left, T right) => new T(left.Value + right.Value);
+ public static T operator -(T left, T right) => new T(left.Value - right.Value);
+ public static T operator -(T t) => new T(-t.Value);
+
+ #endregion
+
+ #region compare
+
+ public static Boolean operator ==(T left, T right) => left.Value == right.Value;
+ public static Boolean operator !=(T left, T right) => left.Value != right.Value;
+ public static Boolean operator > (T left, T right) => left.Value > right.Value;
+ public static Boolean operator < (T left, T right) => left.Value < right.Value;
+ public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
+ public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
+
+ #endregion
+
+ #region conversion
+
+ public static implicit operator T(Decimal d) => new T(d);
+ public static implicit operator T(Double d) => new T((Decimal)d);
+ public static implicit operator T(Int32 i) => new T(i);
+ public static implicit operator Decimal(T t) => t.Value;
+
+ #endregion
+
+ #region equality
+
+ public Boolean Equals(T other) => Value == other.Value;
+ public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
+ public override Int32 GetHashCode() => Value.GetHashCode();
+
+ #endregion
+
+}
\ No newline at end of file
diff --git a/csharp/Lib/Units/Resistance.cs b/csharp/Lib/Units/Resistance.cs
new file mode 100644
index 000000000..c3c0b34c0
--- /dev/null
+++ b/csharp/Lib/Units/Resistance.cs
@@ -0,0 +1,63 @@
+namespace InnovEnergy.Lib.Units;
+
+using T = Resistance;
+
+public readonly struct Resistance
+{
+ public static String Unit => "Ω";
+ public static String Symbol => "R";
+
+ public Decimal Value { get; }
+
+ public Resistance(Decimal value) => Value = value;
+
+ public override String ToString() => Value + Unit;
+
+ // U=RI
+ public static Voltage operator *(Resistance resistance, Current current) => new Voltage(resistance.Value * current.Value);
+
+ #region scalar multiplication
+
+ public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
+ public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
+ public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
+
+ #endregion
+
+ #region addition
+
+ public static T operator +(T left, T right) => new T(left.Value + right.Value);
+ public static T operator -(T left, T right) => new T(left.Value - right.Value);
+ public static T operator -(T t) => new T(-t.Value);
+
+ #endregion
+
+ #region compare
+
+ public static Boolean operator ==(T left, T right) => left.Value == right.Value;
+ public static Boolean operator !=(T left, T right) => left.Value != right.Value;
+ public static Boolean operator > (T left, T right) => left.Value > right.Value;
+ public static Boolean operator < (T left, T right) => left.Value < right.Value;
+ public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
+ public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
+
+ #endregion
+
+ #region conversion
+
+ public static implicit operator T(Decimal d) => new T(d);
+ public static implicit operator T(Double d) => new T((Decimal)d);
+ public static implicit operator T(Int32 i) => new T(i);
+ public static implicit operator Decimal(T t) => t.Value;
+
+ #endregion
+
+ #region equality
+
+ public Boolean Equals(T other) => Value == other.Value;
+ public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
+ public override Int32 GetHashCode() => Value.GetHashCode();
+
+ #endregion
+
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusData/State.cs b/csharp/Lib/Units/State.cs
similarity index 73%
rename from csharp/Lib/StatusData/State.cs
rename to csharp/Lib/Units/State.cs
index 1f91b1249..752a5751d 100644
--- a/csharp/Lib/StatusData/State.cs
+++ b/csharp/Lib/Units/State.cs
@@ -1,4 +1,4 @@
-namespace InnovEnergy.Lib.StatusData;
+namespace InnovEnergy.Lib.Units;
public readonly struct State
{
@@ -9,13 +9,10 @@ public readonly struct State
public State(params String[] values) : this((IReadOnlyList)values){}
public State(params State[] states) : this(states.SelectMany(s => s.Values).ToList()){}
- public State(Enum e) : this(e.ToString())
- {
- }
+ public State(Enum e) : this(e.ToString()){}
public static implicit operator State(Enum e) => new State(e);
public static implicit operator State(String s) => new State(s);
- // parallel
- public static State operator |(State left, State right) => new State(left, right);
+ public static State operator +(State left, State right) => new State(left, right);
}
\ No newline at end of file
diff --git a/csharp/Lib/Units/Temperature.cs b/csharp/Lib/Units/Temperature.cs
new file mode 100644
index 000000000..22a411338
--- /dev/null
+++ b/csharp/Lib/Units/Temperature.cs
@@ -0,0 +1,61 @@
+namespace InnovEnergy.Lib.Units;
+
+using T = Temperature;
+
+public readonly struct Temperature
+{
+ public static String Unit => "°C";
+ public static String Symbol => "T";
+
+ public Decimal Value { get; }
+
+ public Temperature(Decimal value) => Value = value;
+
+ public override String ToString() => Value + Unit;
+
+
+ #region scalar multiplication
+
+ public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
+ public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
+ public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
+
+ #endregion
+
+ #region addition
+
+ public static T operator +(T left, T right) => new T(left.Value + right.Value);
+ public static T operator -(T left, T right) => new T(left.Value - right.Value);
+ public static T operator -(T t) => new T(-t.Value);
+
+ #endregion
+
+ #region compare
+
+ public static Boolean operator ==(T left, T right) => left.Value == right.Value;
+ public static Boolean operator !=(T left, T right) => left.Value != right.Value;
+ public static Boolean operator > (T left, T right) => left.Value > right.Value;
+ public static Boolean operator < (T left, T right) => left.Value < right.Value;
+ public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
+ public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
+
+ #endregion
+
+ #region conversion
+
+ public static implicit operator T(Decimal d) => new T(d);
+ public static implicit operator T(Double d) => new T((Decimal)d);
+ public static implicit operator T(Int32 i) => new T(i);
+ public static implicit operator Decimal(T t) => t.Value;
+
+ #endregion
+
+ #region equality
+
+ public Boolean Equals(T other) => Value == other.Value;
+ public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
+ public override Int32 GetHashCode() => Value.GetHashCode();
+
+ #endregion
+
+}
\ No newline at end of file
diff --git a/csharp/Lib/Units/Units.cs b/csharp/Lib/Units/Units.cs
new file mode 100644
index 000000000..88b9e04aa
--- /dev/null
+++ b/csharp/Lib/Units/Units.cs
@@ -0,0 +1,20 @@
+using System.Text.Json.Serialization;
+using InnovEnergy.Lib.Units.Json;
+
+namespace InnovEnergy.Lib.Units;
+
+public static class Units
+{
+ public static Current A (this Decimal value) => new Current(value);
+ public static Voltage V (this Decimal value) => new Voltage(value);
+ public static Power W (this Decimal value) => new Power(value);
+ public static Resistance Ohm(this Decimal value) => new Resistance(value);
+
+ public static readonly IReadOnlyList JsonConverters = new JsonConverter[]
+ {
+ new CurrentConverter(),
+ new VoltageConverter(),
+ new PowerConverter(),
+ new ResistanceConverter()
+ };
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusData/StatusData.csproj b/csharp/Lib/Units/Units.csproj
similarity index 52%
rename from csharp/Lib/StatusData/StatusData.csproj
rename to csharp/Lib/Units/Units.csproj
index 69d164c4f..eab4f3f58 100644
--- a/csharp/Lib/StatusData/StatusData.csproj
+++ b/csharp/Lib/Units/Units.csproj
@@ -6,4 +6,12 @@
preview
+
+
+
+
+
+
+
+
diff --git a/csharp/Lib/Units/Voltage.cs b/csharp/Lib/Units/Voltage.cs
new file mode 100644
index 000000000..db75e63e0
--- /dev/null
+++ b/csharp/Lib/Units/Voltage.cs
@@ -0,0 +1,69 @@
+namespace InnovEnergy.Lib.Units;
+
+using T = Voltage;
+
+public readonly struct Voltage
+{
+ public static String Unit => "V";
+ public static String Symbol => "U";
+
+ public Decimal Value { get; }
+
+ public Voltage(Decimal value) => Value = value;
+
+ public override String ToString() => Value + Unit;
+
+ // U=RI
+ public static Current operator /(Voltage voltage, Resistance resistance) => new Current(voltage.Value / resistance.Value);
+
+ // P=UI
+ public static Power operator *(Voltage voltage, Current current) => new Power(current.Value * voltage.Value);
+
+
+ #region scalar multiplication
+
+ public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
+ public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
+ public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
+
+ #endregion
+
+ #region addition
+
+ public static T operator +(T left, T right) => new T(left.Value + right.Value);
+ public static T operator -(T left, T right) => new T(left.Value - right.Value);
+ public static T operator -(T t) => new T(-t.Value);
+
+ #endregion
+
+ #region compare
+
+ public static Boolean operator ==(T left, T right) => left.Value == right.Value;
+ public static Boolean operator !=(T left, T right) => left.Value != right.Value;
+ public static Boolean operator > (T left, T right) => left.Value > right.Value;
+ public static Boolean operator < (T left, T right) => left.Value < right.Value;
+ public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
+ public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
+
+ #endregion
+
+ #region conversion
+
+ public static implicit operator T(Decimal d) => new T(d);
+ public static implicit operator T(Double d) => new T((Decimal)d);
+ public static implicit operator T(Int32 i) => new T(i);
+ public static implicit operator Decimal(T t) => t.Value;
+
+ #endregion
+
+ #region equality
+
+ public Boolean Equals(T other) => Value == other.Value;
+ public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
+ public override Int32 GetHashCode() => Value.GetHashCode();
+
+ #endregion
+
+
+
+}
\ No newline at end of file
diff --git a/csharp/Lib/Utils/Units.cs b/csharp/Lib/Utils/Units.cs
deleted file mode 100644
index db95bfcbb..000000000
--- a/csharp/Lib/Utils/Units.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace InnovEnergy.Lib.Utils;
-
-public static class Units
-{
- public static String Unit(this Object v, String unit) => $"{v} {unit}";
-
- public static String V(this Object v) => v.Unit("V");
- public static String W(this Object v) => v.Unit("W");
- public static String A(this Object v) => v.Unit("A");
-
- public static String Degrees(this Object v) => v.Unit("°");
- public static String Celsius(this Object v) => v.Unit("°C");
- public static String Percent(this Object v) => v.Unit("%");
-
-}
\ No newline at end of file
diff --git a/csharp/Lib/Utils/Utils.cs b/csharp/Lib/Utils/Utils.cs
index f4e5deb88..690d6abaa 100644
--- a/csharp/Lib/Utils/Utils.cs
+++ b/csharp/Lib/Utils/Utils.cs
@@ -79,6 +79,15 @@ public static class Utils
? res
: res + length;
}
+
+ public static Decimal Modulo(this Decimal dividend, Decimal divisor)
+ {
+ var res = dividend % divisor;
+
+ return res >= 0
+ ? res
+ : res + divisor;
+ }
public static IEnumerable Traverse(this T root, Func> getChildren)
{