Innovenergy_trunk/csharp/app/EmuMeterDriver/EmuMeterDriver.cs

67 lines
2.2 KiB
C#

using System.Reactive.Linq;
using InnovEnergy.Lib.Devices.EmuMeter;
using InnovEnergy.Lib.Protocols.DBus;
using InnovEnergy.Lib.Protocols.Modbus.Clients;
using InnovEnergy.Lib.Utils;
using InnovEnergy.Lib.Victron.VeDBus;
namespace InnovEnergy.EmuMeter;
public static class EmuMeterDriver
{
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 emuMeter = new EmuMeterDevice(hostName, port, Config.ModbusNodeId);
var meterStatus = Observable
.Interval(Config.UpdatePeriod)
.Select(_ => emuMeter.ReadStatus())
.Publish();
var poller = meterStatus.Connect();
var properties = Config.DefaultProperties;
var signals = Config
.Signals
.Select(signal => meterStatus.Select(signal.ToVeProperty))
.Merge()
.Do(p => properties.Set(p));
// TODO: remove when possible
// Apparently some VE services need to be periodically reminded that
// this service is /Connected
meterStatus.Subscribe(_ => properties.Set("/Connected", 1));
// Wait until status is read once to make sure all
// properties are set when we go onto the bus.
var dbus = meterStatus
.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);
}
}