laatzen/Common/Hardware/WaterMeter/WaterMeterCore/MeterBatch.cs
2022-04-06 10:42:16 +02:00

249 lines
7.7 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using NLog;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.BatchActions;
using Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters;
using Xylem.Common.Utils.Logging;
namespace Xylem.Common.Hardware.WaterMeter.WaterMeterCore
{
/// <summary>
/// Can hold various <see cref="IMeter"/>s and hold connection record to relieve the meter.
/// Every contact with meter has to go over <see cref="MeterBatch"/> even if you have only one.
/// </summary>
[Guid("CC3D4FEF-3EA6-47B2-9916-6F9AD4AE1F4B"),
ComVisible(true),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(IMeterBatch))]
public class MeterBatch : IMeterBatch
{
private readonly List<MeterTypeRegisters> _meterTypeRegistersCollection = new List<MeterTypeRegisters>();
private readonly ILogger _logger;
private readonly string _sourceLocation;
/// <summary>
/// ctor
/// </summary>
public MeterBatch(String SourceLocation = "")
{
SourceLocation = _sourceLocation;
_logger = NLogHelper.CreateOrGetLogger("MeterBatch");
_logger.Info("Meter batch created");
}
private readonly List<IMeter> _listOfMeters = new List<IMeter>();
/// <summary>
/// Registered list of meters
/// </summary>
public List<IMeter> ListOfMeters => _listOfMeters;
/// <inheritdoc />
public void AddMeter(IMeter meterToAdd)
{
_logger.Info($"Slot:{meterToAdd.Slot} - Meter assigned to batch");
var add = meterToAdd as IWaterMeterWithRegisters;
if (add != null)
{
AddMeterTypeToBatch(add);
}
_listOfMeters.Add(meterToAdd);
meterToAdd.ConnectMeter();
}
private void AddMeterTypeToBatch(IWaterMeterWithRegisters meterToAdd)
{
if (_meterTypeRegistersCollection.All(mtr => mtr.MeterType == meterToAdd.GetType()))
{
_meterTypeRegistersCollection.Add(new MeterTypeRegisters(meterToAdd.GetType()));
meterToAdd.LoadConfiguration(!string.IsNullOrEmpty(_sourceLocation) ? _sourceLocation : Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)));
}
}
//private void AddMeterTypeToBatch(IWaterMeterWithRegisters meterToAdd)
//{
// if (_meterTypeRegistersCollection.All(mtr => mtr.MeterType == meterToAdd.GetType()))
// {
// _meterTypeRegistersCollection.Add(new MeterTypeRegisters(meterToAdd.GetType(),
// meterToAdd.LoadConfiguration()));
// }
// List<IRegister> allRegisters =
// _meterTypeRegistersCollection.First(f => f.MeterType == meterToAdd.GetType()).Registers;
// if (allRegisters == null || !allRegisters.Any())
// {
// throw new ApplicationException($"No valid RegisterConfiguration found for meter type {meterToAdd.GetType()}. Check Configuration");
// }
// meterToAdd.SetConfigRegisterDefinitions(allRegisters);
//}
/// <inheritdoc />
public IMeter[] GetCurrentMeter()
{
if (_listOfMeters == null || _listOfMeters.Count == 0)
{
return new IMeter[0];
}
return _listOfMeters.ToArray();
}
/// <inheritdoc />
public Int32[] GetCurrentMeterSlots()
{
if (_listOfMeters == null || _listOfMeters.Count == 0)
{
return new Int32[0];
}
var ret = new Int32[_listOfMeters.Count];
for (var i = 0; i < _listOfMeters.Count; i++)
{
ret[i] = _listOfMeters[i].Slot;
}
return ret;
}
/// <inheritdoc />
public void RemoveMeter(IMeter meterToRemove)
{
meterToRemove?.DisposeMeter();
_listOfMeters.Remove(meterToRemove);
_logger.Info($"Slot:{ meterToRemove?.Slot} - Meter removed from batch");
}
/// <inheritdoc />
public void MetersLogin()
{
_logger.Info("Batch call Login to all meters");
var batchCall = new BatchCallLogin();
batchCall.RunAction(ListOfMeters);
}
/// <inheritdoc />
public void MetersInit()
{
_logger.Info("Batch call to init all meters");
var batchCall = new BatchCallConnectMeter();
batchCall.RunAction(ListOfMeters);
}
/// <inheritdoc />
public void MetersInitCalibration()
{
_logger.Info("Batch call to init calibration all meters");
var batchCall = new BatchCallInitCalibration();
batchCall.RunAction(ListOfMeters);
}
/// <inheritdoc />
public void MetersInitMeasurement()
{
_logger.Info("Batch call to init measurement all meters");
var batchCall = new BatchCallInitMeasurement();
batchCall.RunAction(ListOfMeters);
}
/// <inheritdoc />
public void MetersSaveCalculatedCalibration()
{
_logger.Info("Batch call to save calculated calibration on all meters");
var batchCall = new BatchCallSetCalibrationFactor();
batchCall.RunAction(ListOfMeters);
}
/// <inheritdoc />
public void MetersStartCalibration()
{
_logger.Info("Batch call to start calibration on all meters");
var batchCall = new BatchCallStartCalibration();
batchCall.RunAction(ListOfMeters);
}
/// <inheritdoc />
public void MetersStartMeasurement()
{
_logger.Info("Batch call to start measurement on all meters");
var batchCall = new BatchCallStartMeasurement();
batchCall.RunAction(ListOfMeters);
}
/// <inheritdoc />
public void MetersStopCalibration()
{
_logger.Info("Batch call to stop calibration on all meters");
var batchCall = new BatchCallStopCalibration();
batchCall.RunAction(ListOfMeters);
}
/// <inheritdoc />
public void MetersStopMeasurement()
{
_logger.Info("Batch call to stop measurement on all meters");
var batchCall = new BatchCallStopMeasurement();
batchCall.RunAction(ListOfMeters);
}
/// <inheritdoc />
public IMeter GetMeter(Int32 slot)
{
return ListOfMeters.Find(f => f.Slot == slot);
}
/// <inheritdoc />
public void RemoveAllMeters()
{
try
{
foreach (var item in ListOfMeters)
{
_logger.Info($"Slot:{ item.Slot} - Meter disposed");
item.DisposeMeter();
}
ListOfMeters.Clear();
}
catch (Exception ex)
{
_logger.Error(ex, "Error on RemoveAllMeters, prop. not all comports are closed");
}
}
/// <inheritdoc />
public void Dispose()
{
try
{
_logger.Info("Dispose batch");
RemoveAllMeters();
GC.Collect();
}
catch (Exception ex)
{
_logger.Error(ex, "Error on batch disposing, possible comport error");
}
}
}
}