175 lines
4.7 KiB
C#
175 lines
4.7 KiB
C#
using System.Collections;
|
|
using System.Reflection;
|
|
using InnovEnergy.Lib.Units.Power;
|
|
using InnovEnergy.Lib.Utils;
|
|
using static System.Reflection.BindingFlags;
|
|
|
|
namespace InnovEnergy.Lib.Units;
|
|
|
|
public static class Units
|
|
{
|
|
public static Byte DisplaySignificantDigits { get; set; } = 3;
|
|
public static Byte JsonSignificantDigits { get; set; } = 3;
|
|
|
|
public static Current A (this Double value) => value;
|
|
public static Voltage V (this Double value) => value;
|
|
public static ActivePower W (this Double value) => value;
|
|
public static ReactivePower Var (this Double value) => value;
|
|
public static ApparentPower Va (this Double value) => value;
|
|
public static Resistance Ohm (this Double value) => value;
|
|
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 String ToCsv(this Object thing)
|
|
{
|
|
var csvLines = new List<String>();
|
|
var visited = new HashSet<Object>();
|
|
|
|
GetCsv(thing);
|
|
|
|
return csvLines.JoinLines();
|
|
|
|
void GetCsv(Object? parent, String path = "")
|
|
{
|
|
if (parent == null)
|
|
return;
|
|
|
|
var type = parent.GetType();
|
|
|
|
if (parent is Unit u)
|
|
{
|
|
csvLines.Add($"{path};{u.Value};{u.Symbol}"); // leaf: unit
|
|
}
|
|
else if (parent is String s)
|
|
{
|
|
csvLines.Add($"{path};{s};"); // leaf: unit
|
|
}
|
|
else if(type.IsEnum || (type.IsValueType && !type.IsNested))
|
|
{
|
|
csvLines.Add($"{path};{parent};"); // leaf: value type
|
|
}
|
|
else if (parent is IEnumerable enumerable)
|
|
{
|
|
var enumerableType = enumerable.GetType();
|
|
|
|
var elementType = enumerableType.GetGenericArguments().SingleOrDefault() ??
|
|
enumerableType.GetElementType(); // for arrays
|
|
|
|
if (elementType is null)
|
|
return;
|
|
|
|
if (elementType.IsValueType || elementType == typeof(String))
|
|
{
|
|
var value = enumerable.Cast<Object>().JoinWith(",");
|
|
csvLines.Add($"{path};{value};");
|
|
}
|
|
else
|
|
{
|
|
var i = 1;
|
|
foreach (var o in enumerable)
|
|
GetCsv(o, $"{path}/{i++}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!visited.Add(parent))
|
|
return;
|
|
|
|
foreach (var p in type.GetProperties(Instance | Public))
|
|
{
|
|
var name = p.Name;
|
|
var value = p.GetValue(parent);
|
|
GetCsv(value, $"{path}/{name}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class Prefixes
|
|
{
|
|
private static readonly IReadOnlyList<String> Big = new[]
|
|
{
|
|
"",
|
|
"k",
|
|
"M",
|
|
"G",
|
|
"T",
|
|
"P",
|
|
"E",
|
|
"Y",
|
|
};
|
|
|
|
private static readonly IReadOnlyList<String> 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}";
|
|
}
|
|
|
|
}
|