using CordonelPreadjustmentUi.Const; using CordonelPreadjustmentUi.Helper; using Logic.ProductionToProductMapper.Cordonel; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; using Logic.ProductionToProductMapper.Cordonel; using Xylem.Common.CommonCore.Consts; using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.EventArguments; using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords; using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig; using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore; using Xylem.Common.Ui.CordonelPreadjustmentUi.Helper.Extensions; namespace CordonelPreadjustmentUi { public class ZeroFlowGenesisMeter : GenesisMeter { #region Data logging private bool logZeroFlow = false; public bool logAmpTest = false; #endregion private CultureInfo GlobalCulture { get; set; } public Byte Gp30LastByte { get; set; } private Byte[] GP30LastRegister { get; set; } public void SetGP30LastRegister(Byte[] data) { GP30LastRegister = data; } private Byte GP30LastPayloadLsb { get; set; } public Byte GP30LastCommand { get; set; } private Byte GP30RXPayload { get; set; } private Boolean GP30RequestStarted { get; set; } private Boolean GP30RequestFailed { get; set; } private Boolean GP30RequestGotAnswer { get; set; } private Byte Privilege { get; set; } private Byte FirstHitLevelUpPath0 { get; set; } private Byte FirstHitLevelUpPath1 { get; set; } private Byte FirstHitLevelUpPath2 { get; set; } private Byte FirstHitLevelDownPath0 { get; set; } private Byte FirstHitLevelDownPath1 { get; set; } private Byte FirstHitLevelDownPath2 { get; set; } private Byte PercentPath0 { get; set; } private Byte PercentPath1 { get; set; } private Byte PercentPath2 { get; set; } public Byte Subreason { get; set; } private Byte Starthit { get; set; } private Byte StoreCalibration { get; set; } private Byte Amplitude { get; set; } private Byte Samplerate { get; set; } private UInt16 CalibrationFactorPath0 { get; set; } private UInt16 CalibrationFactorPath1 { get; set; } private UInt16 CalibrationFactorPath2 { get; set; } private Int32 ZeroOffsetPath0 { get; set; } private Int32 ZeroOffsetPath1 { get; set; } private Int32 ZeroOffsetPath2 { get; set; } private Byte LedMode { get; set; } private Byte UpdatePeriode { get; set; } private Byte FirstHitShift { get; set; } private UInt32 ToFTempCalibrate { get; set; } private Int32 ToFTempOffsetPath0 { get; set; } private Int32 ToFTempOffsetPath1 { get; set; } private Int32 ToFTempOffsetPath2 { get; set; } public Int32 MeterNumber { get; set; } private Byte MeterSize { get; set; } public bool CalculationIndicatorZeroFlowTest { get; private set; } public bool LoggingIndicatorZeroFlowTest { get; private set; } public long ZeroflowOffsetTestNumberOfLines { get; private set; } public Boolean LogOnEnable; public Boolean AmplitudeEnable; public Boolean ZeroFlowOffsetEnable; public Boolean TempCalEnable; public Boolean CompletionEnable; public Boolean LoginFailed; public Boolean PreparationFailed; public Boolean AmplitudeFailed; public Boolean ZeroFlowOffsetFailed; public Boolean TempCalFailed; public Boolean CompletionFailed; public Boolean Ok; public Boolean EmptyPipeCheckEnable; public Boolean EmptyPipeCheckFailed; public Boolean MeterSelected; public CalibrationResult calibrationResult = new CalibrationResult(); public ConcurrentQueue CurrentRecords = new ConcurrentQueue(); public ZeroFlowGenesisMeter(int Slot, int PathsCount = 3, bool ignorCurruptdata = true) : base() { base.SetupFromConfigFile(Slot, ignorCurruptdata); //base.EnableAutoLogon(); Setup(PathsCount); //on zeroflow every param has to be stored _configuration.UseRegisterWatchService = true; _configuration.RegisterWatchServiceUrl = Xylem.Common.CommonCore.Configuration.ServiceUrls.RegisterWatchServiceUrl(); } public ZeroFlowGenesisMeter(int Slot, int PathsCount, PortConfig request, PortConfig streaming, bool ignoreCurrptData) : base() { base.SetupGenesisMeter(Slot, request, streaming, ignoreCurrptData); // base.EnableAutoLogon(); Setup(PathsCount); //overide register watch service //on zeroflow every param has to be stored _configuration.UseRegisterWatchService = true; } private void Setup(int PathsCount) { base.LogRawData(true); this.GP30LastRegister = new Byte[2] { 0, 0 }; this.GP30LastPayloadLsb = 0; this.GP30LastCommand = 0; this.GP30RXPayload = 0; this.GP30RequestStarted = false; this.GP30RequestFailed = false; this.GP30RequestGotAnswer = false; this.FirstHitLevelUpPath0 = 0; this.FirstHitLevelUpPath1 = 0; this.FirstHitLevelUpPath2 = 0; this.FirstHitLevelDownPath0 = 0; this.FirstHitLevelDownPath1 = 0; this.FirstHitLevelDownPath2 = 0; this.Starthit = 0; this.Amplitude = 0; this.Samplerate = 0; this.CalibrationFactorPath0 = 0; this.CalibrationFactorPath1 = 0; this.CalibrationFactorPath2 = 0; this.ZeroOffsetPath0 = 0; this.ZeroOffsetPath1 = 0; this.ZeroOffsetPath2 = 0; this.LedMode = 0; this.MeterNumber = Slot; this.GlobalCulture = CultureInfo.CreateSpecificCulture("en-US"); this.Gp30LastByte = 0; linesRecived = new MultiPathDataLogContainer(PathsCount); listOfTotalTimeOfFlightSPerPath = new ActivityCheckMultiPathDataLogContainer>(PathsCount); listOfTotalTimeOfFlightSPerPath.Update(null, new List()); BadDataCounterZeroFlowTest = new MultiPathDataLogContainer(PathsCount); LineCounterZeroFlowTest = new MultiPathDataLogContainer(PathsCount); AmplitudeValuesUp = new MultiPathDataLogContainer>(PathsCount); AmplitudeValuesDown = new MultiPathDataLogContainer>(PathsCount); DeltaTimeOfFlightAverage = new MultiPathDataLogContainer>(PathsCount); Decoded = new MultiPathDataLogContainer(PathsCount); } public Boolean CheckStreamingPort() { if (!StreamingPort.IsOpen()) { base.StreamingPort.Open(); } return StreamingPort.IsOpen(); } public Boolean CheckRequestPort() { if (!RequestPort.IsOpen()) { base.RequestPort.Open(); } return RequestPort.IsOpen(); } public void StartRecordData(int zeroflowOffsetTestNumberOfLines = 0) { CurrentRecords.Clear(); StreamingProtocol.OnRecordIsDecoded += StreamingProtocol_OnRecordIsDecoded; ; SyncStreamingBuffer(SyncMarkRecord.DecodeEveryPackage); ZeroflowOffsetTestNumberOfLines = zeroflowOffsetTestNumberOfLines; } private List logContent = new List(); public ActivityCheckMultiPathDataLogContainer> listOfTotalTimeOfFlightSPerPath; private MultiPathDataLogContainer linesRecived; private MultiPathDataLogContainer BadDataCounterZeroFlowTest; private MultiPathDataLogContainer LineCounterZeroFlowTest; private MultiPathDataLogContainer> AmplitudeValuesUp; private MultiPathDataLogContainer> AmplitudeValuesDown; private MultiPathDataLogContainer> DeltaTimeOfFlightAverage; private MultiPathDataLogContainer Decoded; internal void DataLog(string text) { logContent.Add(text); //todo nlog! } private void StreamingProtocol_OnRecordIsDecoded(object sender, BaseDataEventArgs e) { try { if (e is CalibDataEventArgs) { var decodedDate = (CalibDataEventArgs)e; var data = decodedDate.CalibChl; if (Slot == 10 && data.Channel == 2) { String time = DateTime.Now.ToString(Formats.RawDataDateTimeLogString); DataLog($"{time} {decodedDate.RawData}\n"); } CurrentRecords.Enqueue(data); //todo make new imesturementrecord according to units need by zeroflow app var TotalTimeOfFlightS = data.TotalTimeOfFlightS * 1000000; Double temp = data.DeltaTimeOfFlightS; //data.DeltaTimeOfFlightS = data.DeltaTimeOfFlightS * (1.0 / 0x4000000000); // 2^38; data.AmplitudeUpV = data.AmplitudeUpV * 1000.0; data.AmplitudeDownV = data.AmplitudeDownV * 1000.0; #region Logging (Zero flow test) if (logZeroFlow || logAmpTest) { String time = DateTime.Now.ToString(Formats.RawDataDateTimeLogString); DataLog($"{time} {decodedDate.RawData}\n"); } #endregion #region Add to list h-protocol UInt16 Path = (UInt16)(decodedDate.CalibChl.Channel - 1); //todo check if isValid == crc Ok if (decodedDate.CalibChl.IsValid) { #region Activity check for empty pipe test linesRecived.Update(Path, linesRecived.Get(Path) + 1); #endregion #region Data for amplitude test if (logAmpTest) { DataLog($"Add {TotalTimeOfFlightS} for chnl {Path}\n"); var tmp = listOfTotalTimeOfFlightSPerPath.Get(Path).ToList(); tmp.Add(TotalTimeOfFlightS); listOfTotalTimeOfFlightSPerPath.Update(Path, tmp); } #endregion #region Data for zero flow test var meterDone = true; for (int i = 0; i < LineCounterZeroFlowTest.GetPathCount(); i++) { if (LineCounterZeroFlowTest.Get(i) < ZeroflowOffsetTestNumberOfLines) { meterDone = false; } } if (meterDone) { CalculationIndicatorZeroFlowTest = false; LoggingIndicatorZeroFlowTest = false; } if (CalculationIndicatorZeroFlowTest) { #region Bad data check if (decodedDate.CalibChl.Validation == DataErrorCodes.NoError) { AmplitudeValuesUp.Get(Path).Add(decodedDate.CalibChl.AmplitudeUpV); AmplitudeValuesDown.Get(Path).Add(decodedDate.CalibChl.AmplitudeDownV); DeltaTimeOfFlightAverage.Get(Path).Add(decodedDate.CalibChl.DeltaTimeOfFlightS); LineCounterZeroFlowTest.Update(Path, LineCounterZeroFlowTest.Get(Path) + 1); } else { BadDataCounterZeroFlowTest.Update(Path, BadDataCounterZeroFlowTest.Get(Path) + 1); } #endregion } #endregion } #endregion #region Copy to global object Decoded.Update(Path, data); #endregion } } catch (Exception ex) { DataLog($"Exception occur {e}\n"); } } public void StopRecordData() { StreamingProtocol.OnRecordIsDecoded -= StreamingProtocol_OnRecordIsDecoded; SyncStreamingBuffer(SyncMarkRecord.SkipDecoding); } internal void Flush() { if (StreamingPort == null) { throw new ApplicationException("Synchronization not possible due to undefined streaming port"); } SyncStreamingBuffer(SyncMarkRecord.FlushBuffer); } public new Boolean WriteRegisterUnsafe(string reg, T value) { var RetrysLeft = 8; while (RetrysLeft >= 0) { try { var result = base.WriteRegister(reg, value, true, false); if (result) { return result; } Thread.Sleep(1500); } catch (Exception e) { base.WriteLog($"Can not WriteRegisterUnsafe retry left: {RetrysLeft}, message: {e.Message}"); } RetrysLeft = RetrysLeft - 1; } return false; } public new Boolean WriteRegisterSafe(string reg, T value) { var RetrysLeft = 8; while (RetrysLeft >= 0) { try { var result = base.WriteRegister(reg, value, true, true); if (result) { return result; } Thread.Sleep(1500); } catch (Exception e) { base.WriteLog($"Can not WriteRegisterUnsafe retry left: {RetrysLeft}, message: {e.Message}"); } RetrysLeft = RetrysLeft - 1; } return false; } public new Byte[] ReadRegister(string reg) { var RetrysLeft = 8; Exception lastEx = null; while (RetrysLeft >= 0) { try { return base.ReadRegister(reg); } catch (Exception e) { lastEx = e; base.WriteLog($"Can not WriteRegisterUnsafe retry left: {RetrysLeft}, message: {e.Message}"); } Thread.Sleep(1500); RetrysLeft = RetrysLeft - 1; } if (lastEx == null) { throw new ApplicationException("something went totally wrong on ReadRegister. no Exception found"); } throw new ApplicationException($"something went wrong on ReadRegister.Message{lastEx.Message}"); } } }