92 lines
3.1 KiB
C#
92 lines
3.1 KiB
C#
using System.Reactive.Linq;
|
|
using InnovEnergy.Lib.Devices.IEM3kGridMeter;
|
|
using InnovEnergy.Lib.Protocols.DBus;
|
|
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
|
using InnovEnergy.Lib.Utils;
|
|
using InnovEnergy.Lib.Victron.VeDBus;
|
|
|
|
namespace InnovEnergy.App.SchneiderDriver;
|
|
|
|
public static class SchneiderMeterDriver
|
|
{
|
|
|
|
public static Task<Exception> Run(String hostName, Bus dbusAddress)
|
|
{
|
|
return Run(hostName, ModbusTcpClient.DefaultPort, dbusAddress);
|
|
}
|
|
|
|
public static async Task<Exception> Run(String hostName, UInt16 port, Bus dbusAddress)
|
|
{
|
|
// var ep = new UnixDomainSocketEndPoint("/home/eef/graber_dbus.sock");
|
|
// var auth = AuthenticationMethod.ExternalAsRoot();
|
|
// dbusAddress = new Bus(ep, auth);
|
|
|
|
var schneider = new Iem3KGridMeterDevice(hostName, port, Config.ModbusNodeId);
|
|
|
|
|
|
var schneiderStatus = Observable
|
|
.Interval(Config.UpdatePeriod)
|
|
.Select(_ => schneider.Read())
|
|
.Where(reading => reading != null)
|
|
.Publish();
|
|
|
|
var poller = schneiderStatus.Connect();
|
|
|
|
var properties = Config.DefaultProperties;
|
|
|
|
var signals = Config
|
|
.Signals
|
|
.Select(signal => schneiderStatus
|
|
.Select(reading =>
|
|
{
|
|
var property = signal.ToVeProperty(reading);
|
|
if (property == null)
|
|
{
|
|
// Console.WriteLine($"Warning: Signal {signal} produced a null property.");
|
|
}
|
|
else
|
|
{
|
|
//Console.WriteLine($"Transformed Signal to Property: {property}");
|
|
}
|
|
return property;
|
|
})
|
|
.Where(property => property != null))
|
|
.Merge()
|
|
.Do(p =>
|
|
{
|
|
// Console.WriteLine($"Setting property: {p}");
|
|
properties.Set(p);
|
|
});
|
|
|
|
// TODO: remove when possible
|
|
// Apparently some VE services need to be periodically reminded that
|
|
// this service is /Connected
|
|
Console.WriteLine("Goes to subscribe");
|
|
schneiderStatus.Subscribe(_ => properties.Set("/Connected", 1));
|
|
Console.WriteLine("Subscribed successfully");
|
|
// Wait until status is read once to make sure all
|
|
// properties are set when we go onto the bus.
|
|
|
|
var dbus = schneiderStatus
|
|
.Skip(1)
|
|
.Take(1)
|
|
.SelectMany(_ => PublishPropertiesOnDBus(properties, dbusAddress));
|
|
|
|
return await signals
|
|
.MergeErrors(dbus)
|
|
.Finally(poller.Dispose)
|
|
.SelectErrors();
|
|
}
|
|
|
|
|
|
private static Task<Exception> PublishPropertiesOnDBus(VeProperties properties, Bus bus)
|
|
{
|
|
Console.WriteLine($"Connecting to DBus {bus}");
|
|
return properties.PublishOnDBus(bus, Config.BusName);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|