93 lines
2.5 KiB
C#
93 lines
2.5 KiB
C#
|
using System.Collections.Immutable;
|
||
|
using InnovEnergy.Lib.Victron.VeDBus;
|
||
|
using InnovEnergy.WireFormat.VictronV1;
|
||
|
|
||
|
namespace InnovEnergy.VenusLogger.Parsers;
|
||
|
|
||
|
using Props = ImmutableDictionary<String, VeProperty>;
|
||
|
|
||
|
public static class Utils
|
||
|
{
|
||
|
|
||
|
public static Phase ZeroPhase { get; } = new Phase { Current = 0, Voltage = 0 };
|
||
|
|
||
|
public static IEnumerable<Int32> AcPhases { get; } = new[] { 1, 2, 3 };
|
||
|
public static IEnumerable<Phase> ZeroPhases { get; } = new[] { ZeroPhase, ZeroPhase, ZeroPhase };
|
||
|
|
||
|
public static T? TryGetProperty<T>(this Props props, String path, T? defaultValue = default(T?))
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
return props.GetProperty<T>(path);
|
||
|
}
|
||
|
catch
|
||
|
{
|
||
|
return defaultValue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// TODO: maybegetproperty?
|
||
|
public static T GetProperty<T>(this Props props, String path)
|
||
|
{
|
||
|
if (typeof(T).IsEnum)
|
||
|
{
|
||
|
var type = Enum.GetUnderlyingType(typeof(T));
|
||
|
var value = props.GetProperty(path, type);
|
||
|
|
||
|
return (T) Enum.ToObject(typeof(T), value);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return (T) props.GetProperty(path, typeof(T));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
private static Object GetProperty(this Props props, String path, Type type)
|
||
|
{
|
||
|
var value = props[path].Value;
|
||
|
|
||
|
var isConvertible = type.GetInterface(nameof(IConvertible)) is not null;
|
||
|
|
||
|
return isConvertible
|
||
|
? Convert.ChangeType(value, type)
|
||
|
: value;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
public static IEnumerable<Phase> GetAcPhases(this Props props)
|
||
|
{
|
||
|
return AcPhases.TrySelect(props.ParseAcPhase);
|
||
|
}
|
||
|
|
||
|
public static Phase ParseAcPhase(this Props props, Int32 phase) => new Phase
|
||
|
{
|
||
|
Current = props.GetProperty<Single>($"/Ac/L{phase}/Current"),
|
||
|
Voltage = props.GetProperty<Single>($"/Ac/L{phase}/Voltage"),
|
||
|
Power = props.GetProperty<Single>($"/Ac/L{phase}/Power"),
|
||
|
};
|
||
|
|
||
|
public static Phase GetDcPhase(this Props props, Int32 phase = 0)
|
||
|
{
|
||
|
var current = props.GetProperty<Single>($"/Dc/{phase}/Current");
|
||
|
var voltage = props.GetProperty<Single>($"/Dc/{phase}/Voltage");
|
||
|
var power = current * voltage;
|
||
|
|
||
|
// if (props.ContainsKey($"/Dc/{phase}/Power"))
|
||
|
// {
|
||
|
// var losses = props.GetProperty<Single>($"/Dc/{phase}/Power") - power;
|
||
|
// Console.WriteLine("Losses: " + losses);
|
||
|
// }
|
||
|
|
||
|
return new Phase
|
||
|
{
|
||
|
Current = current,
|
||
|
Voltage = voltage,
|
||
|
Power = power
|
||
|
};
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|