add new Unit: Energy (kWh)
This commit is contained in:
parent
72293807ee
commit
7e58b78572
|
@ -0,0 +1,15 @@
|
||||||
|
using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
|
|
||||||
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
[Sum]
|
||||||
|
public readonly partial struct Energy
|
||||||
|
{
|
||||||
|
public static String Unit => "kWh";
|
||||||
|
public static String Symbol => "E";
|
||||||
|
|
||||||
|
public Energy(Decimal value) => Value = value;
|
||||||
|
|
||||||
|
public static Power operator /(Energy energy, TimeSpan timeSpan) => energy.Value / (Decimal) timeSpan.TotalHours * 1000m;
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
||||||
|
#define Sum
|
||||||
|
|
||||||
|
using static System.Math;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
using T = Energy;
|
||||||
|
|
||||||
|
[JsonConverter(typeof(EnergyConverter))]
|
||||||
|
public readonly partial struct Energy
|
||||||
|
{
|
||||||
|
public Decimal Value { get; }
|
||||||
|
public override String ToString() => Value.RoundToSignificantDigits(Units.DisplaySignificantDigits) + Unit;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// parallel
|
||||||
|
|
||||||
|
#if Sum
|
||||||
|
|
||||||
|
public static T operator |(T left, T right) => new T(left.Value + right.Value);
|
||||||
|
public static T operator -(T t) => new T(-t.Value);
|
||||||
|
|
||||||
|
#elif Mean
|
||||||
|
|
||||||
|
public static T operator |(T left, T right) => new T((left.Value + right.Value)/2m);
|
||||||
|
|
||||||
|
#elif Equal
|
||||||
|
|
||||||
|
public static T operator |(T left, T right)
|
||||||
|
{
|
||||||
|
var d = Max(Abs(left.Value), Abs(right.Value));
|
||||||
|
|
||||||
|
if (d == 0m)
|
||||||
|
return new T(0m);
|
||||||
|
|
||||||
|
var relativeError = Abs(left.Value - right.Value) / d;
|
||||||
|
|
||||||
|
const Decimal maxRelativeError = 0.05m;
|
||||||
|
|
||||||
|
if (relativeError > maxRelativeError)
|
||||||
|
throw new Exception($"{nameof(left)} and {nameof(right)} must be approximately equal.\n" +
|
||||||
|
$"Difference > {maxRelativeError * 100}% detected\n" +
|
||||||
|
$"{nameof(left)} : {left}\n" +
|
||||||
|
$"{nameof(right)}: {right}");
|
||||||
|
|
||||||
|
return new T((left.Value + right.Value) / 2m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal class EnergyConverter : JsonConverter<Energy>
|
||||||
|
{
|
||||||
|
public override Energy Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
return new Energy(reader.GetDecimal());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, Energy value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
var rounded = value.Value.RoundToSignificantDigits(Units.JsonSignificantDigits);
|
||||||
|
|
||||||
|
writer.WriteNumberValue(rounded);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,5 +14,7 @@ public readonly partial struct Power
|
||||||
// P=UI
|
// P=UI
|
||||||
public static Voltage operator /(Power power, Current current) => new Voltage(power.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);
|
public static Current operator /(Power power, Voltage voltage) => new Current(power.Value / voltage.Value);
|
||||||
|
|
||||||
|
public static Energy operator *(Power power, TimeSpan timeSpan) => power.Value / 1000m * (Decimal) timeSpan.TotalHours;
|
||||||
|
public static Energy operator *(TimeSpan timeSpan, Power power) => power.Value / 1000m * (Decimal) timeSpan.TotalHours;
|
||||||
}
|
}
|
Loading…
Reference in New Issue