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 { /// /// Can hold various s and hold connection record to relieve the meter. /// Every contact with meter has to go over even if you have only one. /// [Guid("CC3D4FEF-3EA6-47B2-9916-6F9AD4AE1F4B"), ComVisible(true), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(IMeterBatch))] public class MeterBatch : IMeterBatch { private readonly List _meterTypeRegistersCollection = new List(); private readonly ILogger _logger; private readonly String _sourceLocation; /// /// ctor /// public MeterBatch(String sourceLocation = "") { _sourceLocation = sourceLocation; _logger = NLogHelper.CreateOrGetLogger("MeterBatch"); _logger.Info("Meter batch created"); } private readonly List _listOfMeters = new List(); /// /// Registered list of meters /// public List ListOfMeters => _listOfMeters; /// 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 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); //} /// public IMeter[] GetCurrentMeter() { if (_listOfMeters == null || _listOfMeters.Count == 0) { return new IMeter[0]; } return _listOfMeters.ToArray(); } /// 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; } /// public void RemoveMeter(IMeter meterToRemove) { meterToRemove?.DisposeMeter(); _listOfMeters.Remove(meterToRemove); _logger.Info($"Slot:{ meterToRemove?.Slot} - Meter removed from batch"); } /// public void MetersLogin() { _logger.Info("Batch call Login to all meters"); var batchCall = new BatchCallLogin(); batchCall.RunAction(ListOfMeters); } /// public void MetersInit() { _logger.Info("Batch call to init all meters"); var batchCall = new BatchCallConnectMeter(); batchCall.RunAction(ListOfMeters); } /// public void MetersInitCalibration() { _logger.Info("Batch call to init calibration all meters"); var batchCall = new BatchCallInitCalibration(); batchCall.RunAction(ListOfMeters); } /// public void MetersInitMeasurement() { _logger.Info("Batch call to init measurement all meters"); var batchCall = new BatchCallInitMeasurement(); batchCall.RunAction(ListOfMeters); } /// public void MetersSaveCalculatedCalibration() { _logger.Info("Batch call to save calculated calibration on all meters"); var batchCall = new BatchCallSetCalibrationFactor(); batchCall.RunAction(ListOfMeters); } /// public void MetersStartCalibration() { _logger.Info("Batch call to start calibration on all meters"); var batchCall = new BatchCallStartCalibration(); batchCall.RunAction(ListOfMeters); } /// public void MetersStartMeasurement() { _logger.Info("Batch call to start measurement on all meters"); var batchCall = new BatchCallStartMeasurement(); batchCall.RunAction(ListOfMeters); } /// public void MetersStopCalibration() { _logger.Info("Batch call to stop calibration on all meters"); var batchCall = new BatchCallStopCalibration(); batchCall.RunAction(ListOfMeters); } /// public void MetersStopMeasurement() { _logger.Info("Batch call to stop measurement on all meters"); var batchCall = new BatchCallStopMeasurement(); batchCall.RunAction(ListOfMeters); } /// public IMeter GetMeter(Int32 slot) { return ListOfMeters.Find(f => f.Slot == slot); } /// 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"); } } /// public void Dispose() { try { _logger.Info("Dispose batch"); RemoveAllMeters(); GC.Collect(); } catch (Exception ex) { _logger.Error(ex, "Error on batch disposing, possible comport error"); } } public void DisposeTestBench() { _logger.Info("Dispose batch make sure green LED is off"); var batchCall = new BatchCallStopMeasurement(); batchCall.RunAction(ListOfMeters); } } }