diff --git a/csharp/InnovEnergy.sln.DotSettings b/csharp/InnovEnergy.sln.DotSettings
index f48e450b2..0584ce254 100644
--- a/csharp/InnovEnergy.sln.DotSettings
+++ b/csharp/InnovEnergy.sln.DotSettings
@@ -4,6 +4,7 @@
False
True
+ True
True
True
True
diff --git a/csharp/Lib/StatusApi/BatteryStatus.cs b/csharp/Lib/StatusApi/BatteryStatus.cs
index 0b033b420..2e241e5a9 100644
--- a/csharp/Lib/StatusApi/BatteryStatus.cs
+++ b/csharp/Lib/StatusApi/BatteryStatus.cs
@@ -1,7 +1,14 @@
using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Generator;
using InnovEnergy.Lib.Units.Composite;
namespace InnovEnergy.Lib.StatusApi;
-public abstract record BatteryStatus(DcPhase Dc) : DeviceStatus, IDcConnection;
+using T = BatteryStatus;
+
+[OpParallel]
+public partial record BatteryStatus : DeviceStatus, IDcConnection
+{
+ public required DcPhase Dc { get; init; }
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/BatteryStatus.generated.cs b/csharp/Lib/StatusApi/BatteryStatus.generated.cs
new file mode 100644
index 000000000..d5f549056
--- /dev/null
+++ b/csharp/Lib/StatusApi/BatteryStatus.generated.cs
@@ -0,0 +1,16 @@
+#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
+using System.CodeDom.Compiler;
+using InnovEnergy.Lib.Units.Composite;
+using InnovEnergy.Lib.Utils;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+using T = BatteryStatus;
+
+[GeneratedCode("generate.sh", "1")]
+public partial record BatteryStatus
+{
+ private static readonly Func OpParallel = "|".CreateBinaryOpForProps();
+ public static T operator |(T left, T right) => OpParallel(left, right);
+}
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Connections/IAc3Connection.cs b/csharp/Lib/StatusApi/Connections/IAc3Connection.cs
index 231982cf0..b95939124 100644
--- a/csharp/Lib/StatusApi/Connections/IAc3Connection.cs
+++ b/csharp/Lib/StatusApi/Connections/IAc3Connection.cs
@@ -4,5 +4,5 @@ namespace InnovEnergy.Lib.StatusApi.Connections;
public interface IAc3Connection
{
- Ac1Phase Ac3 { get; }
+ Ac3Phase Ac { get; }
}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/DcDcConverterStatus.cs b/csharp/Lib/StatusApi/DcDcConverterStatus.cs
index cdda395d9..a7d931065 100644
--- a/csharp/Lib/StatusApi/DcDcConverterStatus.cs
+++ b/csharp/Lib/StatusApi/DcDcConverterStatus.cs
@@ -1,8 +1,14 @@
+using InnovEnergy.Lib.StatusApi.Generator;
using InnovEnergy.Lib.Units.Composite;
namespace InnovEnergy.Lib.StatusApi;
-public abstract record DcDcConverterStatus(DcPhase Left, DcPhase Right) : DeviceStatus;
+[OpParallel]
+public partial record DcDcConverterStatus : DeviceStatus
+{
+ public required DcPhase Left { get; init; }
+ public required DcPhase Right { get; init; }
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/DcDcConverterStatus.generated.cs b/csharp/Lib/StatusApi/DcDcConverterStatus.generated.cs
new file mode 100644
index 000000000..32a133a8a
--- /dev/null
+++ b/csharp/Lib/StatusApi/DcDcConverterStatus.generated.cs
@@ -0,0 +1,16 @@
+#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
+using System.CodeDom.Compiler;
+using InnovEnergy.Lib.Units.Composite;
+using InnovEnergy.Lib.Utils;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+using T = DcDcConverterStatus;
+
+[GeneratedCode("generate.sh", "1")]
+public partial record DcDcConverterStatus
+{
+ private static readonly Func OpParallel = "|".CreateBinaryOpForProps();
+ public static T operator |(T left, T right) => OpParallel(left, right);
+}
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Generator/OpParallelAttribute.cs b/csharp/Lib/StatusApi/Generator/OpParallelAttribute.cs
new file mode 100644
index 000000000..ec94f9d34
--- /dev/null
+++ b/csharp/Lib/StatusApi/Generator/OpParallelAttribute.cs
@@ -0,0 +1,5 @@
+namespace InnovEnergy.Lib.StatusApi.Generator;
+
+[AttributeUsage(AttributeTargets.Class)]
+internal class OpParallelAttribute : Attribute
+{}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Generator/Template.txt b/csharp/Lib/StatusApi/Generator/Template.txt
new file mode 100644
index 000000000..43f22557f
--- /dev/null
+++ b/csharp/Lib/StatusApi/Generator/Template.txt
@@ -0,0 +1,16 @@
+#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
+using System.CodeDom.Compiler;
+using InnovEnergy.Lib.Units.Composite;
+using InnovEnergy.Lib.Utils;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+using T = Template;
+
+[GeneratedCode("generate.sh", "1")]
+public partial record Template
+{
+ private static readonly Func OpParallel = "|".CreateBinaryOpForProps();
+ public static T operator |(T left, T right) => OpParallel(left, right);
+}
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Generator/generate.sh b/csharp/Lib/StatusApi/Generator/generate.sh
new file mode 100755
index 000000000..1233bd1b7
--- /dev/null
+++ b/csharp/Lib/StatusApi/Generator/generate.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+
+scriptDir=$( dirname -- "$0"; )
+cd "$scriptDir/.." || exit
+
+for path in $(grep -e '\[OpParallel\]' -l *.cs)
+do
+ file=$(basename -- "$path")
+ class="${file%.*}"
+ echo "generating $file"
+ sed "s/Template/$class/g" "./Generator/Template.txt" > "./$class.generated.cs"
+done
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/MpptStatus.cs b/csharp/Lib/StatusApi/MpptStatus.cs
index bec31ddec..6514ad5f0 100644
--- a/csharp/Lib/StatusApi/MpptStatus.cs
+++ b/csharp/Lib/StatusApi/MpptStatus.cs
@@ -1,8 +1,14 @@
using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Generator;
using InnovEnergy.Lib.Units.Composite;
namespace InnovEnergy.Lib.StatusApi;
-public record MpptStatus(DcPhase Dc, IReadOnlyList Strings) : IDcConnection, IPvConnection;
+[OpParallel]
+public partial record MpptStatus : IDcConnection, IPvConnection
+{
+ public required DcPhase Dc { get; init; }
+ public required IReadOnlyList Strings { get; init; }
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/MpptStatus.generated.cs b/csharp/Lib/StatusApi/MpptStatus.generated.cs
new file mode 100644
index 000000000..5e2afe796
--- /dev/null
+++ b/csharp/Lib/StatusApi/MpptStatus.generated.cs
@@ -0,0 +1,16 @@
+#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
+using System.CodeDom.Compiler;
+using InnovEnergy.Lib.Units.Composite;
+using InnovEnergy.Lib.Utils;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+using T = MpptStatus;
+
+[GeneratedCode("generate.sh", "1")]
+public partial record MpptStatus
+{
+ private static readonly Func OpParallel = "|".CreateBinaryOpForProps();
+ public static T operator |(T left, T right) => OpParallel(left, right);
+}
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/PowerMeterStatus.cs b/csharp/Lib/StatusApi/PowerMeterStatus.cs
index 41038f4dc..d02a2ea72 100644
--- a/csharp/Lib/StatusApi/PowerMeterStatus.cs
+++ b/csharp/Lib/StatusApi/PowerMeterStatus.cs
@@ -1,6 +1,11 @@
using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Generator;
using InnovEnergy.Lib.Units.Composite;
namespace InnovEnergy.Lib.StatusApi;
-public abstract record PowerMeterStatus(Ac1Phase Ac3) : DeviceStatus, IAc3Connection;
\ No newline at end of file
+[OpParallel]
+public partial record PowerMeterStatus : DeviceStatus, IAc3Connection
+{
+ public required Ac3Phase Ac { get; init; }
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/PowerMeterStatus.generated.cs b/csharp/Lib/StatusApi/PowerMeterStatus.generated.cs
new file mode 100644
index 000000000..9e6dcaf9c
--- /dev/null
+++ b/csharp/Lib/StatusApi/PowerMeterStatus.generated.cs
@@ -0,0 +1,16 @@
+#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
+using System.CodeDom.Compiler;
+using InnovEnergy.Lib.Units.Composite;
+using InnovEnergy.Lib.Utils;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+using T = PowerMeterStatus;
+
+[GeneratedCode("generate.sh", "1")]
+public partial record PowerMeterStatus
+{
+ private static readonly Func OpParallel = "|".CreateBinaryOpForProps();
+ public static T operator |(T left, T right) => OpParallel(left, right);
+}
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/SinglePhaseInverterStatus.cs b/csharp/Lib/StatusApi/SinglePhaseInverterStatus.cs
index 9e1e2c8ba..efd9e7f5c 100644
--- a/csharp/Lib/StatusApi/SinglePhaseInverterStatus.cs
+++ b/csharp/Lib/StatusApi/SinglePhaseInverterStatus.cs
@@ -1,9 +1,15 @@
using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Generator;
using InnovEnergy.Lib.Units.Composite;
namespace InnovEnergy.Lib.StatusApi;
-public abstract record SinglePhaseInverterStatus(Ac1Phase Ac, DcPhase Dc) :
+[OpParallel]
+public partial record SinglePhaseInverterStatus :
DeviceStatus,
IAc1Connection,
- IDcConnection;
+ IDcConnection
+{
+ public required Ac1Phase Ac { get; init; }
+ public required DcPhase Dc { get; init; }
+}
diff --git a/csharp/Lib/StatusApi/SinglePhaseInverterStatus.generated.cs b/csharp/Lib/StatusApi/SinglePhaseInverterStatus.generated.cs
new file mode 100644
index 000000000..047f609fc
--- /dev/null
+++ b/csharp/Lib/StatusApi/SinglePhaseInverterStatus.generated.cs
@@ -0,0 +1,16 @@
+#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
+using System.CodeDom.Compiler;
+using InnovEnergy.Lib.Units.Composite;
+using InnovEnergy.Lib.Utils;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+using T = SinglePhaseInverterStatus;
+
+[GeneratedCode("generate.sh", "1")]
+public partial record SinglePhaseInverterStatus
+{
+ private static readonly Func OpParallel = "|".CreateBinaryOpForProps();
+ public static T operator |(T left, T right) => OpParallel(left, right);
+}
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/SinglePhasePvInverterStatus.cs b/csharp/Lib/StatusApi/SinglePhasePvInverterStatus.cs
index 51c113fce..3fc2db56a 100644
--- a/csharp/Lib/StatusApi/SinglePhasePvInverterStatus.cs
+++ b/csharp/Lib/StatusApi/SinglePhasePvInverterStatus.cs
@@ -1,9 +1,15 @@
using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Generator;
using InnovEnergy.Lib.Units.Composite;
namespace InnovEnergy.Lib.StatusApi;
-public abstract record SinglePhasePvInverterStatus(Ac1Phase Ac, IReadOnlyList Strings) :
+[OpParallel]
+public partial record SinglePhasePvInverterStatus :
DeviceStatus,
IAc1Connection,
- IPvConnection;
+ IPvConnection
+{
+ public required Ac1Phase Ac { get; init; }
+ public required IReadOnlyList Strings { get; init; }
+}
diff --git a/csharp/Lib/StatusApi/SinglePhasePvInverterStatus.generated.cs b/csharp/Lib/StatusApi/SinglePhasePvInverterStatus.generated.cs
new file mode 100644
index 000000000..37340f111
--- /dev/null
+++ b/csharp/Lib/StatusApi/SinglePhasePvInverterStatus.generated.cs
@@ -0,0 +1,16 @@
+#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
+using System.CodeDom.Compiler;
+using InnovEnergy.Lib.Units.Composite;
+using InnovEnergy.Lib.Utils;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+using T = SinglePhasePvInverterStatus;
+
+[GeneratedCode("generate.sh", "1")]
+public partial record SinglePhasePvInverterStatus
+{
+ private static readonly Func OpParallel = "|".CreateBinaryOpForProps();
+ public static T operator |(T left, T right) => OpParallel(left, right);
+}
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/StatusApi.csproj b/csharp/Lib/StatusApi/StatusApi.csproj
index 88fda982e..d14ca02c9 100644
--- a/csharp/Lib/StatusApi/StatusApi.csproj
+++ b/csharp/Lib/StatusApi/StatusApi.csproj
@@ -3,9 +3,13 @@
-
+
+
+
+
+
diff --git a/csharp/Lib/StatusApi/ThreePhaseInverterStatus.cs b/csharp/Lib/StatusApi/ThreePhaseInverterStatus.cs
index 8c2fc424f..306430190 100644
--- a/csharp/Lib/StatusApi/ThreePhaseInverterStatus.cs
+++ b/csharp/Lib/StatusApi/ThreePhaseInverterStatus.cs
@@ -1,10 +1,16 @@
using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Generator;
using InnovEnergy.Lib.Units.Composite;
namespace InnovEnergy.Lib.StatusApi;
-public abstract record ThreePhaseInverterStatus(Ac1Phase Ac3, DcPhase Dc) :
+[OpParallel]
+public partial record ThreePhaseInverterStatus :
DeviceStatus,
IAc3Connection,
- IDcConnection;
+ IDcConnection
+{
+ public required Ac3Phase Ac { get; init; }
+ public required DcPhase Dc { get; init; }
+}
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/ThreePhaseInverterStatus.generated.cs b/csharp/Lib/StatusApi/ThreePhaseInverterStatus.generated.cs
new file mode 100644
index 000000000..989941505
--- /dev/null
+++ b/csharp/Lib/StatusApi/ThreePhaseInverterStatus.generated.cs
@@ -0,0 +1,16 @@
+#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
+using System.CodeDom.Compiler;
+using InnovEnergy.Lib.Units.Composite;
+using InnovEnergy.Lib.Utils;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+using T = ThreePhaseInverterStatus;
+
+[GeneratedCode("generate.sh", "1")]
+public partial record ThreePhaseInverterStatus
+{
+ private static readonly Func OpParallel = "|".CreateBinaryOpForProps();
+ public static T operator |(T left, T right) => OpParallel(left, right);
+}
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/ThreePhasePvInverterStatus.cs b/csharp/Lib/StatusApi/ThreePhasePvInverterStatus.cs
index c09471d4b..b5a7686da 100644
--- a/csharp/Lib/StatusApi/ThreePhasePvInverterStatus.cs
+++ b/csharp/Lib/StatusApi/ThreePhasePvInverterStatus.cs
@@ -1,9 +1,15 @@
using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Generator;
using InnovEnergy.Lib.Units.Composite;
namespace InnovEnergy.Lib.StatusApi;
-public abstract record ThreePhasePvInverterStatus(Ac1Phase Ac3, IReadOnlyList Strings) :
+[OpParallel]
+public partial record ThreePhasePvInverterStatus :
DeviceStatus,
IAc3Connection,
- IPvConnection;
+ IPvConnection
+{
+ public required Ac3Phase Ac { get; init; }
+ public required IReadOnlyList Strings { get; init; }
+}
diff --git a/csharp/Lib/StatusApi/ThreePhasePvInverterStatus.generated.cs b/csharp/Lib/StatusApi/ThreePhasePvInverterStatus.generated.cs
new file mode 100644
index 000000000..4e7170a21
--- /dev/null
+++ b/csharp/Lib/StatusApi/ThreePhasePvInverterStatus.generated.cs
@@ -0,0 +1,16 @@
+#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
+using System.CodeDom.Compiler;
+using InnovEnergy.Lib.Units.Composite;
+using InnovEnergy.Lib.Utils;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+using T = ThreePhasePvInverterStatus;
+
+[GeneratedCode("generate.sh", "1")]
+public partial record ThreePhasePvInverterStatus
+{
+ private static readonly Func OpParallel = "|".CreateBinaryOpForProps();
+ public static T operator |(T left, T right) => OpParallel(left, right);
+}
+
\ No newline at end of file
diff --git a/csharp/Lib/StatusApi/Utils.cs b/csharp/Lib/StatusApi/Utils.cs
deleted file mode 100644
index b86db8478..000000000
--- a/csharp/Lib/StatusApi/Utils.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using InnovEnergy.Lib.Utils;
-
-namespace InnovEnergy.Lib.StatusApi;
-
-public static class Utils
-{
- public static Decimal Round3(this Decimal d)
- {
- return d.RoundToSignificantFigures(3);
- }
-}
\ No newline at end of file